Skip to content

Commit

Permalink
Changing image create and upload in order to support ARM (#103)
Browse files Browse the repository at this point in the history
* Changing image create and upload in order to support ARM
  • Loading branch information
IsabellaMerkulova authored Jan 10, 2024
1 parent ad9dfad commit 96b4e9b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 49 deletions.
66 changes: 37 additions & 29 deletions client/images/v1/images/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,33 +140,38 @@ var imageCreateCommand = cli.Command{
&cli.StringFlag{
Name: "volume-id",
Aliases: []string{"v"},
Usage: "Required if source is volume",
Usage: "Id of the source volume",
Required: true,
},
&cli.StringFlag{
Name: "hw-firmware-type",
Usage: "Specifies the type of firmware with which to boot the guest. Available value is 'bios', 'uefi'",
Required: true,
Name: "hw-firmware-type",
Usage: "Specifies the type of firmware with which to boot the guest. Available value is 'bios', 'uefi'",
},
&cli.StringFlag{
Name: "hw-machine-type",
Usage: "A virtual chipset type. Available value is 'i440', 'q35'",
Required: true,
Name: "hw-machine-type",
Usage: "A virtual chipset type. Available value is 'i440', 'q35'. Cannot be provided for 'aarch64' images",
},
&cli.StringFlag{
Name: "ssh-key",
Usage: "Permission to use a ssh key in instances. Available value is 'allow', 'deny', 'required'",
Required: true,
Name: "architecture",
Usage: "The architecture of the image. Available values are 'x86_64', 'aarch64'. Default to 'x86_64'",
},
&cli.StringFlag{
Name: "os-type",
Usage: "The operating system installed on the image. Available value is 'windows', 'linux'",
Required: true,
Name: "ssh-key",
Usage: "Permission to use a ssh key in instances. Available value is 'allow', 'deny', 'required'. Default to 'allow'",
},
&cli.StringFlag{
Name: "os-type",
Usage: "The operating system installed on the image. Available value is 'windows', 'linux'",
},
&cli.BoolFlag{
Name: "is-baremetal",
Usage: "Set to true if the image will be used by baremetal instances. Defaults to false.",
},
&cli.StringSliceFlag{
Name: "metadata",
Usage: "Image metadata. Example: --metadata one=two --metadata three=four",
Required: false,
},
}, flags.WaitCommandFlags...),
Action: func(c *cli.Context) error {
downloadClient, err := client.NewDownloadImageClientV1(c)
Expand All @@ -175,15 +180,23 @@ var imageCreateCommand = cli.Command{
return cli.NewExitError(err, 1)
}

metadata, err := StringSliceToMetadata(c.StringSlice("metadata"))
if err != nil {
_ = cli.ShowCommandHelp(c, "create")
return cli.NewExitError(err, 1)
}

opts := images.CreateOpts{
Name: c.String("name"),
HwMachineType: types.HwMachineType(c.String("hw-machine-type")),
SshKey: types.SshKeyType(c.String("ssh-key")),
OSType: types.OSType(c.String("os-type")),
IsBaremetal: utils.BoolToPointer(c.Bool("is-baremetal")),
HwFirmwareType: types.HwFirmwareType(c.String("hw-firmware-type")),
Architecture: types.ImageArchitectureType(c.String("architecture")),
Source: types.ImageSourceVolume,
VolumeID: c.String("volume-id"),
Metadata: metadata,
}

results, err := images.Create(downloadClient, opts).Extract()
Expand Down Expand Up @@ -333,29 +346,24 @@ var imageUploadCommand = cli.Command{
Required: true,
},
&cli.StringFlag{
Name: "hw-firmware-type",
Usage: "Specifies the type of firmware with which to boot the guest. Available values are 'bios', 'uefi'",
Required: true,
Name: "hw-firmware-type",
Usage: "Specifies the type of firmware with which to boot the guest. Available values are 'bios', 'uefi'",
},
&cli.StringFlag{
Name: "hw-machine-type",
Usage: "A virtual chipset type. Available values are 'i440', 'q35'",
Required: true,
Name: "hw-machine-type",
Usage: "A virtual chipset type. Available values are 'i440', 'q35'. Cannot be provided for 'aarch64' images",
},
&cli.StringFlag{
Name: "ssh-key",
Usage: "Permission to use a ssh key in instances. Available values are 'allow', 'deny', 'required'",
Required: true,
Name: "ssh-key",
Usage: "Permission to use a ssh key in instances. Available values are 'allow', 'deny', 'required'. Default to 'allow'",
},
&cli.StringFlag{
Name: "os-type",
Usage: "The operating system installed on the image. Available values are 'windows', 'linux'",
Required: true,
Name: "os-type",
Usage: "The operating system installed on the image. Available values are 'windows', 'linux'",
},
&cli.StringFlag{
Name: "architecture",
Usage: "The architecture of the image. Available values are 'x86_64', 'aarch64'",
Required: true,
Name: "architecture",
Usage: "The architecture of the image. Available values are 'x86_64', 'aarch64'. Default to 'x86_64'",
},
&cli.BoolFlag{
Name: "is-baremetal",
Expand All @@ -381,7 +389,7 @@ var imageUploadCommand = cli.Command{
}

opts := images.UploadOpts{
Architecture: c.String("architecture"),
Architecture: types.ImageArchitectureType(c.String("architecture")),
OsVersion: c.String("os-version"),
HwMachineType: types.HwMachineType(c.String("hw-machine-type")),
SshKey: types.SshKeyType(c.String("ssh-key")),
Expand Down
1 change: 1 addition & 0 deletions client/images/v1/testing/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func TestImageMetadata(t *testing.T) {
URL: "http://mirror.noris.net/cirros/0.4.0/cirros-0.4.0-x86_64-disk.img",
HwFirmwareType: "uefi",
Metadata: map[string]string{"key1": "val1", "key2": "val2"},
Architecture: "x86_64",
}

res, err := images.Upload(downloadClient, opts).Extract()
Expand Down
42 changes: 22 additions & 20 deletions gcore/image/v1/images/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ type CreateOptsBuilder interface {

// CreateOpts represents options used to create an image.
type CreateOpts struct {
Name string `json:"name" required:"true" validate:"required"`
HwMachineType types.HwMachineType `json:"hw_machine_type" validate:"required,enum"`
SshKey types.SshKeyType `json:"ssh_key" validate:"required,enum"`
OSType types.OSType `json:"os_type" validate:"required,enum"`
IsBaremetal *bool `json:"is_baremetal,omitempty"`
HwFirmwareType types.HwFirmwareType `json:"hw_firmware_type" validate:"required,enum"`
Source types.ImageSourceType `json:"source" validate:"required,enum"`
VolumeID string `json:"volume_id" required:"true" validate:"required"`
Name string `json:"name" required:"true" validate:"required"`
HwMachineType types.HwMachineType `json:"hw_machine_type,omitempty" validate:"enum"`
SshKey types.SshKeyType `json:"ssh_key,omitempty" validate:"required,enum"`
OSType types.OSType `json:"os_type" validate:"required,enum"`
IsBaremetal *bool `json:"is_baremetal,omitempty"`
HwFirmwareType types.HwFirmwareType `json:"hw_firmware_type,omitempty" validate:"enum"`
Source types.ImageSourceType `json:"source" validate:"required,enum"`
VolumeID string `json:"volume_id" required:"true" validate:"required"`
Metadata map[string]string `json:"metadata,omitempty"`
Architecture types.ImageArchitectureType `json:"architecture,omitempty" validate:"enum"`
}

/*
Expand Down Expand Up @@ -102,18 +104,18 @@ type UploadOptsBuilder interface {

// UploadOpts represents options used to upload an image.
type UploadOpts struct {
OsVersion string `json:"os_version,omitempty"`
HwMachineType types.HwMachineType `json:"hw_machine_type" validate:"required,enum"`
SshKey types.SshKeyType `json:"ssh_key" validate:"required,enum"`
Name string `json:"name" required:"true" validate:"required"`
OsDistro string `json:"os_distro,omitempty"`
OSType types.OSType `json:"os_type" validate:"required,enum"`
URL string `json:"url" required:"true" validate:"required,url"`
IsBaremetal *bool `json:"is_baremetal,omitempty"`
HwFirmwareType types.HwFirmwareType `json:"hw_firmware_type" validate:"required,enum"`
CowFormat bool `json:"cow_format"`
Metadata map[string]string `json:"metadata,omitempty"`
Architecture string `json:"architecture,omitempty"`
OsVersion string `json:"os_version,omitempty"`
HwMachineType types.HwMachineType `json:"hw_machine_type,omitempty" validate:"enum"`
SshKey types.SshKeyType `json:"ssh_key,omitempty" validate:"enum"`
Name string `json:"name" required:"true" validate:"required"`
OsDistro string `json:"os_distro,omitempty"`
OSType types.OSType `json:"os_type" validate:"enum"`
URL string `json:"url" required:"true" validate:"required,url"`
IsBaremetal *bool `json:"is_baremetal,omitempty"`
HwFirmwareType types.HwFirmwareType `json:"hw_firmware_type,omitempty" validate:"enum"`
CowFormat bool `json:"cow_format"`
Metadata map[string]string `json:"metadata,omitempty"`
Architecture types.ImageArchitectureType `json:"architecture,omitempty" validate:"enum"`
}

// Validate
Expand Down
1 change: 1 addition & 0 deletions gcore/image/v1/images/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ func TestCreate(t *testing.T) {
options := images.CreateOpts{
Name: "test_image",
HwMachineType: types.HwMachineQ35,
Architecture: types.ArchitectureX8664,
SshKey: types.SshKeyAllow,
OSType: types.OsLinux,
IsBaremetal: &isBm,
Expand Down
61 changes: 61 additions & 0 deletions gcore/image/v1/images/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ type Visibility string
// HwMachineType virtual chipset type.
type HwMachineType string

// ImageArchitectureType an image architecture type.
type ImageArchitectureType string

// SshKeyType whether the image supports SSH key or not
type SshKeyType string

Expand All @@ -29,6 +32,9 @@ const (
HwMachineI440 HwMachineType = "i440"
HwMachineQ35 HwMachineType = "q35"

ArchitectureAarch64 ImageArchitectureType = "aarch64"
ArchitectureX8664 ImageArchitectureType = "x86_64"

SshKeyAllow SshKeyType = "allow"
SshKeyDeny SshKeyType = "deny"
SshKeyRequired SshKeyType = "required"
Expand Down Expand Up @@ -152,6 +158,61 @@ func (v *HwMachineType) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}

func (v ImageArchitectureType) IsValid() error {
switch v {
case ArchitectureAarch64, ArchitectureX8664:
return nil
}
return fmt.Errorf("invalid ImageArchitectureType type: %v", v)
}

func (v ImageArchitectureType) ValidOrNil() (*ImageArchitectureType, error) {
if v.String() == "" {
return nil, nil
}
err := v.IsValid()
if err != nil {
return &v, err
}
return &v, nil
}

func (v ImageArchitectureType) String() string {
return string(v)
}

func (v ImageArchitectureType) List() []ImageArchitectureType {
return []ImageArchitectureType{ArchitectureAarch64, ArchitectureX8664}
}

func (v ImageArchitectureType) StringList() []string {
var s []string
for _, v := range v.List() {
s = append(s, v.String())
}
return s
}

// UnmarshalJSON - implements Unmarshaler interface for ImageArchitectureType
func (v *ImageArchitectureType) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
vt := ImageArchitectureType(s)
err := vt.IsValid()
if err != nil {
return err
}
*v = vt
return nil
}

// MarshalJSON - implements Marshaler interface for ImageArchitectureType
func (v *ImageArchitectureType) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}

func (v SshKeyType) IsValid() error {
switch v {
case SshKeyAllow, SshKeyDeny, SshKeyRequired:
Expand Down

0 comments on commit 96b4e9b

Please sign in to comment.