Skip to content

Commit 4b2c735

Browse files
authored
Merge pull request #73 from msau42/cleanup
Make dataRoot optional, cleanup
2 parents 82936aa + 08dfcb7 commit 4b2c735

File tree

2 files changed

+147
-133
lines changed

2 files changed

+147
-133
lines changed

pkg/hostpath/controllerserver.go

+35-127
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import (
2020
"fmt"
2121
"math"
2222
"os"
23+
"path/filepath"
2324
"sort"
2425
"strconv"
25-
"strings"
2626

2727
"github.com/golang/protobuf/ptypes"
2828

@@ -33,14 +33,11 @@ import (
3333
"google.golang.org/grpc/status"
3434

3535
"github.com/container-storage-interface/spec/lib/go/csi"
36-
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
3736
utilexec "k8s.io/utils/exec"
3837
)
3938

4039
const (
4140
deviceID = "deviceID"
42-
provisionRoot = "/csi-data-dir"
43-
snapshotRoot = "/csi-data-dir"
4441
maxStorageCapacity = tib
4542
)
4643

@@ -138,114 +135,46 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
138135
},
139136
}, nil
140137
}
141-
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("Volume with the same name: %s but with different size already exist", req.GetName()))
138+
return nil, status.Errorf(codes.AlreadyExists, "Volume with the same name: %s but with different size already exist", req.GetName())
142139
}
143140

144141
volumeID := uuid.NewUUID().String()
145142
path := getVolumePath(volumeID)
146143

147-
if requestedAccessType == blockAccess {
148-
executor := utilexec.New()
149-
size := fmt.Sprintf("%dM", capacity/mib)
150-
// Create a block file.
151-
out, err := executor.Command("fallocate", "-l", size, path).CombinedOutput()
152-
if err != nil {
153-
glog.V(3).Infof("failed to create block device: %v", string(out))
154-
return nil, err
155-
}
156-
157-
// Associate block file with the loop device.
158-
volPathHandler := volumepathhandler.VolumePathHandler{}
159-
_, err = volPathHandler.AttachFileDevice(path)
160-
if err != nil {
161-
glog.Errorf("failed to attach device: %v", err)
162-
// Remove the block file because it'll no longer be used again.
163-
if err2 := os.Remove(path); err != nil {
164-
glog.Errorf("failed to cleanup block file %s: %v", path, err2)
165-
}
166-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to attach device: %v", err))
167-
}
168-
}
169-
170144
vol, err := createHostpathVolume(volumeID, req.GetName(), capacity, requestedAccessType, false /* ephemeral */)
171145
if err != nil {
172-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create volume: %s", err))
146+
return nil, status.Errorf(codes.Internal, "failed to create volume %v: %v", volumeID, err)
173147
}
174148
glog.V(4).Infof("created volume %s at path %s", vol.VolID, vol.VolPath)
175149

