diff --git a/pkg/util/zstack/host.go b/pkg/util/zstack/host.go index b4cef4d8f0..4aeca9aebe 100644 --- a/pkg/util/zstack/host.go +++ b/pkg/util/zstack/host.go @@ -99,6 +99,7 @@ func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) { } istorages := []cloudprovider.ICloudStorage{} for i := 0; i < len(storages); i++ { + storages[i].region = host.zone.region switch storages[i].Type { case StorageTypeLocal: localStorages, err := host.zone.region.getILocalStorages(storages[i].UUID, host.UUID) diff --git a/pkg/util/zstack/image.go b/pkg/util/zstack/image.go index 9e4927e1ad..ef2050f23f 100644 --- a/pkg/util/zstack/image.go +++ b/pkg/util/zstack/image.go @@ -22,6 +22,7 @@ import ( "sort" "time" + "github.com/pkg/errors" "yunion.io/x/onecloud/pkg/util/imagetools" "yunion.io/x/jsonutils" @@ -183,13 +184,20 @@ func (image *SImage) GetCreateTime() time.Time { } func (region *SRegion) GetImage(imageId string) (*SImage, error) { - image := &SImage{storageCache: region.getStorageCache()} - return image, region.client.getResource("images", imageId, image) + image := &SImage{} + err := region.client.getResource("images", imageId, image) + if err != nil { + return nil, errors.Wrapf(err, "region.GetImage") + } + return image, nil } -func (region *SRegion) GetImages(imageId string) ([]SImage, error) { +func (region *SRegion) GetImages(zoneId string, imageId string) ([]SImage, error) { images := []SImage{} params := []string{"q=system=false"} + if len(zoneId) > 0 { + params = append(params, "q=backupStorage.zone.uuid="+zoneId) + } if len(imageId) > 0 { params = append(params, "q=uuid="+imageId) } @@ -199,8 +207,8 @@ func (region *SRegion) GetImages(imageId string) ([]SImage, error) { return images, region.client.listAll("images", params, &images) } -func (region *SRegion) GetBackupStorageUUID() ([]string, error) { - imageServers, err := region.GetImageServers("") +func (region *SRegion) GetBackupStorageUUID(zondId string) ([]string, error) { + imageServers, err := region.GetImageServers(zondId, "") if err != nil { return nil, err } @@ -212,8 +220,8 @@ func (region *SRegion) GetBackupStorageUUID() ([]string, error) { return []string{servers[0].UUID}, nil } -func (region *SRegion) CreateImage(imageName, format, osType, desc string, reader io.Reader, size int64) (*SImage, error) { - backupStorageUUIDs, err := region.GetBackupStorageUUID() +func (region *SRegion) CreateImage(zoneId string, imageName, format, osType, desc string, reader io.Reader, size int64) (*SImage, error) { + backupStorageUUIDs, err := region.GetBackupStorageUUID(zoneId) if err != nil { return nil, err } @@ -250,7 +258,7 @@ func (region *SRegion) CreateImage(imageName, format, osType, desc string, reade body := multipart.NewReader(reader, "", imageName) - image := &SImage{storageCache: region.getStorageCache()} + image := &SImage{} err = region.client.create("images", jsonutils.Marshal(parmas), image) if err != nil { return nil, err diff --git a/pkg/util/zstack/image_server.go b/pkg/util/zstack/image_server.go index fed09c0c3f..385a1b5300 100644 --- a/pkg/util/zstack/image_server.go +++ b/pkg/util/zstack/image_server.go @@ -47,7 +47,7 @@ func (v ImageServers) Less(i, j int) bool { return true } -func (region *SRegion) GetImageServers(zoneId string) ([]SImageServer, error) { +func (region *SRegion) GetImageServers(zoneId, serverId string) ([]SImageServer, error) { servers := []SImageServer{} params := []string{"q=state=Enabled", "q=status=Connected"} if SkipEsxi { @@ -56,5 +56,8 @@ func (region *SRegion) GetImageServers(zoneId string) ([]SImageServer, error) { if len(zoneId) > 0 { params = append(params, "q=zone.uuid="+zoneId) } + if len(serverId) > 0 { + params = append(params, "q=uuid="+serverId) + } return servers, region.client.listAll("backup-storage", params, &servers) } diff --git a/pkg/util/zstack/region.go b/pkg/util/zstack/region.go index e32fc5face..1b9f8bb302 100644 --- a/pkg/util/zstack/region.go +++ b/pkg/util/zstack/region.go @@ -35,8 +35,6 @@ type SRegion struct { izones []cloudprovider.ICloudZone ivpcs []cloudprovider.ICloudVpc - - storageCache *SStoragecache } func (region *SRegion) GetClient() *SZStackClient { @@ -127,12 +125,15 @@ func (region *SRegion) GetIStoragecacheById(id string) (cloudprovider.ICloudStor } func (region *SRegion) GetIStoragecaches() ([]cloudprovider.ICloudStoragecache, error) { - region.storageCache = &SStoragecache{region: region} - return []cloudprovider.ICloudStoragecache{region.storageCache}, nil -} - -func (region *SRegion) getStorageCache() *SStoragecache { - return &SStoragecache{region: region} + zones, err := region.GetZones("") + if err != nil { + return nil, err + } + icaches := []cloudprovider.ICloudStoragecache{} + for i := 0; i < len(zones); i++ { + icaches = append(icaches, &SStoragecache{ZoneId: zones[i].UUID, region: region}) + } + return icaches, nil } func (region *SRegion) GetIVpcById(vpcId string) (cloudprovider.ICloudVpc, error) { diff --git a/pkg/util/zstack/shell/image.go b/pkg/util/zstack/shell/image.go index 0ae48fdb8a..4300e61fac 100644 --- a/pkg/util/zstack/shell/image.go +++ b/pkg/util/zstack/shell/image.go @@ -23,10 +23,11 @@ import ( func init() { type ImageListOptions struct { + ZoneId string ImageId string } shellutils.R(&ImageListOptions{}, "image-list", "List images", func(cli *zstack.SRegion, args *ImageListOptions) error { - images, err := cli.GetImages(args.ImageId) + images, err := cli.GetImages(args.ZoneId, args.ImageId) if err != nil { return err } @@ -35,6 +36,7 @@ func init() { }) type ImageCreateOptions struct { + ZONE string FILE string FORMAT string `choices:"qcow2|raw|iso"` PLATFORM string `choices:"Linux|Windows|Other"` @@ -51,7 +53,7 @@ func init() { if err != nil { return err } - image, err := cli.CreateImage(args.FILE, args.FORMAT, args.PLATFORM, args.Desc, f, finfo.Size()) + image, err := cli.CreateImage(args.ZONE, args.FILE, args.FORMAT, args.PLATFORM, args.Desc, f, finfo.Size()) if err != nil { return err } diff --git a/pkg/util/zstack/shell/image_server.go b/pkg/util/zstack/shell/image_server.go index 5cd71f8fb0..c81f641296 100644 --- a/pkg/util/zstack/shell/image_server.go +++ b/pkg/util/zstack/shell/image_server.go @@ -21,10 +21,11 @@ import ( func init() { type ImageServerListOptions struct { - ZoneId string + ZoneId string + ServerId string } shellutils.R(&ImageServerListOptions{}, "image-server-list", "List image servers", func(cli *zstack.SRegion, args *ImageServerListOptions) error { - servers, err := cli.GetImageServers(args.ZoneId) + servers, err := cli.GetImageServers(args.ZoneId, args.ServerId) if err != nil { return err } diff --git a/pkg/util/zstack/storage.go b/pkg/util/zstack/storage.go index 36123ae988..24d6b8a5a2 100644 --- a/pkg/util/zstack/storage.go +++ b/pkg/util/zstack/storage.go @@ -210,8 +210,7 @@ func (storage *SStorage) GetEnabled() bool { } func (storage *SStorage) GetIStoragecache() cloudprovider.ICloudStoragecache { - storage.region.GetIStoragecaches() - return storage.region.storageCache + return &SStoragecache{ZoneId: storage.ZoneUUID, region: storage.region} } func (storage *SStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) { diff --git a/pkg/util/zstack/storage_local.go b/pkg/util/zstack/storage_local.go index 0e998e8007..685747ecc1 100644 --- a/pkg/util/zstack/storage_local.go +++ b/pkg/util/zstack/storage_local.go @@ -182,8 +182,17 @@ func (storage *SLocalStorage) GetEnabled() bool { } func (storage *SLocalStorage) GetIStoragecache() cloudprovider.ICloudStoragecache { - storage.region.GetIStoragecaches() - return storage.region.storageCache + cache := &SStoragecache{region: storage.region} + host, _ := storage.region.GetHost(storage.HostUUID) + if host != nil { + cache.ZoneId = host.ZoneUUID + } else { + _storage, _ := storage.region.GetStorage(storage.primaryStorageID) + if _storage != nil { + cache.ZoneId = _storage.ZoneUUID + } + } + return cache } func (storage *SLocalStorage) CreateIDisk(name string, sizeGb int, desc string) (cloudprovider.ICloudDisk, error) { diff --git a/pkg/util/zstack/storagecache.go b/pkg/util/zstack/storagecache.go index 8c630f8d60..9da4a23863 100644 --- a/pkg/util/zstack/storagecache.go +++ b/pkg/util/zstack/storagecache.go @@ -31,6 +31,7 @@ import ( ) type SStoragecache struct { + ZoneId string region *SRegion } @@ -39,11 +40,11 @@ func (scache *SStoragecache) GetMetadata() *jsonutils.JSONDict { } func (scache *SStoragecache) GetId() string { - return fmt.Sprintf("%s-%s", scache.region.client.providerID, scache.region.GetId()) + return fmt.Sprintf("%s-%s/%s", scache.region.client.providerID, scache.region.GetId(), scache.ZoneId) } func (scache *SStoragecache) GetName() string { - return fmt.Sprintf("%s-%s", scache.region.client.providerName, scache.region.GetId()) + return fmt.Sprintf("%s-%s/%s", scache.region.client.providerName, scache.region.GetId(), scache.ZoneId) } func (scache *SStoragecache) GetStatus() string { @@ -55,7 +56,7 @@ func (scache *SStoragecache) Refresh() error { } func (scache *SStoragecache) GetGlobalId() string { - return fmt.Sprintf("%s-%s", scache.region.client.providerID, scache.region.GetGlobalId()) + return scache.GetId() } func (scache *SStoragecache) IsEmulated() bool { @@ -63,7 +64,7 @@ func (scache *SStoragecache) IsEmulated() bool { } func (scache *SStoragecache) GetIImages() ([]cloudprovider.ICloudImage, error) { - images, err := scache.region.GetImages("") + images, err := scache.region.GetImages(scache.ZoneId, "") if err != nil { return nil, err } @@ -118,7 +119,7 @@ func (self *SStoragecache) uploadImage(ctx context.Context, userCred mcclient.To log.Infof("meta data %s", meta) size, _ := meta.Int("size") - img, err := self.region.CreateImage(image.ImageName, string(qemuimg.QCOW2), image.OsType, "", reader, size) + img, err := self.region.CreateImage(self.ZoneId, image.ImageName, string(qemuimg.QCOW2), image.OsType, "", reader, size) if err != nil { return "", err }