@@ -2,7 +2,6 @@ package cvmfs
22
33import (
44 "context"
5- "errors"
65 "os"
76
87 "github.com/golang/glog"
@@ -17,68 +16,82 @@ type nodeServer struct {
1716 * csicommon.DefaultNodeServer
1817}
1918
20- func validateNodePublishVolumeRequest (req * csi.NodePublishVolumeRequest ) error {
21- if req .GetVolumeCapability () == nil {
22- return errors .New ("Volume capability missing in request" )
19+ func (ns * nodeServer ) NodeStageVolume (ctx context.Context , req * csi.NodeStageVolumeRequest ) (* csi.NodeStageVolumeResponse , error ) {
20+ if err := validateNodeStageVolumeRequest (req ); err != nil {
21+ glog .Errorf ("failed to validate NodeStageVolumeRequest: %v" , err )
22+ return nil , status .Error (codes .InvalidArgument , err .Error ())
2323 }
2424
25- if req .GetVolumeId () == "" {
26- return errors .New ("Volume ID missing in request" )
27- }
25+ // Configuration
2826
29- if req .GetTargetPath () == "" {
30- return errors .New ("Target path missing in request" )
31- }
27+ stagingTargetPath := req .GetStagingTargetPath ()
28+ volId := volumeID (req .GetVolumeId ())
3229
33- return nil
34- }
30+ volOptions , err := newVolumeOptions (req .GetVolumeAttributes ())
31+ if err != nil {
32+ glog .Errorf ("invalid volume attributes for volume %s: %v" , volId , err )
33+ return nil , status .Error (codes .InvalidArgument , err .Error ())
34+ }
3535
36- func validateNodeUnpublishVolumeRequest ( req * csi. NodeUnpublishVolumeRequest ) error {
37- if req . GetVolumeId () == "" {
38- return errors . New ( "Volume ID missing in request" )
36+ if err = createMountPoint ( stagingTargetPath ); err != nil {
37+ glog . Errorf ( "failed to create staging mount point at %s for volume %s: %v" , stagingTargetPath , volId , err )
38+ return nil , status . Error ( codes . Internal , err . Error () )
3939 }
4040
41- if req .GetTargetPath () == "" {
42- return errors .New ("Target path missing in request" )
41+ confData := cvmfsConfigData {
42+ VolumeId : volId ,
43+ Tag : volOptions .Tag ,
44+ Hash : volOptions .Hash ,
45+ Proxy : volOptions .Proxy ,
4346 }
4447
45- return nil
46- }
48+ if err := confData .writeToFile (); err != nil {
49+ glog .Errorf ("failed to write cvmfs config for volume %s: %v" , volId , err )
50+ return nil , status .Error (codes .Internal , err .Error ())
51+ }
4752
48- func (ns * nodeServer ) NodePublishVolume (ctx context.Context , req * csi.NodePublishVolumeRequest ) (* csi.NodePublishVolumeResponse , error ) {
49- if err := validateNodePublishVolumeRequest (req ); err != nil {
50- return nil , status .Error (codes .InvalidArgument , err .Error ())
53+ if err := createVolumeCache (volId ); err != nil {
54+ glog .Errorf ("failed to create cache for volume %s: %v" , volId , err )
5155 }
5256
53- targetPath := req .GetTargetPath ()
54- volId := req .GetVolumeId ()
55- volUuid := uuidFromVolumeId (volId )
57+ // Check if the volume is already mounted
5658
57- // Configuration
59+ isMnt , err := isMountPoint ( stagingTargetPath )
5860
59- volOptions , err := newVolumeOptions (req .GetVolumeAttributes ())
6061 if err != nil {
61- glog .Errorf ("error reading volume options : %v" , err )
62- return nil , status .Error (codes .InvalidArgument , err .Error ())
62+ glog .Errorf ("stat failed : %v" , err )
63+ return nil , status .Error (codes .Internal , err .Error ())
6364 }
6465
65- confData := cvmfsConfigData {
66- VolUuid : volUuid ,
67- Tag : volOptions .Tag ,
68- Hash : volOptions .Hash ,
69- Proxy : volOptions .Proxy ,
66+ if isMnt {
67+ glog .Infof ("cvmfs: volume %s is already mounted to %s, skipping" , volId , stagingTargetPath )
68+ return & csi.NodeStageVolumeResponse {}, nil
7069 }
7170
72- if err := confData .writeToFile (); err != nil {
73- glog .Errorf ("failed to write cvmfs config for volume %s: %v" , volId , err )
74- return nil , status .Errorf (codes .Internal , err .Error ())
71+ // It's not, mount now
72+
73+ if err = mountCvmfs (volOptions , volId , stagingTargetPath ); err != nil {
74+ glog .Errorf ("failed to mount volume %s to %s: %v" , volId , stagingTargetPath , err )
75+ return nil , status .Error (codes .Internal , err .Error ())
7576 }
7677
77- if err := createVolumeCache (volUuid ); err != nil {
78- glog .Errorf ("failed to create cache for volume %s: %v" , volId , err )
78+ glog .Infof ("cvmfs: successfuly mounted volume %s to %s" , volId , stagingTargetPath )
79+
80+ return & csi.NodeStageVolumeResponse {}, nil
81+ }
82+
83+ func (ns * nodeServer ) NodePublishVolume (ctx context.Context , req * csi.NodePublishVolumeRequest ) (* csi.NodePublishVolumeResponse , error ) {
84+ if err := validateNodePublishVolumeRequest (req ); err != nil {
85+ glog .Errorf ("failed to validate NodePublishVolumeRequest: %v" , err )
86+ return nil , status .Error (codes .InvalidArgument , err .Error ())
7987 }
8088
81- if err = createMountPoint (targetPath ); err != nil {
89+ // Configuration
90+
91+ targetPath := req .GetTargetPath ()
92+ volId := volumeID (req .GetVolumeId ())
93+
94+ if err := createMountPoint (targetPath ); err != nil {
8295 glog .Errorf ("failed to create mount point for volume %s at %s: %v" , volId , targetPath , err )
8396 return nil , status .Error (codes .Internal , err .Error ())
8497 }
@@ -93,59 +106,94 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
93106 }
94107
95108 if isMnt {
96- glog .V ( 4 ). Infof ("cephfs : volume %s is already mounted to %s" , volId , targetPath )
109+ glog .Infof ("cvmfs : volume %s is already bind- mounted to %s" , volId , targetPath )
97110 return & csi.NodePublishVolumeResponse {}, nil
98111 }
99112
100- // It's not, mount now
113+ // It's not, bind- mount now
101114
102- if err = mountVolume ( targetPath , volOptions , volUuid ); err != nil {
103- glog .Errorf ("failed to mount volume %s: %v" , volId , err )
115+ if err = bindMount ( req . GetStagingTargetPath (), targetPath ); err != nil {
116+ glog .Errorf ("failed to bind- mount volume %s to %s : %v" , volId , targetPath , err )
104117 return nil , status .Error (codes .Internal , err .Error ())
105118 }
106119
107- glog .V ( 4 ). Infof ("cvmfs: volume %s successfuly mounted to %s" , volId , targetPath )
120+ glog .Infof ("cvmfs: successfuly bind-mounted volume %s to %s" , volId , targetPath )
108121
109122 return & csi.NodePublishVolumeResponse {}, nil
110123}
111124
112125func (ns * nodeServer ) NodeUnpublishVolume (ctx context.Context , req * csi.NodeUnpublishVolumeRequest ) (* csi.NodeUnpublishVolumeResponse , error ) {
113126 if err := validateNodeUnpublishVolumeRequest (req ); err != nil {
127+ glog .Errorf ("failed to validate NodeUnpublishVolumeRequest: %v" , err )
114128 return nil , status .Error (codes .InvalidArgument , err .Error ())
115129 }
116130
117131 targetPath := req .GetTargetPath ()
118- volId := req .GetVolumeId ()
119- volUuid := uuidFromVolumeId (volId )
132+ volId := volumeID (req .GetVolumeId ())
120133
121- if err := unmountVolume (targetPath , volUuid ); err != nil {
122- glog .Errorf ("failed to unmount volume %s: %v" )
134+ // Unbind the volume
135+
136+ if err := unmountVolume (targetPath ); err != nil {
137+ glog .Errorf ("failed to unbind volume %s: %v" )
123138 return nil , status .Error (codes .Internal , err .Error ())
124139 }
125140
126- if err := os .Remove (getVolumeRootPath (volUuid )); err != nil {
127- glog .Error ("failed to remove root for volume %s: %v" , volId , err )
128- return nil , status .Error (codes .Internal , err .Error ())
141+ // Clean up
142+
143+ if err := os .Remove (targetPath ); err != nil {
144+ glog .Errorf ("cvmfs: cannot delete target path %s for volume %s: %v" , targetPath , volId , err )
129145 }
130146
131- if err := os .Remove (getConfigFilePath (volUuid )); err != nil {
132- glog .Warningf ("cannot remove config for volume %s: %v" , volId , err )
147+ glog .Infof ("cvmfs: successfuly unbinded volume %s from %s" , volId , targetPath )
148+
149+ return & csi.NodeUnpublishVolumeResponse {}, nil
150+ }
151+
152+ func (ns * nodeServer ) NodeUnstageVolume (ctx context.Context , req * csi.NodeUnstageVolumeRequest ) (* csi.NodeUnstageVolumeResponse , error ) {
153+ if err := validateNodeUnstageVolumeRequest (req ); err != nil {
154+ glog .Errorf ("failed to validate NodeUnstageVolumeRequest: %v" , err )
155+ return nil , status .Error (codes .InvalidArgument , err .Error ())
133156 }
134157
135- if err := purgeVolumeCache (volUuid ); err != nil {
136- glog .Errorf ("failed to delete cache for volume %s: %v" , volId , err )
158+ stagingTargetPath := req .GetStagingTargetPath ()
159+ volId := volumeID (req .GetVolumeId ())
160+
161+ // Unmount the volume
162+
163+ if err := unmountVolume (stagingTargetPath ); err != nil {
164+ glog .Errorf ("failed unmount volume %s: %v" , volId , err )
137165 return nil , status .Error (codes .Internal , err .Error ())
138166 }
139167
140- glog . V ( 4 ). Infof ( "cvmfs: volume %s successfuly unmounted from %s" , req . GetVolumeId (), targetPath )
168+ // Clean up
141169
142- return & csi.NodeUnpublishVolumeResponse {}, nil
143- }
170+ if err := os .Remove (getConfigFilePath (volId )); err != nil {
171+ glog .Errorf ("cvmfs: cannot remove config for volume %s: %v" , volId , err )
172+ }
144173
145- func (ns * nodeServer ) NodeStageVolume (ctx context.Context , req * csi.NodeStageVolumeRequest ) (* csi.NodeStageVolumeResponse , error ) {
146- return nil , status .Error (codes .Unimplemented , "" )
174+ if err := purgeVolumeCache (volId ); err != nil {
175+ glog .Errorf ("cvmfs: cannot delete cache for volume %s: %v" , volId , err )
176+ }
177+
178+ if err := os .Remove (stagingTargetPath ); err != nil {
179+ glog .Errorf ("cvmfs: cannot delete staging target path %s for volume %s: %v" , stagingTargetPath , volId , err )
180+ }
181+
182+ glog .Infof ("cvmfs: successfuly unmounted volume %s from %s" , volId , stagingTargetPath )
183+
184+ return & csi.NodeUnstageVolumeResponse {}, nil
147185}
148186
149- func (ns * nodeServer ) NodeUnstageVolume (ctx context.Context , req * csi.NodeUnstageVolumeRequest ) (* csi.NodeUnstageVolumeResponse , error ) {
150- return nil , status .Error (codes .Unimplemented , "" )
187+ func (ns * nodeServer ) NodeGetCapabilities (ctx context.Context , req * csi.NodeGetCapabilitiesRequest ) (* csi.NodeGetCapabilitiesResponse , error ) {
188+ return & csi.NodeGetCapabilitiesResponse {
189+ Capabilities : []* csi.NodeServiceCapability {
190+ {
191+ Type : & csi.NodeServiceCapability_Rpc {
192+ Rpc : & csi.NodeServiceCapability_RPC {
193+ Type : csi .NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME ,
194+ },
195+ },
196+ },
197+ },
198+ }, nil
151199}
0 commit comments