Exemple #1
0
func (s *HardwareSuite) TestParseHardware(c *gc.C) {
	for i, t := range parseHardwareTests {
		c.Logf("test %d: %s", i, t.summary)
		hwc, err := instance.ParseHardware(t.args...)
		if t.err == "" {
			c.Assert(err, gc.IsNil)
		} else {
			c.Assert(err, gc.ErrorMatches, t.err)
			continue
		}
		cons1, err := instance.ParseHardware(hwc.String())
		c.Assert(err, gc.IsNil)
		c.Assert(cons1, gc.DeepEquals, hwc)
	}
}
Exemple #2
0
// FormatMachineTabular returns a tabular summary of machine
func FormatMachineTabular(value interface{}) ([]byte, error) {
	fs, valueConverted := value.(formattedMachineStatus)
	if !valueConverted {
		return nil, errors.Errorf("expected value of type %T, got %T", fs, value)
	}
	var out bytes.Buffer
	// To format things into columns.
	tw := tabwriter.NewWriter(&out, 0, 1, 1, ' ', 0)
	p := func(values ...interface{}) {
		for _, v := range values {
			fmt.Fprintf(tw, "%s\t", v)
		}
		fmt.Fprintln(tw)
	}

	p("\n[Machines]")
	p("ID\tSTATE\tDNS\tINS-ID\tSERIES\tAZ")
	for _, name := range common.SortStringsNaturally(stringKeysFromMap(fs.Machines)) {
		m := fs.Machines[name]
		// We want to display availability zone so extract from hardware info".
		hw, err := instance.ParseHardware(m.Hardware)
		if err != nil {
			logger.Warningf("invalid hardware info %s for machine %v", m.Hardware, m)
		}
		az := ""
		if hw.AvailabilityZone != nil {
			az = *hw.AvailabilityZone
		}
		p(m.Id, m.AgentState, m.DNSName, m.InstanceId, m.Series, az)
	}
	tw.Flush()

	return out.Bytes(), nil
}
Exemple #3
0
func (manager *containerManager) CreateContainer(
	machineConfig *cloudinit.MachineConfig,
	series string,
	network *container.NetworkConfig,
) (instance.Instance, *instance.HardwareCharacteristics, error) {

	name := names.NewMachineTag(machineConfig.MachineId).String()
	if manager.name != "" {
		name = fmt.Sprintf("%s-%s", manager.name, name)
	}
	// Note here that the kvmObjectFacotry only returns a valid container
	// object, and doesn't actually construct the underlying kvm container on
	// disk.
	kvmContainer := KvmObjectFactory.New(name)

	// Create the cloud-init.
	directory, err := container.NewDirectory(name)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create container directory: %v", err)
	}
	logger.Tracef("write cloud-init")
	userDataFilename, err := container.WriteUserData(machineConfig, directory)
	if err != nil {
		return nil, nil, errors.LoggedErrorf(logger, "failed to write user data: %v", err)
	}
	// Create the container.
	startParams = ParseConstraintsToStartParams(machineConfig.Constraints)
	startParams.Arch = version.Current.Arch
	startParams.Series = series
	startParams.Network = network
	startParams.UserDataFile = userDataFilename

	// If the Simplestream requested is anything but released, update
	// our StartParams to request it.
	if machineConfig.ImageStream != imagemetadata.ReleasedStream {
		startParams.ImageDownloadUrl = imagemetadata.UbuntuCloudImagesURL + "/" + machineConfig.ImageStream
	}

	var hardware instance.HardwareCharacteristics
	hardware, err = instance.ParseHardware(
		fmt.Sprintf("arch=%s mem=%vM root-disk=%vG cpu-cores=%v",
			startParams.Arch, startParams.Memory, startParams.RootDisk, startParams.CpuCores))
	if err != nil {
		logger.Warningf("failed to parse hardware: %v", err)
	}

	logger.Tracef("create the container, constraints: %v", machineConfig.Constraints)
	if err := kvmContainer.Start(startParams); err != nil {
		return nil, nil, errors.LoggedErrorf(logger, "kvm container creation failed: %v", err)
	}
	logger.Tracef("kvm container created")
	return &kvmInstance{kvmContainer, name}, &hardware, nil
}
Exemple #4
0
func (ts *parseHardwareTestSpec) check(c *gc.C) {
	hwc, err := instance.ParseHardware(ts.args...)

	// Check the spec'ed error condition first.
	if ts.err != "" {
		c.Check(err, gc.ErrorMatches, ts.err)
		// We expected an error so we don't worry about checking hwc.
		return
	} else if !c.Check(err, jc.ErrorIsNil) {
		// We got an unexpected error so we don't worry about checking hwc.
		return
	}

	// The error condition matched so we check hwc.
	cons1, err := instance.ParseHardware(hwc.String())
	if !c.Check(err, jc.ErrorIsNil) {
		// Parsing didn't work so we don't worry about checking hwc.
		return
	}

	// Compare the round-tripped HWC.
	c.Check(cons1, gc.DeepEquals, hwc)
}
Exemple #5
0
func printMachine(w output.Wrapper, m machineStatus) {
	// We want to display availability zone so extract from hardware info".
	hw, err := instance.ParseHardware(m.Hardware)
	if err != nil {
		logger.Warningf("invalid hardware info %s for machine %v", m.Hardware, m)
	}
	az := ""
	if hw.AvailabilityZone != nil {
		az = *hw.AvailabilityZone
	}
	w.Print(m.Id)
	w.PrintStatus(m.JujuStatus.Current)
	w.Println(m.DNSName, m.InstanceId, m.Series, az)
	for _, name := range utils.SortStringsNaturally(stringKeysFromMap(m.Containers)) {
		printMachine(w, m.Containers[name])
	}
}
Exemple #6
0
// getHardwareCharacteristics compiles hardware-related details about
// the given instance and relative to the provided spec and returns it.
func (env *environ) getHardwareCharacteristics(args environs.StartInstanceParams, inst *environInstance) *instance.HardwareCharacteristics {
	raw := inst.raw.Hardware

	archStr := raw.Architecture
	if archStr == "unknown" || !arch.IsSupportedArch(archStr) {
		// TODO(ericsnow) This special-case should be improved.
		archStr = arch.HostArch()
	}

	hwc, err := instance.ParseHardware(
		"arch="+archStr,
		fmt.Sprintf("cpu-cores=%d", raw.NumCores),
		fmt.Sprintf("mem=%dM", raw.MemoryMB),
		//"root-disk=",
		//"tags=",
	)
	if err != nil {
		logger.Errorf("unexpected problem parsing hardware info: %v", err)
		// Keep moving...
	}
	return &hwc
}
Exemple #7
0
// FormatTabular returns a tabular summary of machines, services, and
// units. Any subordinate items are indented by two spaces beneath
// their superior.
func FormatTabular(value interface{}) ([]byte, error) {
	fs, valueConverted := value.(formattedStatus)
	if !valueConverted {
		return nil, errors.Errorf("expected value of type %T, got %T", fs, value)
	}
	var out bytes.Buffer
	// To format things into columns.
	tw := tabwriter.NewWriter(&out, 0, 1, 1, ' ', 0)
	p := func(values ...interface{}) {
		for _, v := range values {
			fmt.Fprintf(tw, "%s\t", v)
		}
		fmt.Fprintln(tw)
	}

	if envStatus := fs.ModelStatus; envStatus != nil {
		p("[Model]")
		if envStatus.AvailableVersion != "" {
			p("UPGRADE-AVAILABLE")
			p(envStatus.AvailableVersion)
		}
		p()
		tw.Flush()
	}

	units := make(map[string]unitStatus)
	relations := newRelationFormatter()
	p("[Services]")
	p("NAME\tSTATUS\tEXPOSED\tCHARM")
	for _, svcName := range common.SortStringsNaturally(stringKeysFromMap(fs.Services)) {
		svc := fs.Services[svcName]
		for un, u := range svc.Units {
			units[un] = u
		}

		subs := set.NewStrings(svc.SubordinateTo...)
		p(svcName, svc.StatusInfo.Current, fmt.Sprintf("%t", svc.Exposed), svc.Charm)
		for relType, relatedUnits := range svc.Relations {
			for _, related := range relatedUnits {
				relations.add(related, svcName, relType, subs.Contains(related))
			}
		}

	}
	if relations.len() > 0 {
		p()
		p("[Relations]")
		p("SERVICE1\tSERVICE2\tRELATION\tTYPE")
		for _, k := range relations.sorted() {
			r := relations.get(k)
			if r != nil {
				p(r.service1, r.service2, r.relation, r.relationType())
			}
		}
	}
	tw.Flush()

	pUnit := func(name string, u unitStatus, level int) {
		message := u.WorkloadStatusInfo.Message
		agentDoing := agentDoing(u.AgentStatusInfo)
		if agentDoing != "" {
			message = fmt.Sprintf("(%s) %s", agentDoing, message)
		}
		p(
			indent("", level*2, name),
			u.WorkloadStatusInfo.Current,
			u.AgentStatusInfo.Current,
			u.AgentStatusInfo.Version,
			u.Machine,
			strings.Join(u.OpenedPorts, ","),
			u.PublicAddress,
			message,
		)
	}

	header := []string{"ID", "WORKLOAD-STATE", "AGENT-STATE", "VERSION", "MACHINE", "PORTS", "PUBLIC-ADDRESS", "MESSAGE"}

	p("\n[Units]")
	p(strings.Join(header, "\t"))
	for _, name := range common.SortStringsNaturally(stringKeysFromMap(units)) {
		u := units[name]
		pUnit(name, u, 0)
		const indentationLevel = 1
		recurseUnits(u, indentationLevel, pUnit)
	}
	tw.Flush()

	p("\n[Machines]")
	p("ID\tSTATE\tDNS\tINS-ID\tSERIES\tAZ")
	for _, name := range common.SortStringsNaturally(stringKeysFromMap(fs.Machines)) {
		m := fs.Machines[name]
		// We want to display availability zone so extract from hardware info".
		hw, err := instance.ParseHardware(m.Hardware)
		if err != nil {
			logger.Warningf("invalid hardware info %s for machine %v", m.Hardware, m)
		}
		az := ""
		if hw.AvailabilityZone != nil {
			az = *hw.AvailabilityZone
		}
		p(m.Id, m.AgentState, m.DNSName, m.InstanceId, m.Series, az)
	}
	tw.Flush()

	return out.Bytes(), nil
}
Exemple #8
0
func (manager *containerManager) CreateContainer(
	instanceConfig *instancecfg.InstanceConfig,
	cons constraints.Value,
	series string,
	networkConfig *container.NetworkConfig,
	storageConfig *container.StorageConfig,
	callback container.StatusCallback,
) (_ instance.Instance, _ *instance.HardwareCharacteristics, err error) {

	name, err := manager.namespace.Hostname(instanceConfig.MachineId)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}

	defer func() {
		if err != nil {
			callback(status.ProvisioningError, fmt.Sprintf("Creating container: %v", err), nil)
		}
	}()

	// Set the MachineContainerHostname to match the name returned by virsh list
	instanceConfig.MachineContainerHostname = name

	// Note here that the kvmObjectFactory only returns a valid container
	// object, and doesn't actually construct the underlying kvm container on
	// disk.
	kvmContainer := KvmObjectFactory.New(name)

	// Create the cloud-init.
	directory, err := container.NewDirectory(name)
	if err != nil {
		return nil, nil, errors.Annotate(err, "failed to create container directory")
	}
	logger.Tracef("write cloud-init")
	userDataFilename, err := containerinit.WriteUserData(instanceConfig, networkConfig, directory)
	if err != nil {
		logger.Infof("machine config api %#v", *instanceConfig.APIInfo)
		err = errors.Annotate(err, "failed to write user data")
		logger.Infof(err.Error())
		return nil, nil, err
	}
	// Create the container.
	startParams = ParseConstraintsToStartParams(cons)
	startParams.Arch = arch.HostArch()
	startParams.Series = series
	startParams.Network = networkConfig
	startParams.UserDataFile = userDataFilename

	// If the Simplestream requested is anything but released, update
	// our StartParams to request it.
	if instanceConfig.ImageStream != imagemetadata.ReleasedStream {
		startParams.ImageDownloadUrl = imagemetadata.UbuntuCloudImagesURL + "/" + instanceConfig.ImageStream
	}

	var hardware instance.HardwareCharacteristics
	hardware, err = instance.ParseHardware(
		fmt.Sprintf("arch=%s mem=%vM root-disk=%vG cores=%v",
			startParams.Arch, startParams.Memory, startParams.RootDisk, startParams.CpuCores))
	if err != nil {
		return nil, nil, errors.Annotate(err, "failed to parse hardware")
	}

	callback(status.Allocating, "Creating container; it might take some time", nil)
	logger.Tracef("create the container, constraints: %v", cons)
	if err := kvmContainer.Start(startParams); err != nil {
		err = errors.Annotate(err, "kvm container creation failed")
		logger.Infof(err.Error())
		return nil, nil, err
	}
	logger.Tracef("kvm container created")
	return &kvmInstance{kvmContainer, name}, &hardware, nil
}