// Units returns all units and any associated filesystems of the specified application.
// Filesystems are mounted via volumes bound to the unit.
504317
func (k *kubernetesClient) Units(appName string) ([]caas.Unit, error) {
	pods := k.client().CoreV1().Pods(k.namespace)
	podsList, err := pods.List(v1.ListOptions{
		LabelSelector: applicationSelector(appName),
	})
	if err != nil {
		return nil, errors.Trace(err)
	}

	var units []caas.Unit
	now := time.Now()
	for _, p := range podsList.Items {
		var ports []string
		for _, c := range p.Spec.Containers {
			for _, p := range c.Ports {
				ports = append(ports, fmt.Sprintf("%v/%v", p.ContainerPort, p.Protocol))
			}
		}
		terminated := p.DeletionTimestamp != nil
		statusMessage, unitStatus, since, err := k.getPODStatus(p, now)
		if err != nil {
			return nil, errors.Trace(err)
		}
		providerId := string(p.UID)
		stateful := false

		// Pods managed by a stateful set use the pod name
		// as the provider id as this is stable across pod restarts.
		for _, ref := range p.OwnerReferences {
			if stateful = ref.Kind == "StatefulSet"; stateful {
				providerId = p.Name
				break
			}
		}
		unitInfo := caas.Unit{
			Id:       providerId,
			Address:  p.Status.PodIP,
			Ports:    ports,
			Dying:    terminated,
			Stateful: stateful,
			Status: status.StatusInfo{
				Status:  unitStatus,
				Message: statusMessage,
				Since:   &since,
			},
		}

		volumesByName := make(map[string]core.Volume)
		for _, pv := range p.Spec.Volumes {
			volumesByName[pv.Name] = pv
		}

		// Gather info about how filesystems are attached/mounted to the pod.
		// The mount name represents the filesystem tag name used by Juju.
		for _, volMount := range p.Spec.Containers[0].VolumeMounts {
			vol, ok := volumesByName[volMount.Name]
			if !ok {
				logger.Warningf("volume for volume mount %q not found", volMount.Name)
				continue
			}
			var fsInfo *caas.FilesystemInfo
			if vol.PersistentVolumeClaim != nil && vol.PersistentVolumeClaim.ClaimName != "" {
				fsInfo, err = k.volumeInfoForPVC(vol, volMount, vol.PersistentVolumeClaim.ClaimName, now)
			} else if vol.EmptyDir != nil {
				fsInfo, err = k.volumeInfoForEmptyDir(vol, volMount, now)
			} else {
				// Ignore volumes which are not Juju managed filesystems.
				logger.Debugf("Ignoring blank EmptyDir, PersistentVolumeClaim or ClaimName")
				continue
			}
			if err != nil {
				return nil, errors.Annotatef(err, "finding filesystem info for %v", volMount.Name)
			}
			if fsInfo == nil {
				continue
			}
			if fsInfo.StorageName == "" {
				if valid := legacyJujuPVNameRegexp.MatchString(volMount.Name); valid {
					fsInfo.StorageName = legacyJujuPVNameRegexp.ReplaceAllString(volMount.Name, "$storageName")
				} else if valid := jujuPVNameRegexp.MatchString(volMount.Name); valid {
					fsInfo.StorageName = jujuPVNameRegexp.ReplaceAllString(volMount.Name, "$storageName")
				}
			}
			logger.Debugf("filesystem info for %v: %+v", volMount.Name, *fsInfo)
			unitInfo.FilesystemInfo = append(unitInfo.FilesystemInfo, *fsInfo)
		}
		units = append(units, unitInfo)
	}
	return units, nil
}
974865
func StorageServices(ctx types.Context) <-chan types.StorageService {
	c := make(chan types.StorageService)
	go func() {
		for _, v := range getStorageServices(ctx) {
			c <- v
		}
		close(c)
	}()
	return c
}
848351
func (daemon *Daemon) SystemDiskUsage(ctx context.Context) (*types.DiskUsage, error) {
	if !atomic.CompareAndSwapInt32(&daemon.diskUsageRunning, 0, 1) {
		return nil, fmt.Errorf("a disk usage operation is already running")
	}
	defer atomic.StoreInt32(&daemon.diskUsageRunning, 0)

	// Retrieve container list
	allContainers, err := daemon.Containers(&types.ContainerListOptions{
		Size: true,
		All:  true,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve container list: %v", err)
	}

	// Get all top images with extra attributes
	allImages, err := daemon.imageService.Images(filters.NewArgs(), false, true)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve image list: %v", err)
	}

	localVolumes, err := daemon.volumes.LocalVolumesSize(ctx)
	if err != nil {
		return nil, err
	}

	allLayersSize, err := daemon.imageService.LayerDiskUsage(ctx)
	if err != nil {
		return nil, err
	}

	return &types.DiskUsage{
		LayersSize: allLayersSize,
		Containers: allContainers,
		Volumes:    localVolumes,
		Images:     allImages,
	}, nil
}
116597
func (s *StorageProvisionerAPIv3) Volumes(args params.Entities) (params.VolumeResults, error) {
	canAccess, err := s.getStorageEntityAuthFunc()
	if err != nil {
		return params.VolumeResults{}, common.ServerError(common.ErrPerm)
	}
	results := params.VolumeResults{
		Results: make([]params.VolumeResult, len(args.Entities)),
	}
	one := func(arg params.Entity) (params.Volume, error) {
		tag, err := names.ParseVolumeTag(arg.Tag)
		if err != nil || !canAccess(tag) {
			return params.Volume{}, common.ErrPerm
		}
		volume, err := s.sb.Volume(tag)
		if errors.IsNotFound(err) {
			return params.Volume{}, common.ErrPerm
		} else if err != nil {
			return params.Volume{}, err
		}
		return storagecommon.VolumeFromState(volume)
	}
	for i, arg := range args.Entities {
		var result params.VolumeResult
		volume, err := one(arg)
		if err != nil {
			result.Error = common.ServerError(err)
		} else {
			result.Result = volume
		}
		results.Results[i] = result
	}
	return results, nil
}
1309471
func getUnitFromFile(file string) (*unit.UnitFile, error) {
	out, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	unitName := path.Base(file)
	log.Debugf("Unit(%s) found in local filesystem", unitName)

	return unit.NewUnitFile(string(out))
}
1240960
func (s *precheckAppShim) AllUnits() ([]PrecheckUnit, error) {
	units, err := s.Application.AllUnits()
	if err != nil {
		return nil, errors.Trace(err)
	}
	out := make([]PrecheckUnit, 0, len(units))
	for _, unit := range units {
		out = append(out, unit)
	}
	return out, nil
}
1283577
func (r *Application) Storage(disk float64) *Application {
	r.Disk = &disk
	return r
}
1120453
func (u *Unit) storageParams() (*storageParams, error) {
	params, err := unitStorageParams(u)
	if err != nil {
		return nil, errors.Trace(err)
	}
	for _, name := range u.doc.Subordinates {
		sub, err := u.st.Unit(name)
		if err != nil {
			return nil, errors.Trace(err)
		}
		subParams, err := unitStorageParams(sub)
		if err != nil {
			return nil, errors.Trace(err)
		}
		params = combineStorageParams(params, subParams)
	}
	return params, nil
}
863914
func (c *FleetClient) ListUnitFiles() (err error) {
	var sortable sort.StringSlice
	units := make(map[string]*schema.Unit, 0)

	us, err := c.Fleet.Units()
	if err != nil {
		return err
	}

	for _, u := range us {
		if strings.HasPrefix(u.Name, "deis-") {
			units[u.Name] = u
			sortable = append(sortable, u.Name)
		}
	}
	sortable.Sort()
	c.printUnitFiles(units, sortable)
	return
}
488122
func (a *Application) AllUnits() (units []*Unit, err error) {
	return allUnits(a.st, a.doc.Name)
}
80045
func unitNames(units map[string]string) string {
	unitIds := make([]string, len(units))
	i := 0
	for u := range units {
		unitIds[i] = u
		i++
	}
	return strings.Join(unitIds, ", ")
}
75858
func (c *Client) DestroyUnits(in DestroyUnitsParams) ([]params.DestroyUnitResult, error) {
	argsV5 := params.DestroyUnitsParams{
		Units: make([]params.DestroyUnitParams, 0, len(in.Units)),
	}
	allResults := make([]params.DestroyUnitResult, len(in.Units))
	index := make([]int, 0, len(in.Units))
	for i, name := range in.Units {
		if !names.IsValidUnit(name) {
			allResults[i].Error = &params.Error{
				Message: errors.NotValidf("unit ID %q", name).Error(),
			}
			continue
		}
		index = append(index, i)
		argsV5.Units = append(argsV5.Units, params.DestroyUnitParams{
			UnitTag:        names.NewUnitTag(name).String(),
			DestroyStorage: in.DestroyStorage,
			Force:          in.Force,
			MaxWait:        in.MaxWait,
		})
	}
	if len(argsV5.Units) == 0 {
		return allResults, nil
	}

	args := interface{}(argsV5)
	if c.BestAPIVersion() < 5 {
		if in.DestroyStorage {
			return nil, errors.New("this controller does not support --destroy-storage")
		}
		argsV4 := params.Entities{
			Entities: make([]params.Entity, len(argsV5.Units)),
		}
		for i, arg := range argsV5.Units {
			argsV4.Entities[i].Tag = arg.UnitTag
		}
		args = argsV4
	}

	var result params.DestroyUnitResults
	if err := c.facade.FacadeCall("DestroyUnit", args, &result); err != nil {
		return nil, errors.Trace(err)
	}
	if n := len(result.Results); n != len(argsV5.Units) {
		return nil, errors.Errorf("expected %d result(s), got %d", len(argsV5.Units), n)
	}
	for i, result := range result.Results {
		allResults[index[i]] = result
	}
	return allResults, nil
}
1040189
func (c *FleetClient) Units(target string) (units []string, err error) {
	allUnits, err := c.Fleet.Units()
	if err != nil {
		return
	}
	// Look for units starting with the given target name first. If the given
	// name starts with "deis-", this will easily locate platform components,
	// but we search without canonicalizing the target name FIRST so we have the
	// opportunity to locate application containers (whose containers do not
	// adhere to the same naming convention as the platform's own components).
	for _, u := range allUnits {
		if strings.HasPrefix(u.Name, target) {
			units = append(units, u.Name)
		}
	}
	// If none are found, canonicalize the target string and search again. This
	// will locate platform components that were referenced by a target string
	// NOT already beginning with "deis-".
	if len(units) == 0 {
		canonTarget := strings.ToLower(target)
		if !strings.HasPrefix(canonTarget, "deis-") {
			canonTarget = "deis-" + canonTarget
		}
		for _, u := range allUnits {
			if strings.HasPrefix(u.Name, canonTarget) {
				units = append(units, u.Name)
			}
		}
	}
	// If still nothing is found, then we have an error on our hands.
	if len(units) == 0 {
		err = fmt.Errorf("could not find unit: %s", target)
	}
	return
}
439200
func (m *MockModelCacheMachine) Units() ([]instancemutater.ModelCacheUnit, error) {
	ret := m.ctrl.Call(m, "Units")
	ret0, _ := ret[0].([]instancemutater.ModelCacheUnit)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}
543066
func (m *systemdUnitManager) Load(name string, u unit.UnitFile) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	err := m.writeUnit(name, u.String())
	if err != nil {
		return err
	}
	if _, exists := u.Contents["Install"]; exists {
		log.Debugf("Detected [Install] section in the systemd unit (%s)", name)
		ok, err := m.enableUnit(name)
		if err != nil || !ok {
			m.removeUnit(name)
			return fmt.Errorf("Failed to enable systemd unit %s: %v", name, err)
		}
	}
	m.hashes[name] = u.Hash()
	return nil
}
104810
func (p *PodContainer) Storage(disk float64) *PodContainer {
	p.Resources.Disk = disk
	return p
}
1251139
func (uow *UnitOfWork) Rm(force bool, volumes bool) {
	for _, container := range uow.Targeted().Reversed() {
		container.Rm(force, volumes)
	}
}