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

Do not use the Storage/Client in ignite-spawn #257

Merged
merged 3 commits into from
Jul 31, 2019
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
52 changes: 34 additions & 18 deletions cmd/ignite-spawn/ignite-spawn.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/weaveworks/ignite/cmd/ignite/cmd/cmdutil"
api "github.com/weaveworks/ignite/pkg/apis/ignite"
"github.com/weaveworks/ignite/pkg/apis/ignite/scheme"
meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1"
"github.com/weaveworks/ignite/pkg/constants"
"github.com/weaveworks/ignite/pkg/container"
Expand All @@ -24,7 +25,22 @@ func main() {
RunIgniteSpawn()
}

func StartVM(co *options) error {
func decodeVM(vmID string) (*api.VM, error) {
filePath := constants.IGNITE_SPAWN_VM_FILE_PATH
obj, err := scheme.Serializer.DecodeFile(filePath, true)
if err != nil {
return nil, err
}
vm, ok := obj.(*api.VM)
if !ok {
return nil, fmt.Errorf("object couldn't be converted to VM")
}
// Explicitely set the GVK on this object
vm.SetGroupVersionKind(api.SchemeGroupVersion.WithKind(api.KindVM.Title()))
return vm, nil
}

func StartVM(vm *api.VM) error {
// Setup networking inside of the container, return the available interfaces
dhcpIfaces, err := container.SetupContainerNetworking()
if err != nil {
Expand All @@ -34,61 +50,61 @@ func StartVM(co *options) error {
// Serve DHCP requests for those interfaces
// This function returns the available IP addresses that are being
// served over DHCP now
ipAddrs, err := container.StartDHCPServers(co.vm, dhcpIfaces)
ipAddrs, err := container.StartDHCPServers(vm, dhcpIfaces)
if err != nil {
return err
}

// Serve metrics over an unix socket in the VM's own directory
metricsSocket := path.Join(co.vm.ObjectPath(), constants.PROMETHEUS_SOCKET)
metricsSocket := path.Join(vm.ObjectPath(), constants.PROMETHEUS_SOCKET)
go prometheus.ServeMetrics(metricsSocket)

// Update the VM status and IP address information
if err := patchRunning(co.vm, ipAddrs); err != nil {
if err := patchRunning(vm, ipAddrs); err != nil {
return fmt.Errorf("failed to patch VM state: %v", err)
}

// Patches the VM object to set state to stopped, and clear IP addresses
defer patchStopped(co.vm)
defer patchStopped(vm)

// Remove the snapshot overlay post-run, which also removes the detached backing loop devices
defer dmlegacy.DeactivateSnapshot(co.vm)
defer dmlegacy.DeactivateSnapshot(vm)

// Remove the Prometheus socket post-run
defer os.Remove(metricsSocket)

// Execute Firecracker
if err := container.ExecuteFirecracker(co.vm, dhcpIfaces); err != nil {
return fmt.Errorf("runtime error for VM %q: %v", co.vm.GetUID(), err)
if err := container.ExecuteFirecracker(vm, dhcpIfaces); err != nil {
return fmt.Errorf("runtime error for VM %q: %v", vm.GetUID(), err)
}

return nil
}

func patchRunning(vm *api.VM, ipAddrs []net.IP) error {
patch, err := patchutil.Create(vm, func(obj meta.Object) error {
patchVM := obj.(*api.VM)
return patchVM(vm, func(patchVM *api.VM) error {
patchVM.Status.State = api.VMStateRunning
patchVM.Status.IPAddresses = ipAddrs
return nil
})
if err != nil {
return err
}
// Perform the patch
return providers.Client.VMs().Patch(vm.GetUID(), patch)
}

func patchStopped(vm *api.VM) error {
patch, err := patchutil.Create(vm, func(obj meta.Object) error {
patchVM := obj.(*api.VM)
return patchVM(vm, func(patchVM *api.VM) error {
patchVM.Status.State = api.VMStateStopped
patchVM.Status.IPAddresses = nil
return nil
})
}

func patchVM(vm *api.VM, fn func(*api.VM) error) error {
patch, err := patchutil.Create(vm, func(obj meta.Object) error {
patchVM := obj.(*api.VM)
return fn(patchVM)
})
if err != nil {
return err
}
// Perform the patch
return providers.Client.VMs().Patch(vm.GetUID(), patch)
return patchutil.ApplyOnFile(constants.IGNITE_SPAWN_VM_FILE_PATH, patch, vm.GroupVersionKind())
}
23 changes: 0 additions & 23 deletions cmd/ignite-spawn/options.go

This file was deleted.

4 changes: 2 additions & 2 deletions cmd/ignite-spawn/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ func RunIgniteSpawn() {
}

cmdutil.CheckErr(func() error {
opts, err := NewOptions(fs.Args()[0])
vm, err := decodeVM(fs.Args()[0])
if err != nil {
return err
}

return StartVM(opts)
return StartVM(vm)
}())
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/constants/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ const (

// Prometheus socket filename
PROMETHEUS_SOCKET = "prometheus.sock"

// Where the VM specification is located inside of the container
IGNITE_SPAWN_VM_FILE_PATH = "/vm.json"
)
25 changes: 7 additions & 18 deletions pkg/operations/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package operations

import (
"fmt"
"github.com/weaveworks/ignite/pkg/logs"
"io"
"io/ioutil"
"path"
Expand All @@ -11,14 +10,13 @@ import (

log "github.com/sirupsen/logrus"
api "github.com/weaveworks/ignite/pkg/apis/ignite"
meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1"
"github.com/weaveworks/ignite/pkg/constants"
"github.com/weaveworks/ignite/pkg/dmlegacy"
"github.com/weaveworks/ignite/pkg/logs"
"github.com/weaveworks/ignite/pkg/operations/lookup"
"github.com/weaveworks/ignite/pkg/providers"
"github.com/weaveworks/ignite/pkg/runtime"
"github.com/weaveworks/ignite/pkg/util"
patchutil "github.com/weaveworks/ignite/pkg/util/patch"
"github.com/weaveworks/ignite/pkg/version"
)

Expand Down Expand Up @@ -49,7 +47,7 @@ func StartVM(vm *api.VM, debug bool) error {
}

config := &runtime.ContainerConfig{
Cmd: []string{vm.GetUID().String(), "--log-level", logs.Logger.Level.String()},
Cmd: []string{fmt.Sprintf("--log-level=%s", logs.Logger.Level.String()), vm.GetUID().String()},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call!

Labels: map[string]string{"ignite.name": vm.GetName()},
Binds: []*runtime.Bind{
{
Expand All @@ -60,6 +58,11 @@ func StartVM(vm *api.VM, debug bool) error {
HostPath: kernelDir,
ContainerPath: kernelDir,
},
{
// Mount the metadata.json file specifically into the container, to a well-known place for ignite-spawn to access
HostPath: path.Join(vmDir, constants.METADATA),
ContainerPath: constants.IGNITE_SPAWN_VM_FILE_PATH,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good as well

},
},
CapAdds: []string{
"SYS_ADMIN", // Needed to run "dmsetup remove" inside the container
Expand Down Expand Up @@ -103,20 +106,6 @@ func StartVM(vm *api.VM, debug bool) error {

log.Infof("Started Firecracker VM %q in a container with ID %q", vm.GetUID(), containerID)

// Set an annotation on the VM object with the containerID for now
patch, err := patchutil.Create(vm, func(obj meta.Object) error {
patchVM := obj.(*api.VM)
patchVM.SetAnnotation("v1alpha1.ignite.weave.works.containerID", containerID)
return nil
})
if err != nil {
return err
}
// Perform the patch
if err := providers.Client.VMs().Patch(vm.GetUID(), patch); err != nil {
return err
}

// TODO: Follow-up the container here with a defer, or dedicated goroutine. We should output
// if it started successfully or not
// TODO: This is temporary until we have proper communication to the container
Expand Down
15 changes: 15 additions & 0 deletions pkg/util/patch/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package patch

import (
"fmt"
"io/ioutil"

"github.com/weaveworks/ignite/pkg/apis/ignite/scheme"
meta "github.com/weaveworks/ignite/pkg/apis/meta/v1alpha1"
Expand Down Expand Up @@ -52,3 +53,17 @@ func Apply(original, patch []byte, gvk schema.GroupVersionKind) ([]byte, error)

return strategicpatch.StrategicMergePatch(original, patch, emptyobj)
}

func ApplyOnFile(filePath string, patch []byte, gvk schema.GroupVersionKind) error {
oldContent, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}

newContent, err := Apply(oldContent, patch, gvk)
if err != nil {
return err
}

return ioutil.WriteFile(filePath, newContent, 0644)
}