<commit_before>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path"

	log "github.com/Sirupsen/logrus"

	"github.com/docker/hyperkit/go"

	"github.com/docker/infrakit/pkg/spi/instance"
	"github.com/docker/infrakit/pkg/types"
)

// 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["Moby"] == nil {
		return nil, errors.New("Property 'Moby' 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)
	uuidStr := ""

	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 {
			uuid := make([]byte, 16)
			uuid[12] = ip.To4()[0]
			uuid[13] = ip.To4()[1]
			uuid[14] = ip.To4()[2]
			uuid[15] = ip.To4()[3]
			uuidStr = fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[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")
			// Make sure the directory exists
			err = os.MkdirAll(p.DiskDir, 0755)
			if err != nil {
				return nil, err
			}
		}
	}
	log.Infof("[%s] LogicalID: %s", id, logicalID)
	log.Debugf("[%s] UUID: %s", id, uuidStr)

	// Start a HyperKit instance
	h, err := hyperkit.New(p.HyperKit, instanceDir, p.VPNKitSock, diskImage)
	if err != nil {
		return nil, err
	}
	h.Kernel = properties["Moby"].(string) + "-bzImage"
	h.Initrd = properties["Moby"].(string) + "-initrd.img"
	h.CPUs = int(properties["CPUs"].(float64))
	h.Memory = int(properties["Memory"].(float64))
	h.DiskSize = diskSize
	h.UUID = uuidStr
	h.UserData = spec.Init
	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)<commit_msg>infrakit: Adjust hyperkit instance plugin to new API<commit_after>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/hyperkit/go"
	"github.com/docker/infrakit/pkg/spi/instance"
	"github.com/docker/infrakit/pkg/types"
	"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["Moby"] == nil {
		return nil, errors.New("Property 'Moby' 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)
	uuidStr := ""

	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 {
			uuid := make([]byte, 16)
			uuid[12] = ip.To4()[0]
			uuid[13] = ip.To4()[1]
			uuid[14] = ip.To4()[2]
			uuid[15] = ip.To4()[3]
			uuidStr = fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[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] UUID: %s", id, uuidStr)

	// Start a HyperKit instance
	h, err := hyperkit.New(p.HyperKit, p.VPNKitSock, instanceDir)
	if err != nil {
		return nil, err
	}
	h.Kernel = properties["Moby"].(string) + "-bzImage"
	h.Initrd = properties["Moby"].(string) + "-initrd.img"
	h.UUID = uuidStr
	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)
{'fraction_non_alphanumeric': 0.15831715210355987, 'fraction_numerical': 0.01423948220064725, 'mean_word_length': 3.780940594059406, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2004189', 'n_tokens_mistral': 3108, 'n_tokens_neox': 2884, 'n_words': 762}