fix(esxi): add ListPath for storage and use it to check iso

When remote iso file is used, CheckFile will failed.
This commit is contained in:
rainzm
2021-04-02 19:21:35 +08:00
parent 45538dc807
commit f8a822c5f3
2 changed files with 91 additions and 7 deletions
@@ -153,7 +153,7 @@ func (c *SAgentImageCacheManager) prefetchImageCacheByUpload(ctx context.Context
return nil, err
}
localImgPath, _ := localImage.GetString("path")
localImgSize, _ := localImage.Int("size")
//localImgSize, _ := localImage.Int("size")
client, err := esxi.NewESXiClientFromAccessInfo(ctx, &data.Datastore)
if err != nil {
@@ -183,14 +183,13 @@ func (c *SAgentImageCacheManager) prefetchImageCacheByUpload(ctx context.Context
exists = true
}
} else {
ret, err := ds.CheckFile(ctx, remotePath)
_, err := ds.ListPath(ctx, remotePath)
if err != nil {
log.Debugf("ds.CheckFile failed: %s", err)
} else {
if int64(ret.Size) == localImgSize {
// exist and same size
exists = true
if errors.Cause(err) != errors.ErrNotFound {
return nil, errors.Wrapf(err, "unable to check file with path %s", remotePath)
}
} else {
exists = true
}
}
log.Debugf("exist: %t, remotePath: %s", exists, remotePath)
+85
View File
@@ -593,6 +593,91 @@ func (self *SDatastore) ListDir(ctx context.Context, remotePath string) ([]SData
return ret, nil
}
func (self *SDatastore) listPath(b *object.HostDatastoreBrowser, path string, spec types.HostDatastoreBrowserSearchSpec) ([]types.HostDatastoreBrowserSearchResults, error) {
ctx := context.TODO()
path = self.getDatastoreObj().Path(path)
search := b.SearchDatastore
task, err := search(ctx, path, &spec)
if err != nil {
return nil, err
}
info, err := task.WaitForResult(ctx, nil)
if err != nil {
return nil, err
}
switch r := info.Result.(type) {
case types.HostDatastoreBrowserSearchResults:
return []types.HostDatastoreBrowserSearchResults{r}, nil
case types.ArrayOfHostDatastoreBrowserSearchResults:
return r.HostDatastoreBrowserSearchResults, nil
default:
return nil, errors.Error(fmt.Sprintf("unknown result type: %T", r))
}
}
func (self *SDatastore) ListPath(ctx context.Context, remotePath string) ([]types.HostDatastoreBrowserSearchResults, error) {
//types.HostDatastoreBrowserSearchResults
ds := self.getDatastoreObj()
b, err := ds.Browser(ctx)
if err != nil {
return nil, err
}
ret := make([]types.HostDatastoreBrowserSearchResults, 0)
spec := types.HostDatastoreBrowserSearchSpec{
MatchPattern: []string{"*"},
Details: &types.FileQueryFlags{
FileType: true,
FileSize: true,
FileOwner: types.NewBool(true), // TODO: omitempty is generated, but seems to be required
Modification: true,
},
}
for i := 0; ; i++ {
r, err := self.listPath(b, remotePath, spec)
if err != nil {
// Treat the argument as a match pattern if not found as directory
if i == 0 && types.IsFileNotFound(err) || isInvalid(err) {
spec.MatchPattern[0] = path.Base(remotePath)
remotePath = path.Dir(remotePath)
continue
}
if types.IsFileNotFound(err) {
return nil, errors.ErrNotFound
}
return nil, err
}
if i == 1 && len(r) == 1 && len(r[0].File) == 0 {
return nil, errors.ErrNotFound
}
for n := range r {
ret = append(ret, r[n])
}
break
}
return ret, nil
}
func isInvalid(err error) bool {
if f, ok := err.(types.HasFault); ok {
switch f.Fault().(type) {
case *types.InvalidArgument:
return true
}
}
return false
}
func (self *SDatastore) CheckFile(ctx context.Context, remotePath string) (*SDatastoreFileInfo, error) {
url := self.GetPathUrl(remotePath)