Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Add labels to VMs #516

Merged
merged 1 commit into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/ignite/cmd/vmcmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func addCreateFlags(fs *pflag.FlagSet, cf *run.CreateFlags) {
// Register flags for simple types (int, string, etc.)
fs.Uint64Var(&cf.VM.Spec.CPUs, "cpus", cf.VM.Spec.CPUs, "VM vCPU count, 1 or even numbers between 1 and 32")
fs.StringVar(&cf.VM.Spec.Kernel.CmdLine, "kernel-args", cf.VM.Spec.Kernel.CmdLine, "Set the command line for the kernel")
fs.StringArrayVarP(&cf.Labels, "label", "l", cf.Labels, "Set a label (foo=bar)")

// Register more complex flags with their own flag types
cmdutil.SizeVar(fs, &cf.VM.Spec.Memory, "memory", "Amount of RAM to allocate for the VM")
Expand Down
5 changes: 5 additions & 0 deletions cmd/ignite/run/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type CreateFlags struct {
SSH api.SSH
ConfigFile string
VM *api.VM
Labels []string
}

type createOptions struct {
Expand Down Expand Up @@ -115,6 +116,10 @@ func Create(co *createOptions) error {
if err := metadata.SetNameAndUID(co.VM, providers.Client); err != nil {
return err
}
// Set VM labels.
if err := metadata.SetLabels(co.VM, co.Labels); err != nil {
return err
}
defer metadata.Cleanup(co.VM, false) // TODO: Handle silent

if err := providers.Client.VMs().Set(co.VM); err != nil {
Expand Down
1 change: 1 addition & 0 deletions docs/cli/ignite/ignite_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ignite create <OCI image> [flags]
-h, --help help for create
--kernel-args string Set the command line for the kernel (default "console=ttyS0 reboot=k panic=1 pci=off ip=dhcp")
-k, --kernel-image oci-image Specify an OCI image containing the kernel at /boot/vmlinux and optionally, modules (default weaveworks/ignite-kernel:4.19.47)
-l, --label stringArray Set a label (foo=bar)
--memory size Amount of RAM to allocate for the VM (default 512.0 MB)
-n, --name string Specify the name
-p, --ports strings Map host ports to VM ports
Expand Down
1 change: 1 addition & 0 deletions docs/cli/ignite/ignite_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ ignite run <OCI image> [flags]
-i, --interactive Attach to the VM after starting
--kernel-args string Set the command line for the kernel (default "console=ttyS0 reboot=k panic=1 pci=off ip=dhcp")
-k, --kernel-image oci-image Specify an OCI image containing the kernel at /boot/vmlinux and optionally, modules (default weaveworks/ignite-kernel:4.19.47)
-l, --label stringArray Set a label (foo=bar)
--memory size Amount of RAM to allocate for the VM (default 512.0 MB)
-n, --name string Specify the name
-p, --ports strings Map host ports to VM ports
Expand Down
1 change: 1 addition & 0 deletions docs/cli/ignite/ignite_vm_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ignite vm create <OCI image> [flags]
-h, --help help for create
--kernel-args string Set the command line for the kernel (default "console=ttyS0 reboot=k panic=1 pci=off ip=dhcp")
-k, --kernel-image oci-image Specify an OCI image containing the kernel at /boot/vmlinux and optionally, modules (default weaveworks/ignite-kernel:4.19.47)
-l, --label stringArray Set a label (foo=bar)
--memory size Amount of RAM to allocate for the VM (default 512.0 MB)
-n, --name string Specify the name
-p, --ports strings Map host ports to VM ports
Expand Down
1 change: 1 addition & 0 deletions docs/cli/ignite/ignite_vm_run.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ ignite vm run <OCI image> [flags]
-i, --interactive Attach to the VM after starting
--kernel-args string Set the command line for the kernel (default "console=ttyS0 reboot=k panic=1 pci=off ip=dhcp")
-k, --kernel-image oci-image Specify an OCI image containing the kernel at /boot/vmlinux and optionally, modules (default weaveworks/ignite-kernel:4.19.47)
-l, --label stringArray Set a label (foo=bar)
--memory size Amount of RAM to allocate for the VM (default 512.0 MB)
-n, --name string Specify the name
-p, --ports strings Map host ports to VM ports
Expand Down
28 changes: 27 additions & 1 deletion pkg/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package metadata

import (
"errors"
"fmt"
"os"
"path"
"regexp"
"strings"

"github.com/weaveworks/gitops-toolkit/pkg/filter"
"github.com/weaveworks/gitops-toolkit/pkg/runtime"
Expand All @@ -21,14 +23,17 @@ var (
uidRegex = regexp.MustCompile(`^[a-z0-9]{16}$`)
)

// ErrNilObject is returned when the runtime object being initialized is nil.
var ErrNilObject = errors.New("object cannot be nil when initializing runtime data")

type Metadata interface {
runtime.Object
}

// SetNameAndUID sets the name and UID for an object if that isn't set automatically
func SetNameAndUID(obj runtime.Object, c *client.Client) error {
if obj == nil {
return fmt.Errorf("object cannot be nil when initializing runtime data")
return ErrNilObject
}

if c == nil {
Expand All @@ -44,6 +49,27 @@ func SetNameAndUID(obj runtime.Object, c *client.Client) error {
return processName(obj, c)
}

// SetLabels metadata labels for a given object.
func SetLabels(obj runtime.Object, labels []string) error {
if obj == nil {
return ErrNilObject
}

for _, label := range labels {
kv := strings.SplitN(label, "=", 2)
// Check the length of key/val. Must be exactly 2.
if len(kv) != 2 {
return fmt.Errorf("invalid label value %q: supported syntax: --label <key>=<value>", label)
}
// Label name must not be empty.
if kv[0] == "" {
return fmt.Errorf("invalid label %q, name empty", label)
}
obj.SetLabel(kv[0], kv[1])
}
return nil
}

// processUID a new 8-byte ID and handles directory creation/deletion
func processUID(obj runtime.Object, c *client.Client) error {
uid := obj.GetUID().String()
Expand Down
68 changes: 68 additions & 0 deletions pkg/metadata/metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package metadata

import (
"testing"

"github.com/weaveworks/gitops-toolkit/pkg/runtime"
api "github.com/weaveworks/ignite/pkg/apis/ignite"
)

func TestSetLabels(t *testing.T) {
cases := []struct {
name string
obj runtime.Object
labels []string
wantLabels map[string]string
err bool
}{
{
name: "nil runtime object",
obj: nil,
err: true,
},
{
name: "valid labels",
obj: &api.VM{},
labels: []string{
"label1=value1",
"label2=value2",
"label3=",
"label4=value4,label5=value5",
},
wantLabels: map[string]string{
"label1": "value1",
"label2": "value2",
"label3": "",
"label4": "value4,label5=value5",
},
},
{
name: "invalid label - key without value",
obj: &api.VM{},
labels: []string{"key1"},
err: true,
},
{
name: "invalid label - empty name",
obj: &api.VM{},
labels: []string{"="},
err: true,
},
}

for _, rt := range cases {
t.Run(rt.name, func(t *testing.T) {
err := SetLabels(rt.obj, rt.labels)
if (err != nil) != rt.err {
t.Errorf("expected error %t, actual: %v", rt.err, err)
}

// Check the values of all the labels.
for k, v := range rt.wantLabels {
if rt.obj.GetLabel(k) != v {
t.Errorf("expected label key %q to have value %q, actual: %q", k, v, rt.obj.GetLabel(k))
}
}
})
}
}