176150
if req.GetVolumeContentSource() != nil {
177151
contentSource := req.GetVolumeContentSource()
178-
if contentSource.GetSnapshot() != nil {
179-
snapshotId := contentSource.GetSnapshot().GetSnapshotId()
180-
snapshot, ok := hostPathVolumeSnapshots[snapshotId]
181-
if !ok {
182-
deleteHostpathVolume(volumeID)
183-
return nil, status.Errorf(codes.NotFound, "cannot find snapshot %v", snapshotId)
184-
}
185-
if snapshot.ReadyToUse != true {
186-
deleteHostpathVolume(volumeID)
187-
return nil, status.Errorf(codes.Internal, "Snapshot %v is not yet ready to use.", snapshotId)
188-
}
189-
snapshotPath := snapshot.Path
190-
args := []string{"zxvf", snapshotPath, "-C", path}
191-
executor := utilexec.New()
192-
out, err := executor.Command("tar", args...).CombinedOutput()
193-
if err != nil {
194-
deleteHostpathVolume(volumeID)
195-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed pre-populate data for volume: %v: %s", err, out))
196-
}
152+
if snapshot := contentSource.GetSnapshot(); snapshot != nil {
153+
err = loadFromSnapshot(snapshot.GetSnapshotId(), path)
197154
}
198155
if srcVolume := contentSource.GetVolume(); srcVolume != nil {
199-
srcVolumeID := srcVolume.GetVolumeId()
200-
hostPathVolume, ok := hostPathVolumes[srcVolumeID]
201-
if !ok {
202-
deleteHostpathVolume(volumeID)
203-
return nil, status.Error(codes.NotFound, "source volumeID does not exist, are source/destination in the same storage class?")
204-
}
205-
srcPath := hostPathVolume.VolPath
206-
isEmpty, err := hostPathIsEmpty(srcPath)
207-
if err != nil {
208-
deleteHostpathVolume(volumeID)
209-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed verification check of source hostpath volume: %s: %v", srcVolumeID, err))
210-
}
211-
212-
// If the source hostpath volume is empty it's a noop and we just move along, otherwise the cp call will fail with a a file stat error DNE
213-
if !isEmpty {
214-
args := []string{"-a", srcPath + "/*", path + "/"}
215-
executor := utilexec.New()
216-
out, err := executor.Command("cp", args...).CombinedOutput()
217-
if err != nil {
218-
deleteHostpathVolume(volumeID)
219-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed pre-populate data (clone) for volume: %s: %s", volumeID, out))
220-
}
156+
err = loadFromVolume(srcVolume.GetVolumeId(), path)
157+
}
158+
if err != nil {
159+
if delErr := deleteHostpathVolume(volumeID); delErr != nil {
160+
glog.V(2).Infof("deleting hostpath volume %v failed: %v", volumeID, delErr)
221161
}
162+
return nil, err
222163
}
164+
glog.V(4).Infof("successfully populated volume %s", vol.VolID)
223165
}
224166

225-
createVolumeResponse := &csi.CreateVolumeResponse{}
226-
if req.GetVolumeContentSource() != nil {
227-
createVolumeResponse = &csi.CreateVolumeResponse{
228-
Volume: &csi.Volume{
229-
VolumeId: volumeID,
230-
CapacityBytes: req.GetCapacityRange().GetRequiredBytes(),
231-
VolumeContext: req.GetParameters(),
232-
ContentSource: req.GetVolumeContentSource(),
233-
},
234-
}
235-
} else {
236-
createVolumeResponse = &csi.CreateVolumeResponse{
237-
Volume: &csi.Volume{
238-
VolumeId: volumeID,
239-
CapacityBytes: req.GetCapacityRange().GetRequiredBytes(),
240-
VolumeContext: req.GetParameters(),
241-
},
242-
}
243-
}
244-
return createVolumeResponse, nil
167+
return &csi.CreateVolumeResponse{
168+
Volume: &csi.Volume{
169+
VolumeId: volumeID,
170+
CapacityBytes: req.GetCapacityRange().GetRequiredBytes(),
171+
VolumeContext: req.GetParameters(),
172+
ContentSource: req.GetVolumeContentSource(),
173+
},
174+
}, nil
245175
}
246176

247177
func (cs *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
248-
249178
// Check arguments
250179
if len(req.GetVolumeId()) == 0 {
251180
return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request")
@@ -256,36 +185,12 @@ func (cs *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
256185
return nil, err
257186
}
258187

259-
vol, err := getVolumeByID(req.GetVolumeId())
260-
if err != nil {
261-
// Return OK if the volume is not found.
262-
return &csi.DeleteVolumeResponse{}, nil
263-
}
264-
glog.V(4).Infof("deleting volume %s", vol.VolID)
265-
266-
if vol.VolAccessType == blockAccess {
267-
268-
volPathHandler := volumepathhandler.VolumePathHandler{}
269-
// Get the associated loop device.
270-
device, err := volPathHandler.GetLoopDevice(getVolumePath(vol.VolID))
271-
if err != nil {
272-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to get the loop device: %v", err))
273-
}
274-
275-
if device != "" {
276-
// Remove any associated loop device.
277-
glog.V(4).Infof("deleting loop device %s", device)
278-
if err := volPathHandler.RemoveLoopDevice(device); err != nil {
279-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to remove loop device: %v", err))
280-
}
281-
}
282-
}
283-
284-
if err := deleteHostpathVolume(vol.VolID); err != nil && !os.IsNotExist(err) {
285-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to delete volume: %s", err))
188+
volId := req.GetVolumeId()
189+
if err := deleteHostpathVolume(volId); err != nil {
190+
return nil, status.Errorf(codes.Internal, "failed to delete volume %v: %v", volId, err)
286191
}
287192

288-
glog.V(4).Infof("volume deleted ok: %s", vol.VolID)
193+
glog.V(4).Infof("volume %v successfully deleted", volId)
289194

290195
return &csi.DeleteVolumeResponse{}, nil
291196
}
@@ -344,6 +249,11 @@ func (cs *controllerServer) ListVolumes(ctx context.Context, req *csi.ListVolume
344249
return nil, status.Error(codes.Unimplemented, "")
345250
}
346251

252+
// getSnapshotPath returns the full path to where the snapshot is stored
253+
func getSnapshotPath(snapshotId string) string {
254+
return filepath.Join(dataRoot, fmt.Sprintf("%s.tgz", snapshotId))
255+
}
256+
347257
// CreateSnapshot uses tar command to create snapshot for hostpath volume. The tar command can quickly create
348258
// archives of entire directories. The host image must have "tar" binaries in /bin, /usr/sbin, or /usr/bin.
349259
func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) {
@@ -377,7 +287,7 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
377287
},
378288
}, nil
379289
}
380-
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("snapshot with the same name: %s but with different SourceVolumeId already exist", req.GetName()))
290+
return nil, status.Errorf(codes.AlreadyExists, "snapshot with the same name: %s but with different SourceVolumeId already exist", req.GetName())
381291
}
382292

