@@ -2,7 +2,6 @@ package cvmfs
2
2
3
3
import (
4
4
"context"
5
- "errors"
6
5
"os"
7
6
8
7
"github.com/golang/glog"
@@ -17,68 +16,82 @@ type nodeServer struct {
17
16
* csicommon.DefaultNodeServer
18
17
}
19
18
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 ())
23
23
}
24
24
25
- if req .GetVolumeId () == "" {
26
- return errors .New ("Volume ID missing in request" )
27
- }
25
+ // Configuration
28
26
29
- if req .GetTargetPath () == "" {
30
- return errors .New ("Target path missing in request" )
31
- }
27
+ stagingTargetPath := req .GetStagingTargetPath ()
28
+ volId := volumeID (req .GetVolumeId ())
32
29
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
+ }
35
35
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 () )
39
39
}
40
40
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 ,
43
46
}
44
47
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
+ }
47
52
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 )
51
55
}
52
56
53
- targetPath := req .GetTargetPath ()
54
- volId := req .GetVolumeId ()
55
- volUuid := uuidFromVolumeId (volId )
57
+ // Check if the volume is already mounted
56
58
57
- // Configuration
59
+ isMnt , err := isMountPoint ( stagingTargetPath )
58
60
59
- volOptions , err := newVolumeOptions (req .GetVolumeAttributes ())
60
61
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 ())
63
64
}
64
65
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
70
69
}
71
70
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 ())
75
76
}
76
77
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 ())
79
87
}
80
88
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 {
82
95
glog .Errorf ("failed to create mount point for volume %s at %s: %v" , volId , targetPath , err )
83
96
return nil , status .Error (codes .Internal , err .Error ())
84
97
}
@@ -93,59 +106,94 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
93
106
}
94
107
95
108
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 )
97
110
return & csi.NodePublishVolumeResponse {}, nil
98
111
}
99
112
100
- // It's not, mount now
113
+ // It's not, bind- mount now
101
114
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 )
104
117
return nil , status .Error (codes .Internal , err .Error ())
105
118
}
106
119
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 )
108
121
109
122
return & csi.NodePublishVolumeResponse {}, nil
110
123
}
111
124
112
125
func (ns * nodeServer ) NodeUnpublishVolume (ctx context.Context , req * csi.NodeUnpublishVolumeRequest ) (* csi.NodeUnpublishVolumeResponse , error ) {
113
126
if err := validateNodeUnpublishVolumeRequest (req ); err != nil {
127
+ glog .Errorf ("failed to validate NodeUnpublishVolumeRequest: %v" , err )
114
128
return nil , status .Error (codes .InvalidArgument , err .Error ())
115
129
}
116
130
117
131
targetPath := req .GetTargetPath ()
118
- volId := req .GetVolumeId ()
119
- volUuid := uuidFromVolumeId (volId )
132
+ volId := volumeID (req .GetVolumeId ())
120
133
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" )
123
138
return nil , status .Error (codes .Internal , err .Error ())
124
139
}
125
140
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 )
129
145
}
130
146
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 ())
133
156
}
134
157
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 )
137
165
return nil , status .Error (codes .Internal , err .Error ())
138
166
}
139
167
140
- glog . V ( 4 ). Infof ( "cvmfs: volume %s successfuly unmounted from %s" , req . GetVolumeId (), targetPath )
168
+ // Clean up
141
169
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
+ }
144
173
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
147
185
}
148
186
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
151
199
}
0 commit comments