summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go')
-rw-r--r--vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go145
1 files changed, 145 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go b/vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go
new file mode 100644
index 00000000..7164fbbe
--- /dev/null
+++ b/vendor/github.com/mitchellh/packer/vendor/github.com/vmware/govmomi/object/datastore_file_manager.go
@@ -0,0 +1,145 @@
+/*
+Copyright (c) 2017 VMware, Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package object
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "path"
+ "strings"
+
+ "github.com/vmware/govmomi/vim25/soap"
+)
+
+// DatastoreFileManager combines FileManager and VirtualDiskManager to manage files on a Datastore
+type DatastoreFileManager struct {
+ Datacenter *Datacenter
+ Datastore *Datastore
+ FileManager *FileManager
+ VirtualDiskManager *VirtualDiskManager
+
+ Force bool
+}
+
+// NewFileManager creates a new instance of DatastoreFileManager
+func (d Datastore) NewFileManager(dc *Datacenter, force bool) *DatastoreFileManager {
+ c := d.Client()
+
+ m := &DatastoreFileManager{
+ Datacenter: dc,
+ Datastore: &d,
+ FileManager: NewFileManager(c),
+ VirtualDiskManager: NewVirtualDiskManager(c),
+ Force: force,
+ }
+
+ return m
+}
+
+// Delete dispatches to the appropriate Delete method based on file name extension
+func (m *DatastoreFileManager) Delete(ctx context.Context, name string) error {
+ switch path.Ext(name) {
+ case ".vmdk":
+ return m.DeleteVirtualDisk(ctx, name)
+ default:
+ return m.DeleteFile(ctx, name)
+ }
+}
+
+// DeleteFile calls FileManager.DeleteDatastoreFile
+func (m *DatastoreFileManager) DeleteFile(ctx context.Context, name string) error {
+ p := m.Path(name)
+
+ task, err := m.FileManager.DeleteDatastoreFile(ctx, p.String(), m.Datacenter)
+ if err != nil {
+ return err
+ }
+
+ return task.Wait(ctx)
+}
+
+// DeleteVirtualDisk calls VirtualDiskManager.DeleteVirtualDisk
+// Regardless of the Datastore type, DeleteVirtualDisk will fail if 'ddb.deletable=false',
+// so if Force=true this method attempts to set 'ddb.deletable=true' before starting the delete task.
+func (m *DatastoreFileManager) DeleteVirtualDisk(ctx context.Context, name string) error {
+ p := m.Path(name)
+
+ var merr error
+
+ if m.Force {
+ merr = m.markDiskAsDeletable(ctx, p)
+ }
+
+ task, err := m.VirtualDiskManager.DeleteVirtualDisk(ctx, p.String(), m.Datacenter)
+ if err != nil {
+ log.Printf("markDiskAsDeletable(%s): %s", p, merr)
+ return err
+ }
+
+ return task.Wait(ctx)
+}
+
+// Path converts path name to a DatastorePath
+func (m *DatastoreFileManager) Path(name string) *DatastorePath {
+ var p DatastorePath
+
+ if !p.FromString(name) {
+ p.Path = name
+ p.Datastore = m.Datastore.Name()
+ }
+
+ return &p
+}
+
+func (m *DatastoreFileManager) markDiskAsDeletable(ctx context.Context, path *DatastorePath) error {
+ r, _, err := m.Datastore.Download(ctx, path.Path, &soap.DefaultDownload)
+ if err != nil {
+ return err
+ }
+
+ defer r.Close()
+
+ hasFlag := false
+ buf := new(bytes.Buffer)
+
+ s := bufio.NewScanner(&io.LimitedReader{R: r, N: 2048}) // should be only a few hundred bytes, limit to be sure
+
+ for s.Scan() {
+ line := s.Text()
+ if strings.HasPrefix(line, "ddb.deletable") {
+ hasFlag = true
+ continue
+ }
+
+ fmt.Fprintln(buf, line)
+ }
+
+ if err := s.Err(); err != nil {
+ return err // any error other than EOF
+ }
+
+ if !hasFlag {
+ return nil // already deletable, so leave as-is
+ }
+
+ // rewrite the .vmdk with ddb.deletable flag removed (the default is true)
+ return m.Datastore.Upload(ctx, buf, path.Path, &soap.DefaultUpload)
+}