383293
volumeID := req.GetSourceVolumeId()
@@ -389,8 +299,7 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
389299
snapshotID := uuid.NewUUID().String()
390300
creationTime := ptypes.TimestampNow()
391301
volPath := hostPathVolume.VolPath
392-
filePath := []string{snapshotRoot, "/", snapshotID, ".tgz"}
393-
file := strings.Join(filePath, "")
302+
file := getSnapshotPath(snapshotID)
394303
args := []string{}
395304
if hostPathVolume.VolAccessType == blockAccess {
396305
glog.V(4).Infof("Creating snapshot of Raw Block Mode Volume")
@@ -402,7 +311,7 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
402311
executor := utilexec.New()
403312
out, err := executor.Command("tar", args...).CombinedOutput()
404313
if err != nil {
405-
return nil, status.Error(codes.Internal, fmt.Sprintf("failed create snapshot: %v: %s", err, out))
314+
return nil, status.Errorf(codes.Internal, "failed create snapshot: %v: %s", err, out)
406315
}
407316

408317
glog.V(4).Infof("create volume snapshot %s", file)
@@ -439,9 +348,8 @@ func (cs *controllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteS
439348
return nil, err
440349
}
441350
snapshotID := req.GetSnapshotId()
442-
glog.V(4).Infof("deleting volume %s", snapshotID)
443-
pathSlice := []string{snapshotRoot, "/", snapshotID, ".tgz"}
444-
path := strings.Join(pathSlice, "")
351+
glog.V(4).Infof("deleting snapshot %s", snapshotID)
352+
path := getSnapshotPath(snapshotID)
445353
os.RemoveAll(path)
446354
delete(hostPathVolumeSnapshots, snapshotID)
447355
return &csi.DeleteSnapshotResponse{}, nil
@@ -579,7 +487,7 @@ func (cs *controllerServer) validateControllerServiceRequest(c csi.ControllerSer
579487
return nil
580488
}
581489
}
582-
return status.Error(codes.InvalidArgument, fmt.Sprintf("%s", c))
490+
return status.Errorf(codes.InvalidArgument, "unsupported capability %s", c)
583491
}
584492

585493
func getControllerServiceCapabilities(cl []csi.ControllerServiceCapability_RPC_Type) []*csi.ControllerServiceCapability {

0 commit comments

Comments
 (0)