github.com/vmware/govmomi@v0.37.2/simulator/host_datastore_system.go (about)

     1  /*
     2  Copyright (c) 2017 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package simulator
    18  
    19  import (
    20  	"os"
    21  	"path"
    22  
    23  	"github.com/vmware/govmomi/units"
    24  	"github.com/vmware/govmomi/vim25/methods"
    25  	"github.com/vmware/govmomi/vim25/mo"
    26  	"github.com/vmware/govmomi/vim25/soap"
    27  	"github.com/vmware/govmomi/vim25/types"
    28  )
    29  
    30  type HostDatastoreSystem struct {
    31  	mo.HostDatastoreSystem
    32  
    33  	Host *mo.HostSystem
    34  }
    35  
    36  func (dss *HostDatastoreSystem) add(ctx *Context, ds *Datastore) *soap.Fault {
    37  	info := ds.Info.GetDatastoreInfo()
    38  
    39  	info.Name = ds.Name
    40  
    41  	if e := ctx.Map.FindByName(ds.Name, dss.Datastore); e != nil {
    42  		return Fault(e.Reference().Value, &types.DuplicateName{
    43  			Name:   ds.Name,
    44  			Object: e.Reference(),
    45  		})
    46  	}
    47  
    48  	fi, err := os.Stat(info.Url)
    49  	if err == nil && !fi.IsDir() {
    50  		err = os.ErrInvalid
    51  	}
    52  
    53  	if err != nil {
    54  		switch {
    55  		case os.IsNotExist(err):
    56  			return Fault(err.Error(), &types.NotFound{})
    57  		default:
    58  			return Fault(err.Error(), &types.HostConfigFault{})
    59  		}
    60  	}
    61  
    62  	folder := ctx.Map.getEntityFolder(dss.Host, "datastore")
    63  
    64  	found := false
    65  	if e := ctx.Map.FindByName(ds.Name, folder.ChildEntity); e != nil {
    66  		if e.Reference().Type != "Datastore" {
    67  			return Fault(e.Reference().Value, &types.DuplicateName{
    68  				Name:   ds.Name,
    69  				Object: e.Reference(),
    70  			})
    71  		}
    72  
    73  		// if datastore already exists, use current reference
    74  		found = true
    75  		ds.Self = e.Reference()
    76  	} else {
    77  		// put datastore to folder and generate reference
    78  		folderPutChild(ctx, folder, ds)
    79  	}
    80  
    81  	ds.Summary.Datastore = &ds.Self
    82  	ds.Summary.Name = ds.Name
    83  	ds.Summary.Url = info.Url
    84  	ds.Capability = types.DatastoreCapability{
    85  		DirectoryHierarchySupported:      true,
    86  		RawDiskMappingsSupported:         false,
    87  		PerFileThinProvisioningSupported: true,
    88  		StorageIORMSupported:             types.NewBool(true),
    89  		NativeSnapshotSupported:          types.NewBool(false),
    90  		TopLevelDirectoryCreateSupported: types.NewBool(true),
    91  		SeSparseSupported:                types.NewBool(true),
    92  	}
    93  
    94  	dss.Datastore = append(dss.Datastore, ds.Self)
    95  	dss.Host.Datastore = dss.Datastore
    96  	parent := hostParent(dss.Host)
    97  	ctx.Map.AddReference(ctx, parent, &parent.Datastore, ds.Self)
    98  
    99  	// NOTE: browser must be created after ds is appended to dss.Datastore
   100  	if !found {
   101  		browser := &HostDatastoreBrowser{}
   102  		browser.Datastore = dss.Datastore
   103  		ds.Browser = ctx.Map.Put(browser).Reference()
   104  
   105  		ds.Summary.Capacity = int64(units.TB * 10)
   106  		ds.Summary.FreeSpace = ds.Summary.Capacity
   107  
   108  		info.FreeSpace = ds.Summary.FreeSpace
   109  		info.MaxMemoryFileSize = ds.Summary.Capacity
   110  		info.MaxFileSize = ds.Summary.Capacity
   111  	}
   112  
   113  	return nil
   114  }
   115  
   116  func (dss *HostDatastoreSystem) CreateLocalDatastore(ctx *Context, c *types.CreateLocalDatastore) soap.HasFault {
   117  	r := &methods.CreateLocalDatastoreBody{}
   118  
   119  	ds := &Datastore{}
   120  	ds.Name = c.Name
   121  
   122  	ds.Info = &types.LocalDatastoreInfo{
   123  		DatastoreInfo: types.DatastoreInfo{
   124  			Name: c.Name,
   125  			Url:  c.Path,
   126  		},
   127  		Path: c.Path,
   128  	}
   129  
   130  	ds.Summary.Type = string(types.HostFileSystemVolumeFileSystemTypeOTHER)
   131  	ds.Summary.MaintenanceMode = string(types.DatastoreSummaryMaintenanceModeStateNormal)
   132  	ds.Summary.Accessible = true
   133  
   134  	if err := dss.add(ctx, ds); err != nil {
   135  		r.Fault_ = err
   136  		return r
   137  	}
   138  
   139  	ds.Host = append(ds.Host, types.DatastoreHostMount{
   140  		Key: dss.Host.Reference(),
   141  		MountInfo: types.HostMountInfo{
   142  			AccessMode: string(types.HostMountModeReadWrite),
   143  			Mounted:    types.NewBool(true),
   144  			Accessible: types.NewBool(true),
   145  		},
   146  	})
   147  
   148  	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})
   149  
   150  	r.Res = &types.CreateLocalDatastoreResponse{
   151  		Returnval: ds.Self,
   152  	}
   153  
   154  	return r
   155  }
   156  
   157  func (dss *HostDatastoreSystem) CreateNasDatastore(ctx *Context, c *types.CreateNasDatastore) soap.HasFault {
   158  	r := &methods.CreateNasDatastoreBody{}
   159  
   160  	// validate RemoteHost and RemotePath are specified
   161  	if c.Spec.RemoteHost == "" {
   162  		r.Fault_ = Fault(
   163  			"A specified parameter was not correct: Spec.RemoteHost",
   164  			&types.InvalidArgument{InvalidProperty: "RemoteHost"},
   165  		)
   166  		return r
   167  	}
   168  	if c.Spec.RemotePath == "" {
   169  		r.Fault_ = Fault(
   170  			"A specified parameter was not correct: Spec.RemotePath",
   171  			&types.InvalidArgument{InvalidProperty: "RemotePath"},
   172  		)
   173  		return r
   174  	}
   175  
   176  	ds := &Datastore{}
   177  	ds.Name = path.Base(c.Spec.LocalPath)
   178  
   179  	ds.Info = &types.NasDatastoreInfo{
   180  		DatastoreInfo: types.DatastoreInfo{
   181  			Url: c.Spec.LocalPath,
   182  		},
   183  		Nas: &types.HostNasVolume{
   184  			HostFileSystemVolume: types.HostFileSystemVolume{
   185  				Name: c.Spec.LocalPath,
   186  				Type: c.Spec.Type,
   187  			},
   188  			RemoteHost: c.Spec.RemoteHost,
   189  			RemotePath: c.Spec.RemotePath,
   190  		},
   191  	}
   192  
   193  	ds.Summary.Type = c.Spec.Type
   194  	ds.Summary.MaintenanceMode = string(types.DatastoreSummaryMaintenanceModeStateNormal)
   195  	ds.Summary.Accessible = true
   196  
   197  	if err := dss.add(ctx, ds); err != nil {
   198  		r.Fault_ = err
   199  		return r
   200  	}
   201  
   202  	_ = ds.RefreshDatastore(&types.RefreshDatastore{This: ds.Self})
   203  
   204  	r.Res = &types.CreateNasDatastoreResponse{
   205  		Returnval: ds.Self,
   206  	}
   207  
   208  	return r
   209  }