func CreateStemcell(c config.Cpi, extInput bosh.MethodArguments) (string, error) {
	var imagePath string

	if reflect.TypeOf(extInput[0]) == reflect.TypeOf(imagePath) {
		imagePath = extInput[0].(string)
	} else {
		return "", errors.New("received unexpected type for stemcell image path")
	}

	stemcellFile, err := os.Open(imagePath)
	if err != nil {
		return "", fmt.Errorf("error obtaining stemcell file handle %s", err)
	}

	defer stemcellFile.Close()

	fileInfo, err := stemcellFile.Stat()
	if err != nil {
		return "", fmt.Errorf("error getting file's stats: %s", err)
	}

	uuid, err := uuid.NewV4()
	if err != nil {
		return "", fmt.Errorf("error generating UUID: %s", err)
	}

	_, err = rackhdapi.UploadFile(c, uuid.String(), stemcellFile, fileInfo.Size())
	if err != nil {
		return "", err
	}
	log.Debug(fmt.Sprintf("uploaded stemcell: %s to server", uuid.String()))

	return uuid.String(), nil
}
func CreateVM(c config.Cpi, extInput bosh.MethodArguments) (string, error) {
	agentID, stemcellCID, publicKey, boshNetworks, nodeID, err := parseCreateVMInput(extInput)
	if err != nil {
		return "", err
	}

	nodeID, err = TryReservation(c, nodeID, SelectNodeFromRackHD, ReserveNodeFromRackHD)
	if err != nil {
		return "", err
	}

	var netSpec bosh.Network
	var netName string
	for k, v := range boshNetworks {
		netName = k
		netSpec = v
	}

	nodeCatalog, err := rackhdapi.GetNodeCatalog(c, nodeID)
	if err != nil {
		return "", err
	}

	if netSpec.NetworkType == bosh.ManualNetworkType {
		netSpec, err = attachMAC(nodeCatalog.Data.NetworkData.Networks, netSpec)
		if err != nil {
			return "", err
		}
	}

	node, err := rackhdapi.GetNode(c, nodeID)
	if err != nil {
		return "", err
	}

	var diskCID string
	if node.PersistentDisk.DiskCID == "" {
		diskCID = fmt.Sprintf("%s-%s", nodeID, c.RequestID)

		container := rackhdapi.PersistentDiskSettingsContainer{
			PersistentDisk: rackhdapi.PersistentDiskSettings{
				PregeneratedDiskCID: diskCID,
			},
		}

		bodyBytes, err := json.Marshal(container)
		if err != nil {
			return "", fmt.Errorf("error marshalling persistent disk information for agent %s", agentID)
		}

		err = rackhdapi.PatchNode(c, node.ID, bodyBytes)
		if err != nil {
			return "", err
		}
	} else {
		diskCID = node.PersistentDisk.DiskCID
	}

	persistentMetadata := map[string]interface{}{}
	if _, sdbFound := nodeCatalog.Data.BlockDevices["sdb"]; sdbFound {
		persistentMetadata = map[string]interface{}{
			diskCID: map[string]string{
				"path": "/dev/sdb",
			},
		}
	}

	env := bosh.AgentEnv{
		AgentID:   agentID,
		Blobstore: c.Agent.Blobstore,
		Disks: map[string]interface{}{
			"system":     "/dev/sda",
			"persistent": persistentMetadata,
		},
		Mbus:     c.Agent.Mbus,
		Networks: map[string]bosh.Network{netName: netSpec},
		NTP:      c.Agent.Ntp,
		VM: map[string]string{
			"id":   nodeID,
			"name": nodeID,
		},
		PublicKey: publicKey,
	}

	envBytes, err := json.Marshal(env)
	if err != nil {
		return "", fmt.Errorf("error marshalling agent env %s", err)
	}
	envReader := bytes.NewReader(envBytes)
	vmCID, err := rackhdapi.UploadFile(c, nodeID, envReader, int64(len(envBytes)))
	if err != nil {
		return "", err
	}
	defer rackhdapi.DeleteFile(c, nodeID)

	workflowName, err := workflows.PublishProvisionNodeWorkflow(c)
	if err != nil {
		return "", fmt.Errorf("error publishing provision workflow: %s", err)
	}

	wipeDisk := (nodeID == "")

	err = workflows.RunProvisionNodeWorkflow(c, nodeID, workflowName, vmCID, stemcellCID, wipeDisk)
	if err != nil {
		return "", fmt.Errorf("error running provision workflow: %s", err)
	}

	return vmCID, nil
}
Exemplo n.º 3
0
			apiServerIP := fmt.Sprintf("%s:8080", os.Getenv("RACKHD_API_URI"))
			Expect(apiServerIP).ToNot(BeEmpty())
			c := config.Cpi{ApiServer: apiServerIP}
			dummyStr := "Some ice cold file"
			dummyFile := strings.NewReader(dummyStr)

			uuid, err := uuid.NewV4()
			Expect(err).ToNot(HaveOccurred())
			baseName := uuid.String()

			url := fmt.Sprintf("http://%s/api/common/files/metadata/%s", c.ApiServer, baseName)
			resp, err := http.Get(url)
			Expect(err).ToNot(HaveOccurred())
			Expect(resp.StatusCode).To(Equal(404))

			rackhdUUID, err := rackhdapi.UploadFile(c, baseName, dummyFile, int64(len(dummyStr)))
			Expect(err).ToNot(HaveOccurred())
			Expect(rackhdUUID).ToNot(BeEmpty())

			getResp, err := http.Get(url)
			Expect(err).ToNot(HaveOccurred())

			respBytes, err := ioutil.ReadAll(getResp.Body)
			Expect(err).ToNot(HaveOccurred())

			defer getResp.Body.Close()
			Expect(getResp.StatusCode).To(Equal(200))

			fileMetadataResp := rackhdapi.FileMetadataResponse{}
			err = json.Unmarshal(respBytes, &fileMetadataResp)
			Expect(err).ToNot(HaveOccurred())