Exemplo n.º 1
0
func (c *statusHistoryCommand) Run(ctx *cmd.Context) error {
	apiclient, err := c.NewAPIClient()
	if err != nil {
		return fmt.Errorf(connectionError, c.ConnectionName(), err)
	}
	defer apiclient.Close()
	var statuses *params.UnitStatusHistory
	kind := params.HistoryKind(c.outputContent)
	statuses, err = apiclient.UnitStatusHistory(kind, c.unitName, c.backlogSize)
	if err != nil {
		if len(statuses.Statuses) == 0 {
			return errors.Trace(err)
		}
		// Display any error, but continue to print status if some was returned
		fmt.Fprintf(ctx.Stderr, "%v\n", err)
	} else if len(statuses.Statuses) == 0 {
		return errors.Errorf("no status history available")
	}
	table := [][]string{{"TIME", "TYPE", "STATUS", "MESSAGE"}}
	lengths := []int{1, 1, 1, 1}
	for _, v := range statuses.Statuses {
		fields := []string{common.FormatTime(v.Since, c.isoTime), string(v.Kind), string(v.Status), v.Info}
		for k, v := range fields {
			if len(v) > lengths[k] {
				lengths[k] = len(v)
			}
		}
		table = append(table, fields)
	}
	f := fmt.Sprintf("%%-%ds\t%%-%ds\t%%-%ds\t%%-%ds\n", lengths[0], lengths[1], lengths[2], lengths[3])
	for _, v := range table {
		fmt.Printf(f, v[0], v[1], v[2], v[3])
	}
	return nil
}
Exemplo n.º 2
0
func createFilesystemInfo(result params.FilesystemDetailsResult) (names.FilesystemTag, FilesystemInfo, error) {
	details := result.Result

	filesystemTag, err := names.ParseFilesystemTag(details.FilesystemTag)
	if err != nil {
		return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err)
	}

	var info FilesystemInfo
	info.ProviderFilesystemId = details.Info.FilesystemId
	info.Size = details.Info.Size
	info.Status = EntityStatus{
		details.Status.Status,
		details.Status.Info,
		// TODO(axw) we should support formatting as ISO time
		common.FormatTime(details.Status.Since, false),
	}

	if details.VolumeTag != "" {
		volumeId, err := idFromTag(details.VolumeTag)
		if err != nil {
			return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err)
		}
		info.Volume = volumeId
	}

	if len(details.MachineAttachments) > 0 {
		machineAttachments := make(map[string]MachineFilesystemAttachment)
		for machineTag, attachment := range details.MachineAttachments {
			machineId, err := idFromTag(machineTag)
			if err != nil {
				return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err)
			}
			machineAttachments[machineId] = MachineFilesystemAttachment{
				attachment.MountPoint,
				attachment.ReadOnly,
			}
		}
		info.Attachments = &FilesystemAttachments{
			Machines: machineAttachments,
		}
	}

	if details.Storage != nil {
		storageTag, storageInfo, err := createStorageInfo(*details.Storage)
		if err != nil {
			return names.FilesystemTag{}, FilesystemInfo{}, errors.Trace(err)
		}
		info.Storage = storageTag.Id()
		if storageInfo.Attachments != nil {
			info.Attachments.Units = storageInfo.Attachments.Units
		}
	}

	return filesystemTag, info, nil
}
Exemplo n.º 3
0
func createVolumeInfo(result params.VolumeDetailsResult) (names.VolumeTag, VolumeInfo, error) {
	details := result.Details
	if details == nil {
		details = volumeDetailsFromLegacy(result)
	}

	volumeTag, err := names.ParseVolumeTag(details.VolumeTag)
	if err != nil {
		return names.VolumeTag{}, VolumeInfo{}, errors.Trace(err)
	}

	var info VolumeInfo
	info.ProviderVolumeId = details.Info.VolumeId
	info.HardwareId = details.Info.HardwareId
	info.Size = details.Info.Size
	info.Persistent = details.Info.Persistent
	info.Status = EntityStatus{
		details.Status.Status,
		details.Status.Info,
		// TODO(axw) we should support formatting as ISO time
		common.FormatTime(details.Status.Since, false),
	}

	if len(details.MachineAttachments) > 0 {
		machineAttachments := make(map[string]MachineVolumeAttachment)
		for machineTag, attachment := range details.MachineAttachments {
			machineId, err := idFromTag(machineTag)
			if err != nil {
				return names.VolumeTag{}, VolumeInfo{}, errors.Trace(err)
			}
			machineAttachments[machineId] = MachineVolumeAttachment{
				attachment.DeviceName,
				attachment.DeviceLink,
				attachment.BusAddress,
				attachment.ReadOnly,
			}
		}
		info.Attachments = &VolumeAttachments{
			Machines: machineAttachments,
		}
	}

	if details.Storage != nil {
		storageTag, storageInfo, err := createStorageInfo(*details.Storage)
		if err != nil {
			return names.VolumeTag{}, VolumeInfo{}, errors.Trace(err)
		}
		info.Storage = storageTag.Id()
		if storageInfo.Attachments != nil {
			info.Attachments.Units = storageInfo.Attachments.Units
		}
	}

	return volumeTag, info, nil
}
Exemplo n.º 4
0
func (sf *statusFormatter) getAgentStatusInfo(unit params.UnitStatus) statusInfoContents {
	info := statusInfoContents{
		Err:     unit.UnitAgent.Err,
		Current: unit.UnitAgent.Status,
		Message: unit.UnitAgent.Info,
		Version: unit.UnitAgent.Version,
	}
	if unit.UnitAgent.Since != nil {
		info.Since = common.FormatTime(unit.UnitAgent.Since, sf.isoTime)
	}
	return info
}
Exemplo n.º 5
0
func (sf *statusFormatter) getServiceStatusInfo(service params.ServiceStatus) statusInfoContents {
	info := statusInfoContents{
		Err:     service.Status.Err,
		Current: service.Status.Status,
		Message: service.Status.Info,
		Version: service.Status.Version,
	}
	if service.Status.Since != nil {
		info.Since = common.FormatTime(service.Status.Since, sf.isoTime)
	}
	return info
}
Exemplo n.º 6
0
func (sf *statusFormatter) getStatusInfoContents(inst params.DetailedStatus) statusInfoContents {
	info := statusInfoContents{
		Err:     inst.Err,
		Current: inst.Status,
		Message: inst.Info,
		Version: inst.Version,
		Life:    inst.Life,
	}
	if inst.Since != nil {
		info.Since = common.FormatTime(inst.Since, sf.isoTime)
	}
	return info
}
Exemplo n.º 7
0
func (sf *statusFormatter) getAgentStatusInfo(unit params.UnitStatus) statusInfoContents {
	// TODO(perrito66) add status validation.
	info := statusInfoContents{
		Err:     unit.AgentStatus.Err,
		Current: status.Status(unit.AgentStatus.Status),
		Message: unit.AgentStatus.Info,
		Version: unit.AgentStatus.Version,
	}
	if unit.AgentStatus.Since != nil {
		info.Since = common.FormatTime(unit.AgentStatus.Since, sf.isoTime)
	}
	return info
}
Exemplo n.º 8
0
func (sf *statusFormatter) getServiceStatusInfo(service params.ApplicationStatus) statusInfoContents {
	// TODO(perrito66) add status validation.
	info := statusInfoContents{
		Err:     service.Status.Err,
		Current: status.Status(service.Status.Status),
		Message: service.Status.Info,
		Version: service.Status.Version,
	}
	if service.Status.Since != nil {
		info.Since = common.FormatTime(service.Status.Since, sf.isoTime)
	}
	return info
}
Exemplo n.º 9
0
func createStorageInfo(details params.StorageDetails) (names.StorageTag, StorageInfo, error) {
	storageTag, err := names.ParseStorageTag(details.StorageTag)
	if err != nil {
		return names.StorageTag{}, StorageInfo{}, errors.Trace(err)
	}

	info := StorageInfo{
		Kind: details.Kind.String(),
		Status: EntityStatus{
			details.Status.Status,
			details.Status.Info,
			// TODO(axw) we should support formatting as ISO time
			common.FormatTime(details.Status.Since, false),
		},
		Persistent: details.Persistent,
	}

	if len(details.Attachments) > 0 {
		unitStorageAttachments := make(map[string]UnitStorageAttachment)
		for unitTagString, attachmentDetails := range details.Attachments {
			unitTag, err := names.ParseUnitTag(unitTagString)
			if err != nil {
				return names.StorageTag{}, StorageInfo{}, errors.Trace(err)
			}
			var machineId string
			if attachmentDetails.MachineTag != "" {
				machineTag, err := names.ParseMachineTag(attachmentDetails.MachineTag)
				if err != nil {
					return names.StorageTag{}, StorageInfo{}, errors.Trace(err)
				}
				machineId = machineTag.Id()
			}
			unitStorageAttachments[unitTag.Id()] = UnitStorageAttachment{
				machineId,
				attachmentDetails.Location,
			}
		}
		info.Attachments = &StorageAttachments{unitStorageAttachments}
	}

	return storageTag, info, nil
}
Exemplo n.º 10
0
func createInfo(volume params.VolumeInstance) (info VolumeInfo, unit, storage string) {
	info.VolumeId = volume.VolumeId
	info.HardwareId = volume.HardwareId
	info.Size = volume.Size
	info.Persistent = volume.Persistent
	info.Status = EntityStatus{
		volume.Status.Status,
		volume.Status.Info,
		// TODO(axw) we should support formatting as ISO time
		common.FormatTime(volume.Status.Since, false),
	}

	if v, err := idFromTag(volume.VolumeTag); err == nil {
		info.Volume = v
	}
	var err error
	if storage, err = idFromTag(volume.StorageTag); err != nil {
		storage = "unassigned"
	}
	if unit, err = idFromTag(volume.UnitTag); err != nil {
		unit = "unattached"
	}
	return
}
Exemplo n.º 11
0
Arquivo: history.go Projeto: bac/juju
func (c *statusHistoryCommand) Run(ctx *cmd.Context) error {
	apiclient, err := c.NewAPIClient()
	if err != nil {
		return errors.Trace(err)
	}
	defer apiclient.Close()
	kind := status.HistoryKind(c.outputContent)
	var delta *time.Duration

	if c.backlogSizeDays != 0 {
		t := time.Duration(c.backlogSizeDays*24) * time.Hour
		delta = &t
	}
	filterArgs := status.StatusHistoryFilter{
		Size:  c.backlogSize,
		Delta: delta,
	}
	if !c.date.IsZero() {
		filterArgs.Date = &c.date
	}
	var tag names.Tag
	switch kind {
	case status.KindUnit, status.KindWorkload, status.KindUnitAgent:
		if !names.IsValidUnit(c.entityName) {
			return errors.Errorf("%q is not a valid name for a %s", c.entityName, kind)
		}
		tag = names.NewUnitTag(c.entityName)
	default:
		if !names.IsValidMachine(c.entityName) {
			return errors.Errorf("%q is not a valid name for a %s", c.entityName, kind)
		}
		tag = names.NewMachineTag(c.entityName)
	}
	statuses, err := apiclient.StatusHistory(kind, tag, filterArgs)
	historyLen := len(statuses)
	if err != nil {
		if historyLen == 0 {
			return errors.Trace(err)
		}
		// Display any error, but continue to print status if some was returned
		fmt.Fprintf(ctx.Stderr, "%v\n", err)
	}

	if historyLen == 0 {
		return errors.Errorf("no status history available")
	}

	table := [][]string{{"TIME", "TYPE", "STATUS", "MESSAGE"}}
	lengths := []int{1, 1, 1, 1}

	statuses = statuses.SquashLogs(1)
	statuses = statuses.SquashLogs(2)
	statuses = statuses.SquashLogs(3)
	for _, v := range statuses {
		fields := []string{common.FormatTime(v.Since, c.isoTime), string(v.Kind), string(v.Status), v.Info}
		for k, v := range fields {
			if len(v) > lengths[k] {
				lengths[k] = len(v)
			}
		}
		table = append(table, fields)
	}
	f := fmt.Sprintf("%%-%ds\t%%-%ds\t%%-%ds\t%%-%ds\n", lengths[0], lengths[1], lengths[2], lengths[3])
	for _, v := range table {
		fmt.Printf(f, v[0], v[1], v[2], v[3])
	}
	return nil
}