Files

101 lines
3.0 KiB
Go

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
}