package oci import ( "context" "fmt" "time" "github.com/oracle/oci-go-sdk/v65/core" ) // Image 是一个可用的实例镜像。 type Image struct { ID string `json:"id"` DisplayName string `json:"displayName"` OperatingSystem string `json:"operatingSystem"` OperatingSystemVersion string `json:"operatingSystemVersion"` SizeInMBs int64 `json:"sizeInMBs"` TimeCreated *time.Time `json:"timeCreated"` } // ImagesQuery 是镜像查询条件。 type ImagesQuery struct { Region string // 目标区域,空则用凭据默认区域 OperatingSystem string // 如 Canonical Ubuntu、Oracle Linux Shape string // 只返回兼容该 shape 的镜像,如 VM.Standard.A1.Flex } // ListImages 实现 Client:分页列出租户可用的平台镜像。 func (c *RealClient) ListImages(ctx context.Context, cred Credentials, q ImagesQuery) ([]Image, error) { cc, err := core.NewComputeClientWithConfigurationProvider(provider(cred)) if err != nil { return nil, fmt.Errorf("new compute client: %w", err) } applyProxy(&cc.BaseClient, cred) if q.Region != "" { cc.SetRegion(normalizeRegion(q.Region)) } var images []Image var page *string for { resp, err := cc.ListImages(ctx, buildImagesRequest(cred, q, page)) if err != nil { return nil, fmt.Errorf("list images: %w", err) } for _, item := range resp.Items { images = append(images, toImage(item)) } if resp.OpcNextPage == nil { return orEmpty(images), nil } page = resp.OpcNextPage } } // GetImage 实现 Client:查询单个镜像(按 imageId 补显示名等信息)。 func (c *RealClient) GetImage(ctx context.Context, cred Credentials, region, imageID string) (Image, error) { cc, err := core.NewComputeClientWithConfigurationProvider(provider(cred)) if err != nil { return Image{}, fmt.Errorf("new compute client: %w", err) } applyProxy(&cc.BaseClient, cred) if region != "" { cc.SetRegion(normalizeRegion(region)) } resp, err := cc.GetImage(ctx, core.GetImageRequest{ImageId: &imageID}) if err != nil { return Image{}, fmt.Errorf("get image: %w", err) } return toImage(resp.Image), nil } // buildImagesRequest 组装镜像列表请求;过滤条件仅在非空时下发。 func buildImagesRequest(cred Credentials, q ImagesQuery, page *string) core.ListImagesRequest { req := core.ListImagesRequest{ CompartmentId: cred.EffectiveCompartment(), Page: page, LifecycleState: core.ImageLifecycleStateAvailable, } if q.OperatingSystem != "" { req.OperatingSystem = &q.OperatingSystem } if q.Shape != "" { req.Shape = &q.Shape } return req } func toImage(img core.Image) Image { out := Image{ ID: deref(img.Id), DisplayName: deref(img.DisplayName), OperatingSystem: deref(img.OperatingSystem), OperatingSystemVersion: deref(img.OperatingSystemVersion), TimeCreated: sdkTime(img.TimeCreated), } if img.SizeInMBs != nil { out.SizeInMBs = *img.SizeInMBs } return out }