@@ -177,22 +177,11 @@ func (dh driveHandler) MountDrive(ctx context.Context, req *drivemount.MountDriv
177
177
logger = logger .WithField ("drive_path" , drive .Path ())
178
178
179
179
// Do a basic check that we won't be mounting over any important system directories
180
- resolvedDest , err := evalAnySymlinks (req .DestinationPath )
181
- if err != nil {
182
- return nil , errors .Wrapf (err ,
183
- "failed to evaluate any symlinks in drive mount destination %q" , req .DestinationPath )
184
- }
185
-
186
- for _ , systemDir := range bannedSystemDirs {
187
- if isOrUnderDir (resolvedDest , systemDir ) {
188
- return nil , errors .Errorf (
189
- "drive mount destination %q resolves to path %q under banned system directory %q" ,
190
- req .DestinationPath , resolvedDest , systemDir ,
191
- )
192
- }
180
+ if err := checkImportantDirs (req .DestinationPath ); err != nil {
181
+ return nil , err
193
182
}
194
183
195
- err = os .MkdirAll (req .DestinationPath , 0700 )
184
+ err : = os .MkdirAll (req .DestinationPath , 0700 )
196
185
if err != nil {
197
186
return nil , errors .Wrapf (err , "failed to create drive mount destination %q" , req .DestinationPath )
198
187
}
@@ -229,6 +218,45 @@ func (dh driveHandler) MountDrive(ctx context.Context, req *drivemount.MountDriv
229
218
drive .Path (), req .DestinationPath )
230
219
}
231
220
221
+ func (dh driveHandler ) UnmountDrive (ctx context.Context , req * drivemount.UnmountDriveRequest ) (* empty.Empty , error ) {
222
+ drive , ok := dh .GetDrive (req .DriveID )
223
+ if ! ok {
224
+ return nil , fmt .Errorf ("drive %q could not be found" , req .DriveID )
225
+ }
226
+
227
+ // Do a basic check that we won't be mounting over any important system directories
228
+ if err := checkImportantDirs (req .DestinationPath ); err != nil {
229
+ return nil , err
230
+ }
231
+
232
+ err := mount .Unmount (req .DestinationPath , 0 )
233
+ if err == nil {
234
+ return & empty.Empty {}, nil
235
+ }
236
+
237
+ return nil , errors .Errorf ("failed to unmount the drive from %q to %q" ,
238
+ drive .Path (), req .DestinationPath )
239
+ }
240
+
241
+ func checkImportantDirs (path string ) error {
242
+ resolvedDest , err := evalAnySymlinks (path )
243
+ if err != nil {
244
+ return errors .Wrapf (err ,
245
+ "failed to evaluate any symlinks in drive ummount destination %q" , path )
246
+ }
247
+
248
+ for _ , systemDir := range bannedSystemDirs {
249
+ if isOrUnderDir (resolvedDest , systemDir ) {
250
+ return errors .Errorf (
251
+ "drive mount destination %q resolves to path %q under banned system directory %q" ,
252
+ path , resolvedDest , systemDir ,
253
+ )
254
+ }
255
+ }
256
+
257
+ return nil
258
+ }
259
+
232
260
// evalAnySymlinks is similar to filepath.EvalSymlinks, except it will not return an error if part of the
233
261
// provided path does not exist. It will evaluate symlinks present in the path up to a component that doesn't
234
262
// exist, at which point it will just append the rest of the provided path to what has been resolved so far.
0 commit comments