diff --git a/Makefile b/Makefile index da7f98281..edaa8ae76 100644 --- a/Makefile +++ b/Makefile @@ -14,9 +14,6 @@ GOARCH=amd64 ifneq ($(GOOS),linux) CROSS=-e GOOS=$(GOOS) -e GOARCH=$(GOARCH) endif -ifeq ($(GOOS),darwin) -default: bin/infrakit-instance-hyperkit -endif PREFIX?=/usr/local/ @@ -35,13 +32,6 @@ bin/linuxkit: $(LINUXKIT_DEPS) | bin rm tmp_linuxkit_bin.tar touch $@ -INFRAKIT_DEPS=$(wildcard src/cmd/infrakit-instance-hyperkit/*.go) Makefile vendor.conf -bin/infrakit-instance-hyperkit: $(INFRAKIT_DEPS) | bin - tar cf - vendor -C src/cmd/infrakit-instance-hyperkit . | docker run --rm --net=none --log-driver=none -i $(CROSS) $(GO_COMPILE) --package github.com/linuxkit/linuxkit -o $@ > tmp_infrakit_instance_hyperkit_bin.tar - tar xf tmp_infrakit_instance_hyperkit_bin.tar > $@ - rm tmp_infrakit_instance_hyperkit_bin.tar - touch $@ - test-initrd.img: $(MOBY) test/test.yml $(MOBY) build test/test.yml diff --git a/README.md b/README.md index cdae2d5fe..0fccdc1ea 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,6 @@ to your `PATH` or copy it to somewhere in your `PATH` eg `sudo cp bin/* /usr/loc If you already have `go` installed you can use `go get -u github.com/linuxkit/linuxkit/src/cmd/moby` to install the `moby` build tool, and `go get -u github.com/linuxkit/linuxkit/src/cmd/linuxkit` to install the `linuxkit` tool. -You can use `go get -u github.com/linuxkit/linuxkit/src/cmd/infrakit-instance-hyperkit` -to get the hyperkit infrakit tool. Once you have built the tool, use `moby build linuxkit.yml` to build the example configuration, and `linuxkit run linuxkit` to run locally. Use `halt` to terminate on the console. diff --git a/src/cmd/infrakit-instance-hyperkit/hyperkit.json b/src/cmd/infrakit-instance-hyperkit/hyperkit.json deleted file mode 100644 index ef158bbf1..000000000 --- a/src/cmd/infrakit-instance-hyperkit/hyperkit.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "ID": "cattle", - "Properties": { - "Allocation": { - "Size": 1 - }, - "Instance": { - "Plugin": "instance-hyperkit", - "Properties": { - "_comment" : "kernel+initrd specifies the prefix as in -bzImage and -initrd.img", - "kernel+initrd": "linux", - "Disk" : 512, - "CPUs" : 2, - "Memory" : 1024 - } - }, - "Flavor": { - "Plugin": "flavor-vanilla", - "Properties": { - "Init": [ - "test1", - "test2" - ], - "Tags": { - "tier": "sample", - "project": "infrakit" - } - } - } - } -} diff --git a/src/cmd/infrakit-instance-hyperkit/instance.go b/src/cmd/infrakit-instance-hyperkit/instance.go deleted file mode 100644 index 1ad9cbe5b..000000000 --- a/src/cmd/infrakit-instance-hyperkit/instance.go +++ /dev/null @@ -1,286 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "io/ioutil" - "net" - "os" - "path" - - log "github.com/Sirupsen/logrus" - "github.com/docker/infrakit/pkg/spi/instance" - "github.com/docker/infrakit/pkg/types" - "github.com/moby/hyperkit/go" - "github.com/rneugeba/iso9660wrap" -) - -// NewHyperKitPlugin creates an instance plugin for hyperkit. -func NewHyperKitPlugin(vmDir, hyperkit, vpnkitSock string) instance.Plugin { - return &hyperkitPlugin{VMDir: vmDir, - HyperKit: hyperkit, - VPNKitSock: vpnkitSock, - DiskDir: path.Join(vmDir, "disks"), - } -} - -type hyperkitPlugin struct { - // VMDir is the path to a directory where per VM state is kept - VMDir string - - // Hyperkit is the path to the hyperkit executable - HyperKit string - - // VPNKitSock is the path to the VPNKit Unix domain socket. - VPNKitSock string - - // DiskDir is the path to persistent (across reboots) disk images - DiskDir string -} - -// Validate performs local validation on a provision request. -func (p hyperkitPlugin) Validate(req *types.Any) error { - return nil -} - -// Provision creates a new instance. -func (p hyperkitPlugin) Provision(spec instance.Spec) (*instance.ID, error) { - - var properties map[string]interface{} - - if spec.Properties != nil { - if err := spec.Properties.Decode(&properties); err != nil { - return nil, fmt.Errorf("Invalid instance properties: %s", err) - } - } - - if properties["kernel+initrd"] == nil { - return nil, errors.New("Property 'kernel+initrd' must be set") - } - if properties["CPUs"] == nil { - properties["CPUs"] = 1 - } - if properties["Memory"] == nil { - properties["Memory"] = 512 - } - diskSize := 0 - if properties["Disk"] != nil { - diskSize = int(properties["Disk"].(float64)) - } - - instanceDir, err := ioutil.TempDir(p.VMDir, "infrakit-") - if err != nil { - return nil, err - } - id := instance.ID(path.Base(instanceDir)) - log.Infof("[%s] New instance", id) - - logicalID := string(id) - vpnkitKeyStr := "" - - diskImage := "" - if spec.LogicalID != nil { - logicalID = string(*spec.LogicalID) - // The LogicalID may be a IP address. If so, translate - // it into a magic UUID which cause VPNKit to assign a - // fixed IP address - if ip := net.ParseIP(logicalID); len(ip) > 0 { - vpnkitkey := make([]byte, 16) - vpnkitkey[12] = ip.To4()[0] - vpnkitkey[13] = ip.To4()[1] - vpnkitkey[14] = ip.To4()[2] - vpnkitkey[15] = ip.To4()[3] - vpnkitKeyStr = fmt.Sprintf("%x-%x-%x-%x-%x", vpnkitkey[0:4], vpnkitkey[4:6], vpnkitkey[6:8], vpnkitkey[8:10], vpnkitkey[10:]) - } - // If a LogicalID is supplied and the Disk size is - // non-zero, we place the disk in a special directory - // so it persists across reboots. - if diskSize != 0 { - diskImage = path.Join(p.DiskDir, logicalID+".img") - } - } - - isoImage := "" - if spec.Init != "" { - isoImage = path.Join(instanceDir, "data.iso") - outfh, err := os.OpenFile(isoImage, os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Fatalf("Cannot create user data ISO: %s", err) - } - err = iso9660wrap.WriteBuffer(outfh, []byte(spec.Init), "config") - if err != nil { - log.Fatalf("Cannot write user data ISO: %s", err) - } - outfh.Close() - } - - log.Infof("[%s] LogicalID: %s", id, logicalID) - log.Debugf("[%s] VPNKitKey: %s", id, vpnkitKeyStr) - - // Start a HyperKit instance - h, err := hyperkit.New(p.HyperKit, p.VPNKitSock, instanceDir) - if err != nil { - return nil, err - } - h.Kernel = properties["kernel+initrd"].(string) + "-bzImage" - h.Initrd = properties["kernel+initrd"].(string) + "-initrd.img" - h.VPNKitKey = vpnkitKeyStr - h.DiskImage = diskImage - h.ISOImage = isoImage - h.CPUs = int(properties["CPUs"].(float64)) - h.Memory = int(properties["Memory"].(float64)) - h.DiskSize = diskSize - h.Console = hyperkit.ConsoleFile - log.Infof("[%s] Booting: %s/%s", id, h.Kernel, h.Initrd) - log.Infof("[%s] %d CPUs, %dMB Memory, %dMB Disk (%s)", id, h.CPUs, h.Memory, h.DiskSize, h.DiskImage) - - err = h.Start("console=ttyS0") - if err != nil { - return nil, err - } - log.Infof("[%s] Started", id) - - if err := ioutil.WriteFile(path.Join(instanceDir, "logical.id"), []byte(logicalID), 0644); err != nil { - return nil, err - } - - tagData, err := types.AnyValue(spec.Tags) - if err != nil { - return nil, err - } - - log.Debugf("[%s] tags: %s", id, tagData) - if err := ioutil.WriteFile(path.Join(instanceDir, "tags"), tagData.Bytes(), 0644); err != nil { - return nil, err - } - - return &id, nil -} - -// Label labels the instance -func (p hyperkitPlugin) Label(instance instance.ID, labels map[string]string) error { - instanceDir := path.Join(p.VMDir, string(instance)) - tagFile := path.Join(instanceDir, "tags") - buff, err := ioutil.ReadFile(tagFile) - if err != nil { - return err - } - - tags := map[string]string{} - err = types.AnyBytes(buff).Decode(&tags) - if err != nil { - return err - } - - for k, v := range labels { - tags[k] = v - } - - encoded, err := types.AnyValue(tags) - if err != nil { - return err - } - return ioutil.WriteFile(tagFile, encoded.Bytes(), 0644) -} - -// Destroy terminates an existing instance. -func (p hyperkitPlugin) Destroy(id instance.ID) error { - log.Info("Destroying VM: ", id) - - instanceDir := path.Join(p.VMDir, string(id)) - _, err := os.Stat(instanceDir) - if err != nil { - if os.IsNotExist(err) { - return errors.New("Instance does not exist") - } - } - - h, err := hyperkit.FromState(instanceDir) - if err != nil { - return err - } - err = h.Stop() - if err != nil { - return err - } - err = h.Remove(false) - if err != nil { - return err - } - return nil -} - -// DescribeInstances returns descriptions of all instances matching all of the provided tags. -func (p hyperkitPlugin) DescribeInstances(tags map[string]string, properties bool) ([]instance.Description, error) { - files, err := ioutil.ReadDir(p.VMDir) - if err != nil { - return nil, err - } - - descriptions := []instance.Description{} - - for _, file := range files { - if !file.IsDir() { - continue - } - - instanceDir := path.Join(p.VMDir, file.Name()) - - tagData, err := ioutil.ReadFile(path.Join(instanceDir, "tags")) - if err != nil { - if os.IsNotExist(err) { - continue - } - - return nil, err - } - - instanceTags := map[string]string{} - if err := types.AnyBytes(tagData).Decode(&instanceTags); err != nil { - return nil, err - } - - allMatched := true - for k, v := range tags { - value, exists := instanceTags[k] - if !exists || v != value { - allMatched = false - break - } - } - - if allMatched { - var logicalID *instance.LogicalID - id := instance.ID(file.Name()) - - h, err := hyperkit.FromState(instanceDir) - if err != nil { - log.Warningln("Could not get instance data. Id: ", id) - p.Destroy(id) - continue - } - if !h.IsRunning() { - log.Warningln("Instance is not running. Id: ", id) - p.Destroy(id) - continue - } - - lidData, err := ioutil.ReadFile(path.Join(instanceDir, "logical.id")) - if err != nil { - log.Warningln("Could not get logical ID. Id: ", id) - p.Destroy(id) - continue - } - lid := instance.LogicalID(lidData) - logicalID = &lid - - descriptions = append(descriptions, instance.Description{ - ID: id, - LogicalID: logicalID, - Tags: instanceTags, - }) - } - } - - return descriptions, nil -} diff --git a/src/cmd/infrakit-instance-hyperkit/main.go b/src/cmd/infrakit-instance-hyperkit/main.go deleted file mode 100644 index 7a25ea7bb..000000000 --- a/src/cmd/infrakit-instance-hyperkit/main.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "os/user" - "path/filepath" - - log "github.com/Sirupsen/logrus" - "github.com/spf13/cobra" - - "github.com/docker/infrakit/pkg/cli" - "github.com/docker/infrakit/pkg/plugin/metadata" - instance_plugin "github.com/docker/infrakit/pkg/rpc/instance" - metadata_plugin "github.com/docker/infrakit/pkg/rpc/metadata" - instance_spi "github.com/docker/infrakit/pkg/spi/instance" -) - -var ( - // Version is the build release identifier. - Version = "Unspecified" - - // Revision is the build source control revision. - Revision = "Unspecified" -) - -func main() { - - cmd := &cobra.Command{ - Use: os.Args[0], - Short: "HyperKit instance plugin", - } - - defaultVMDir := filepath.Join(getHome(), ".infrakit/hyperkit-vms") - - name := cmd.Flags().String("name", "instance-hyperkit", "Plugin name to advertise for discovery") - logLevel := cmd.Flags().Int("log", cli.DefaultLogLevel, "Logging level. 0 is least verbose. Max is 5") - - vmDir := cmd.Flags().String("vm-dir", defaultVMDir, "Directory where to store VM state") - hyperkit := cmd.Flags().String("hyperkit", "", "Path to HyperKit executable") - - vpnkitSock := cmd.Flags().String("vpnkit-sock", "auto", "Path to VPNKit UNIX domain socket") - - cmd.RunE = func(c *cobra.Command, args []string) error { - os.MkdirAll(*vmDir, os.ModePerm) - - cli.SetLogLevel(*logLevel) - cli.RunPlugin(*name, - instance_plugin.PluginServer(NewHyperKitPlugin(*vmDir, *hyperkit, *vpnkitSock)), - metadata_plugin.PluginServer(metadata.NewPluginFromData( - map[string]interface{}{ - "version": Version, - "revision": Revision, - "implements": instance_spi.InterfaceSpec, - }, - )), - ) - return nil - } - - cmd.AddCommand(&cobra.Command{ - Use: "version", - Short: "print build version information", - RunE: func(cmd *cobra.Command, args []string) error { - buff, err := json.MarshalIndent(map[string]interface{}{ - "version": Version, - "revision": Revision, - }, " ", " ") - if err != nil { - return err - } - fmt.Println(string(buff)) - return nil - }, - }) - - if err := cmd.Execute(); err != nil { - log.Error(err) - os.Exit(1) - } -} - -func getHome() string { - if usr, err := user.Current(); err == nil { - return usr.HomeDir - } - return os.Getenv("HOME") -}