diff --git a/cmd/climc/shell/image/images.go b/cmd/climc/shell/image/images.go index fb8cb403b2..c5422cc171 100644 --- a/cmd/climc/shell/image/images.go +++ b/cmd/climc/shell/image/images.go @@ -142,13 +142,15 @@ func init() { type ImageListOptions struct { options.BaseListOptions - IsPublic string `help:"filter images public or not(True, False or None)" choices:"true|false"` - IsStandard string `help:"filter images standard or non-standard" choices:"true|false"` - Protected string `help:"filter images by protected" choices:"true|false"` - IsUefi bool `help:"list uefi image"` - Format []string `help:"Disk formats"` - SubFormats []string `help:"Sub formats"` - Name string `help:"Name filter"` + IsPublic string `help:"filter images public or not(True, False or None)" choices:"true|false"` + IsStandard string `help:"filter images standard or non-standard" choices:"true|false"` + Protected string `help:"filter images by protected" choices:"true|false"` + IsUefi bool `help:"list uefi image"` + Format []string `help:"Disk formats"` + SubFormats []string `help:"Sub formats"` + Name string `help:"Name filter"` + OsType []string `help:"Type of OS filter e.g. 'Windows, Linux, Freebsd, Android, macOS, VMWare'"` + Distribution []string `help:"Distribution filter, e.g. 'CentOS, Ubuntu, Debian, Windows'"` } R(&ImageListOptions{}, "image-list", "List images", func(s *mcclient.ClientSession, args *ImageListOptions) error { params, err := args.Params() @@ -187,6 +189,12 @@ func init() { if len(args.SubFormats) > 0 { params.Add(jsonutils.Marshal(args.SubFormats), "sub_formats") } + if len(args.OsType) > 0 { + params.Add(jsonutils.NewStringArray(args.OsType), "os_types") + } + if len(args.Distribution) > 0 { + params.Add(jsonutils.NewStringArray(args.Distribution), "distributions") + } result, err := modules.Images.List(s, params) if err != nil { return err diff --git a/pkg/apis/image/image.go b/pkg/apis/image/image.go index 927172e8e2..88ba6bc7c9 100644 --- a/pkg/apis/image/image.go +++ b/pkg/apis/image/image.go @@ -43,6 +43,12 @@ type ImageListInput struct { // 是否为数据盘 IsData *bool `json:"is_data"` + + // 操作系统类型,可能值为: Linux, Windows, FreeBSD 等 + OsTypes []string `json:"os_types"` + + // 发行版本,可能值为: CentOS, Ubuntu, Debian, ArchLinux, OpenEuler 等 + Distributions []string `json:"distributions"` } type GuestImageListInput struct { diff --git a/pkg/image/models/images.go b/pkg/image/models/images.go index ac73fcbf77..7c9272708b 100644 --- a/pkg/image/models/images.go +++ b/pkg/image/models/images.go @@ -1263,6 +1263,23 @@ func (manager *SImageManager) ListItemFilter( q = q.IsFalse("is_data") } } + + propFilter := func(nameKeys []string, vals []string) { + if len(vals) == 0 { + return + } + propQ := ImagePropertyManager.Query().In("name", nameKeys) + conds := make([]sqlchemy.ICondition, 0) + for _, val := range vals { + conds = append(conds, sqlchemy.Like(propQ.Field("value"), val)) + } + propQ.Filter(sqlchemy.OR(conds...)) + propSq := propQ.SubQuery() + q = q.Join(propSq, sqlchemy.Equals(q.Field("id"), propSq.Field("image_id"))) + } + propFilter([]string{api.IMAGE_OS_TYPE}, query.OsTypes) + propFilter([]string{api.IMAGE_OS_DISTRO, "distro"}, query.Distributions) + return q, nil }