// Instances is part of the environs.Environ interface.
512504
func (e *environ) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error) {
	if len(ids) == 0 {
		return nil, nil
	}
	insts := make([]instances.Instance, len(ids))
	// Make a series of requests to cope with eventual consistency.
	// Each request will attempt to add more instances to the requested
	// set.
	var err error
	for a := shortAttempt.Start(); a.Next(); {
		var need []string
		for i, inst := range insts {
			if inst == nil {
				need = append(need, string(ids[i]))
			}
		}
		filter := ec2.NewFilter()
		filter.Add("instance-state-name", aliveInstanceStates...)
		filter.Add("instance-id", need...)
		e.addModelFilter(filter)
		err = e.gatherInstances(ctx, ids, insts, filter)
		if err == nil || err != environs.ErrPartialInstances {
			break
		}
	}
	if err == environs.ErrPartialInstances {
		for _, inst := range insts {
			if inst != nil {
				return insts, environs.ErrPartialInstances
			}
		}
		return nil, environs.ErrNoInstances
	}
	if err != nil {
		return nil, err
	}
	return insts, nil
}
1220567
func (e *manualEnviron) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error) {
	result := make([]instances.Instance, len(ids))
	var found bool
	var err error
	for i, id := range ids {
		if id == BootstrapInstanceId {
			result[i] = manualBootstrapInstance{e.host}
			found = true
		} else {
			err = environs.ErrPartialInstances
		}
	}
	if !found {
		err = environs.ErrNoInstances
	}
	return result, err
}
531411
func (e *Environ) AllInstances(ctx context.ProviderCallContext) ([]instances.Instance, error) {
	tagFilter := tagValue{tags.JujuModel, e.ecfg().UUID()}
	instances, err := e.allInstances(ctx, tagFilter, e.ecfg().useFloatingIP())
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return instances, err
	}
	return instances, nil
}
551992
func (o *OracleEnviron) StartInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) (*environs.StartInstanceResult, error) {
	if args.ControllerUUID == "" {
		return nil, errors.NotFoundf("Controller UUID")
	}

	series := args.Tools.OneSeries()
	arches := args.Tools.Arches()

	// take all instance types from the oracle cloud provider
	types, err := instanceTypes(o.client)
	if err != nil {
		return nil, errors.Trace(err)
	}

	// check if we find an image that is compliant with the
	// constraints provided in the oracle cloud account
	if args.ImageMetadata, err = checkImageList(o.client); err != nil {
		return nil, errors.Trace(err)
	}

	// find the best suitable instance based on
	// the oracle cloud instance types,
	// the images that already matched the juju constrains
	spec, imagelist, err := findInstanceSpec(
		o.client,
		args.ImageMetadata,
		types,
		&envinstance.InstanceConstraint{
			Region:      o.spec.Region,
			Series:      series,
			Arches:      arches,
			Constraints: args.Constraints,
		},
	)
	if err != nil {
		return nil, errors.Trace(err)
	}

	tools, err := args.Tools.Match(tools.Filter{Arch: spec.Image.Arch})
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Tracef("agent binaries: %v", tools)
	if err = args.InstanceConfig.SetTools(tools); err != nil {
		return nil, errors.Trace(err)
	}

	if err = instancecfg.FinishInstanceConfig(
		args.InstanceConfig,
		o.Config(),
	); err != nil {
		return nil, errors.Trace(err)
	}

	hostname, err := o.namespace.Hostname(args.InstanceConfig.MachineId)
	if err != nil {
		return nil, errors.Trace(err)
	}

	machineName := o.client.ComposeName(hostname)
	imageName := o.client.ComposeName(imagelist)

	tags := make([]string, 0, len(args.InstanceConfig.Tags)+1)
	for k, v := range args.InstanceConfig.Tags {
		if k == "" || v == "" {
			continue
		}
		t := tagValue{k, v}
		tags = append(tags, t.String())
	}
	tags = append(tags, machineName)

	var apiPort int
	var desiredStatus ociCommon.InstanceState
	if args.InstanceConfig.Controller != nil {
		apiPort = args.InstanceConfig.Controller.Config.APIPort()
		desiredStatus = ociCommon.StateRunning
	} else {
		// All ports are the same so pick the first.
		apiPort = args.InstanceConfig.APIInfo.Ports()[0]
		desiredStatus = ociCommon.StateStarting
	}

	// create a new seclists
	secLists, err := o.CreateMachineSecLists(
		args.InstanceConfig.MachineId, apiPort)
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Debugf("Creating vnic sets")
	vnicSets, err := o.ensureVnicSet(ctx, args.InstanceConfig.MachineId, tags)
	if err != nil {
		return nil, errors.Trace(err)
	}
	// fetch instance network card configuration
	logger.Debugf("Getting instance networks")
	networking, err := o.getInstanceNetworks(ctx, args, secLists, []string{vnicSets.Name})
	if err != nil {
		return nil, errors.Trace(err)
	}

	logger.Debugf("Getting cloud config")
	cloudcfg, err := o.getCloudInitConfig(args.InstanceConfig.Series, networking)
	if err != nil {
		return nil, errors.Annotate(err, "cannot create cloudinit template")
	}

	// compose userdata with the cloud config template
	logger.Debugf("Composing userdata")
	userData, err := providerinit.ComposeUserData(
		args.InstanceConfig,
		cloudcfg,
		OracleRenderer{},
	)
	if err != nil {
		return nil, errors.Annotate(err, "cannot make user data")
	}

	logger.Debugf("oracle user data: %d bytes", len(userData))

	attributes := map[string]interface{}{
		"userdata": string(userData),
	}

	// create the instance based on the instance params
	instance, err := o.createInstance(oci.InstanceParams{
		Instances: []oci.Instances{
			{
				Shape:       spec.InstanceType.Name,
				Imagelist:   imageName,
				Name:        machineName,
				Label:       args.InstanceConfig.MachineAgentServiceName,
				Hostname:    hostname,
				Tags:        tags,
				Attributes:  attributes,
				Reverse_dns: true,
				Networking:  networking,
			},
		},
	})
	if err != nil {
		return nil, errors.Trace(err)
	}

	instance.arch = &spec.Image.Arch
	instance.instType = &spec.InstanceType

	machineId := instance.machine.Name
	timeout := 10 * time.Minute
	if err := instance.waitForMachineStatus(desiredStatus, timeout); err != nil {
		return nil, errors.Trace(err)
	}
	logger.Infof("started instance %q", machineId)

	//TODO: add config option for public IP allocation
	logger.Debugf("Associating public IP to instance %q", machineId)
	if err := instance.associatePublicIP(); err != nil {
		return nil, errors.Trace(err)
	}
	result := &environs.StartInstanceResult{
		Instance: instance,
		Hardware: instance.hardwareCharacteristics(),
	}

	return result, nil
}
964435
func (o *OracleEnviron) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]envinstance.Instance, error) {
	if len(ids) == 0 {
		return nil, nil
	}
	instances, err := o.getOracleInstances(ids...)
	if err != nil {
		return nil, err
	}

	ret := []envinstance.Instance{}
	for _, val := range instances {
		ret = append(ret, val)
	}
	return ret, nil
}
523038
func (api *CloudAPI) InstanceTypes(cons params.CloudInstanceTypesConstraints) (params.InstanceTypesResults, error) {
	return instanceTypes(api, environs.GetEnviron, cons)
}
1027126
func (env *environ) AllInstances(ctx context.ProviderCallContext) ([]instances.Instance, error) {
	// Please note that this must *not* return instances that have not been
	// allocated as part of this environment -- if it does, juju will see they
	// are not tracked in state, assume they're stale/rogue, and shut them down.

	logger.Tracef("environ.AllInstances...")

	servers, err := env.client.instances()
	if err != nil {
		logger.Tracef("environ.AllInstances failed: %v", err)
		return nil, err
	}

	instances := make([]instances.Instance, 0, len(servers))
	for _, server := range servers {
		instance := sigmaInstance{server: server}
		instances = append(instances, instance)
	}

	if logger.LogLevel() <= loggo.TRACE {
		logger.Tracef("All instances, len = %d:", len(instances))
		for _, instance := range instances {
			logger.Tracef("... id: %q, status: %q", instance.Id(), instance.Status(ctx))
		}
	}

	return instances, nil
}
78519
func (e *Environ) StartInstance(ctx context.ProviderCallContext, args environs.StartInstanceParams) (_ *environs.StartInstanceResult, err error) {
	if args.AvailabilityZone != "" {
		// args.AvailabilityZone should only be set if this OpenStack
		// supports zones; validate the zone.
		volumeAttachmentsZone, err := e.volumeAttachmentsZone(args.VolumeAttachments)
		if err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, common.ZoneIndependentError(err)
		}
		if err := validateAvailabilityZoneConsistency(args.AvailabilityZone, volumeAttachmentsZone); err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, common.ZoneIndependentError(err)
		}
		if err := common.ValidateAvailabilityZone(e, ctx, args.AvailabilityZone); err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, errors.Trace(err)
		}
	}

	series := args.Tools.OneSeries()
	arches := args.Tools.Arches()
	spec, err := findInstanceSpec(e, &instances.InstanceConstraint{
		Region:      e.cloud().Region,
		Series:      series,
		Arches:      arches,
		Constraints: args.Constraints,
	}, args.ImageMetadata)
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(err)
	}
	tools, err := args.Tools.Match(tools.Filter{Arch: spec.Image.Arch})
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(
			errors.Errorf("chosen architecture %v not present in %v", spec.Image.Arch, arches),
		)
	}

	if err := args.InstanceConfig.SetTools(tools); err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(err)
	}

	if err := instancecfg.FinishInstanceConfig(args.InstanceConfig, e.Config()); err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(err)
	}
	cloudcfg, err := e.configurator.GetCloudConfig(args)
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(err)
	}
	userData, err := providerinit.ComposeUserData(args.InstanceConfig, cloudcfg, OpenstackRenderer{})
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(errors.Annotate(err, "cannot make user data"))
	}
	logger.Debugf("openstack user data; %d bytes", len(userData))

	networks, err := e.networking.DefaultNetworks()
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(errors.Annotate(err, "getting initial networks"))
	}
	usingNetwork := e.ecfg().network()
	networkId, err := e.networking.ResolveNetwork(usingNetwork, false)
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		if usingNetwork == "" {
			// If there is no network configured, we only throw out when the
			// error reports multiple Openstack networks.
			// If there are no Openstack networks at all (such as Canonistack),
			// having no network config is not an error condition.
			if strings.HasPrefix(err.Error(), "multiple networks") {
				return nil, common.ZoneIndependentError(errors.New(noNetConfigMsg(err)))
			}
		} else {
			return nil, common.ZoneIndependentError(err)
		}
	} else {
		logger.Debugf("using network id %q", networkId)
		networks = append(networks, nova.ServerNetworks{NetworkId: networkId})
	}

	machineName := resourceName(
		e.namespace,
		e.name,
		args.InstanceConfig.MachineId,
	)

	if e.ecfg().useOpenstackGBP() {
		client := e.neutron()
		ptArg := neutron.PolicyTargetV2{
			Name:                fmt.Sprintf("juju-policytarget-%s", machineName),
			PolicyTargetGroupId: e.ecfg().policyTargetGroup(),
		}
		pt, err := client.CreatePolicyTargetV2(ptArg)
		if err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, errors.Trace(err)
		}
		networks = append(networks, nova.ServerNetworks{PortId: pt.PortId})
	}

	// For BUG 1680787: openstack: add support for neutron networks where port
	// security is disabled.
	// If any network specified for instance boot has PortSecurityEnabled equals
	// false, don't create security groups, instance boot will fail.
	createSecurityGroups := true
	if len(networks) > 0 && e.supportsNeutron() {
		client := e.neutron()
		for _, n := range networks {
			if n.NetworkId == "" {
				// It's a GBP network.
				continue
			}
			net, err := client.GetNetworkV2(n.NetworkId)
			if err != nil {
				common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
				return nil, common.ZoneIndependentError(err)
			}
			if net.PortSecurityEnabled != nil &&
				*net.PortSecurityEnabled == false {
				createSecurityGroups = *net.PortSecurityEnabled
				logger.Infof("network %q has port_security_enabled set to false. Not using security groups.", net.Id)
				break
			}
		}
	}

	var novaGroupNames = []nova.SecurityGroupName{}
	if createSecurityGroups {
		var apiPort int
		if args.InstanceConfig.Controller != nil {
			apiPort = args.InstanceConfig.Controller.Config.APIPort()
		} else {
			// All ports are the same so pick the first.
			apiPort = args.InstanceConfig.APIInfo.Ports()[0]
		}
		groupNames, err := e.firewaller.SetUpGroups(ctx, args.ControllerUUID, args.InstanceConfig.MachineId, apiPort)
		if err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, common.ZoneIndependentError(errors.Annotate(err, "cannot set up groups"))
		}
		novaGroupNames = make([]nova.SecurityGroupName, len(groupNames))
		for i, name := range groupNames {
			novaGroupNames[i].Name = name
		}
	}

	waitForActiveServerDetails := func(
		client *nova.Client,
		id string,
		timeout time.Duration,
	) (server *nova.ServerDetail, err error) {

		var errStillBuilding = errors.Errorf("instance %q has status BUILD", id)
		err = retry.Call(retry.CallArgs{
			Clock:       e.clock,
			Delay:       10 * time.Second,
			MaxDuration: timeout,
			Func: func() error {
				server, err = client.GetServer(id)
				if err != nil {
					return err
				}
				if server.Status == nova.StatusBuild {
					return errStillBuilding
				}
				return nil
			},
			NotifyFunc: func(lastError error, attempt int) {
				args.StatusCallback(status.Provisioning, fmt.Sprintf("%s, wait 10 seconds before retry, attempt %d", lastError, attempt), nil)
			},
			IsFatalError: func(err error) bool {
				return err != errStillBuilding
			},
		})
		if err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, err
		}
		return server, nil
	}

	tryStartNovaInstance := func(
		attempts utils.AttemptStrategy,
		client *nova.Client,
		instanceOpts nova.RunServerOpts,
	) (server *nova.Entity, err error) {
		for a := attempts.Start(); a.Next(); {
			server, err = client.RunServer(instanceOpts)
			if err != nil {
				common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
				break
			}
			if server == nil {
				logger.Warningf("may have lost contact with nova api while creating instances, some stray instances may be around and need to be deleted")
				break
			}
			var serverDetail *nova.ServerDetail
			serverDetail, err = waitForActiveServerDetails(client, server.Id, 5*time.Minute)
			if err != nil || serverDetail == nil {
				server = nil
				break
			} else if serverDetail.Status == nova.StatusActive {
				break
			} else if serverDetail.Status == nova.StatusError {
				// Perhaps there is an error case where a retry in the same AZ
				// is a good idea.
				faultMsg := " unable to determine fault details"
				if serverDetail.Fault != nil {
					faultMsg = fmt.Sprintf(" with fault %q", serverDetail.Fault.Message)
				} else {
					logger.Debugf("getting active server details from nova failed without fault details")
				}
				logger.Infof("Deleting instance %q in ERROR state%v", server.Id, faultMsg)
				if err = e.terminateInstances(ctx, []instance.Id{instance.Id(server.Id)}); err != nil {
					logger.Debugf("Failed to delete instance in ERROR state, %q", err)
				}
				server = nil
				err = errors.New(faultMsg)
				break
			}
		}
		return server, err
	}

	var opts = nova.RunServerOpts{
		Name:               machineName,
		FlavorId:           spec.InstanceType.Id,
		ImageId:            spec.Image.Id,
		UserData:           userData,
		SecurityGroupNames: novaGroupNames,
		Networks:           networks,
		Metadata:           args.InstanceConfig.Tags,
		AvailabilityZone:   args.AvailabilityZone,
	}
	e.configurator.ModifyRunServerOptions(&opts)

	server, err := tryStartNovaInstance(shortAttempt, e.nova(), opts)
	if err != nil || server == nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		// 'No valid host available' is typically a resource error,
		// let the provisioner know it is a good idea to try another
		// AZ if available.
		err := errors.Annotate(err, "cannot run instance")
		zoneSpecific := isNoValidHostsError(err)
		if !zoneSpecific {
			err = common.ZoneIndependentError(err)
		}
		return nil, err
	}

	detail, err := e.nova().GetServer(server.Id)
	if err != nil {
		common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
		return nil, common.ZoneIndependentError(errors.Annotate(err, "cannot get started instance"))
	}

	inst := &openstackInstance{
		e:            e,
		serverDetail: detail,
		arch:         &spec.Image.Arch,
		instType:     &spec.InstanceType,
	}
	logger.Infof("started instance %q", inst.Id())
	withPublicIP := e.ecfg().useFloatingIP()
	if withPublicIP {
		// If we don't lock here, AllocatePublicIP() can return the same
		// public IP for 2 different instances.  Only one will successfully
		// be assigned the public IP, the other will not have one.
		e.publicIPMutex.Lock()
		defer e.publicIPMutex.Unlock()
		var publicIP *string
		logger.Debugf("allocating public IP address for openstack node")
		if fip, err := e.networking.AllocatePublicIP(inst.Id()); err != nil {
			common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
			return nil, common.ZoneIndependentError(errors.Annotate(err, "cannot allocate a public IP as needed"))
		} else {
			publicIP = fip
			logger.Infof("allocated public IP %s", *publicIP)
		}
		if err := e.assignPublicIP(publicIP, string(inst.Id())); err != nil {
			if err := e.terminateInstances(ctx, []instance.Id{inst.Id()}); err != nil {
				common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
				// ignore the failure at this stage, just log it
				logger.Debugf("failed to terminate instance %q: %v", inst.Id(), err)
			}
			return nil, common.ZoneIndependentError(errors.Annotatef(err,
				"cannot assign public address %s to instance %q",
				*publicIP, inst.Id(),
			))
		}
		inst.floatingIP = publicIP
	}

	return &environs.StartInstanceResult{
		Instance: inst,
		Hardware: inst.hardwareCharacteristics(),
	}, nil
}
1353968
func (gce *Connection) Instance(id, zone string) (Instance, error) {
	var result Instance
	raw, err := gce.raw.GetInstance(gce.projectID, zone, id)
	if err != nil {
		return result, errors.Trace(err)
	}
	result = *newInstance(raw, nil)
	return result, nil
}
110604
func (s *ProxyStore) Instances(service string) ([]*discoverd.Instance, error) {
	host := s.Peers[rand.Intn(len(s.Peers))]
	client := discoverd.NewClientWithURL("http://" + host)
	return client.Service(service).Instances()
}
13785
func (e *environ) InstanceTypes(ctx context.ProviderCallContext, c constraints.Value) (instances.InstanceTypesWithCostMetadata, error) {
	iTypes, err := e.supportedInstanceTypes(ctx)
	if err != nil {
		return instances.InstanceTypesWithCostMetadata{}, errors.Trace(err)
	}
	iTypes, err = instances.MatchingInstanceTypes(iTypes, "", c)
	if err != nil {
		return instances.InstanceTypesWithCostMetadata{}, errors.Trace(err)
	}
	return instances.InstanceTypesWithCostMetadata{
		InstanceTypes: iTypes,
		CostUnit:      "$USD/hour",
		CostDivisor:   1000,
		CostCurrency:  "USD"}, nil
}
497873
func (env *environ) StopInstances(ctx context.ProviderCallContext, ids ...instance.Id) error {
	return env.withSession(ctx, func(env *sessionEnviron) error {
		return env.StopInstances(ctx, ids...)
	})
}
654087
func (os *OpenStack) Instances() (cloudprovider.Instances, bool) {
	klog.V(4).Info("openstack.Instances() called")

	compute, err := os.NewComputeV2()
	if err != nil {
		klog.Errorf("unable to access compute v2 API : %v", err)
		return nil, false
	}

	klog.V(4).Info("Claiming to support Instances")

	return &Instances{
		compute: compute,
		opts:    os.metadataOpts,
	}, true
}
682651
func (e *environ) DistributeInstances(
	ctx context.ProviderCallContext, candidates, distributionGroup []instance.Id, limitZones []string,
) ([]instance.Id, error) {
	return common.DistributeInstances(e, ctx, candidates, distributionGroup, limitZones)
}
629037
func (env *azureEnviron) getInstanceTypes(ctx context.ProviderCallContext) (map[string]instances.InstanceType, error) {
	env.mu.Lock()
	defer env.mu.Unlock()
	instanceTypes, err := env.getInstanceTypesLocked(ctx)
	if err != nil {
		return nil, errors.Annotate(err, "getting instance types")
	}
	return instanceTypes, nil
}
735645
func (s *Scheduler) instances(ctx context.Context, app string, labels ...string) ([]*twelvefactor.Task, error) {
	var instances []*twelvefactor.Task

	containers, err := s.docker.ListContainers(docker.ListContainersOptions{
		Filters: map[string][]string{
			"label": append([]string{
				fmt.Sprintf("%s=%s", appLabel, app),
			}, labels...),
		},
	})
	if err != nil {
		return nil, fmt.Errorf("error listing containers from attached runs: %v", err)
	}

	for _, apiContainer := range containers {
		container, err := s.docker.InspectContainer(apiContainer.ID)
		if err != nil {
			return instances, fmt.Errorf("error inspecting container %s: %v", apiContainer.ID, err)
		}

		state := strings.ToUpper(container.State.StateString())

		instances = append(instances, &twelvefactor.Task{
			ID:        container.ID[0:12],
			State:     state,
			UpdatedAt: container.State.StartedAt,
			Process: &twelvefactor.Process{
				Type:      container.Config.Labels[processLabel],
				Command:   container.Config.Cmd,
				Env:       parseEnv(container.Config.Env),
				Memory:    uint(container.HostConfig.Memory),
				CPUShares: uint(container.HostConfig.CPUShares),
			},
		})
	}

	return instances, nil
}
194728
func (env *azureEnviron) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error) {
	return env.instances(ctx, env.resourceGroup, ids, true /* refresh addresses */)
}