// StartInstance is specified in the InstanceBroker interface. func (e *environ) StartInstance(args environs.StartInstanceParams) (*environs.StartInstanceResult, error) { defer delay() machineId := args.InstanceConfig.MachineId logger.Infof("dummy startinstance, machine %s", machineId) if err := e.checkBroken("StartInstance"); err != nil { return nil, err } estate, err := e.state() if err != nil { return nil, err } estate.mu.Lock() defer estate.mu.Unlock() // check if an error has been injected on the transientErrorInjection channel (testing purposes) select { case injectedError := <-transientErrorInjection: return nil, injectedError default: } if args.InstanceConfig.MachineNonce == "" { return nil, errors.New("cannot start instance: missing machine nonce") } if _, ok := e.Config().CACert(); !ok { return nil, errors.New("no CA certificate in environment configuration") } if args.InstanceConfig.MongoInfo.Tag != names.NewMachineTag(machineId) { return nil, errors.New("entity tag must match started machine") } if args.InstanceConfig.APIInfo.Tag != names.NewMachineTag(machineId) { return nil, errors.New("entity tag must match started machine") } logger.Infof("would pick tools from %s", args.Tools) series := args.Tools.OneSeries() idString := fmt.Sprintf("%s-%d", e.name, estate.maxId) addrs := network.NewAddresses(idString+".dns", "127.0.0.1") if estate.preferIPv6 { addrs = append(addrs, network.NewAddress(fmt.Sprintf("fc00::%x", estate.maxId+1))) } logger.Debugf("StartInstance addresses: %v", addrs) i := &dummyInstance{ id: instance.Id(idString), addresses: addrs, ports: make(map[network.PortRange]bool), machineId: machineId, series: series, firewallMode: e.Config().FirewallMode(), state: estate, } var hc *instance.HardwareCharacteristics // To match current system capability, only provide hardware characteristics for // environ machines, not containers. if state.ParentId(machineId) == "" { // We will just assume the instance hardware characteristics exactly matches // the supplied constraints (if specified). hc = &instance.HardwareCharacteristics{ Arch: args.Constraints.Arch, Mem: args.Constraints.Mem, RootDisk: args.Constraints.RootDisk, CpuCores: args.Constraints.CpuCores, CpuPower: args.Constraints.CpuPower, Tags: args.Constraints.Tags, } // Fill in some expected instance hardware characteristics if constraints not specified. if hc.Arch == nil { arch := "amd64" hc.Arch = &arch } if hc.Mem == nil { mem := uint64(1024) hc.Mem = &mem } if hc.RootDisk == nil { disk := uint64(8192) hc.RootDisk = &disk } if hc.CpuCores == nil { cores := uint64(1) hc.CpuCores = &cores } } // Simulate networks added when requested. networks := append(args.Constraints.IncludeNetworks(), args.InstanceConfig.Networks...) networkInfo := make([]network.InterfaceInfo, len(networks)) for i, netName := range networks { if strings.HasPrefix(netName, "bad-") { // Simulate we didn't get correct information for the network. networkInfo[i] = network.InterfaceInfo{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: "invalid", } } else if strings.HasPrefix(netName, "invalid-") { // Simulate we got invalid information for the network. networkInfo[i] = network.InterfaceInfo{ ProviderId: network.Id(netName), NetworkName: "$$" + netName, CIDR: fmt.Sprintf("0.%d.2.0/24", i+1), } } else { networkInfo[i] = network.InterfaceInfo{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: fmt.Sprintf("0.%d.2.0/24", i+1), InterfaceName: fmt.Sprintf("eth%d", i), VLANTag: i, MACAddress: fmt.Sprintf("aa:bb:cc:dd:ee:f%d", i), } } // TODO(dimitern) Add the rest of the network.InterfaceInfo // fields when we can use them. } // Simulate creating volumes when requested. volumes := make([]storage.Volume, len(args.Volumes)) for i, v := range args.Volumes { persistent, _ := v.Attributes[storage.Persistent].(bool) volumes[i] = storage.Volume{ Tag: names.NewVolumeTag(strconv.Itoa(i + 1)), VolumeInfo: storage.VolumeInfo{ Size: v.Size, Persistent: persistent, }, } } estate.insts[i.id] = i estate.maxId++ estate.ops <- OpStartInstance{ Env: e.name, MachineId: machineId, MachineNonce: args.InstanceConfig.MachineNonce, PossibleTools: args.Tools, Constraints: args.Constraints, Networks: args.InstanceConfig.Networks, NetworkInfo: networkInfo, Volumes: volumes, Instance: i, Jobs: args.InstanceConfig.Jobs, Info: args.InstanceConfig.MongoInfo, APIInfo: args.InstanceConfig.APIInfo, AgentEnvironment: args.InstanceConfig.AgentEnvironment, Secret: e.ecfg().secret(), } return &environs.StartInstanceResult{ Instance: i, Hardware: hc, NetworkInfo: networkInfo, }, nil }
// StartInstance is specified in the InstanceBroker interface. func (e *environ) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) { defer delay() machineId := args.MachineConfig.MachineId logger.Infof("dummy startinstance, machine %s", machineId) if err := e.checkBroken("StartInstance"); err != nil { return nil, nil, nil, err } estate, err := e.state() if err != nil { return nil, nil, nil, err } estate.mu.Lock() defer estate.mu.Unlock() if args.MachineConfig.MachineNonce == "" { return nil, nil, nil, fmt.Errorf("cannot start instance: missing machine nonce") } if _, ok := e.Config().CACert(); !ok { return nil, nil, nil, fmt.Errorf("no CA certificate in environment configuration") } if args.MachineConfig.MongoInfo.Tag != names.NewMachineTag(machineId) { return nil, nil, nil, fmt.Errorf("entity tag must match started machine") } if args.MachineConfig.APIInfo.Tag != names.NewMachineTag(machineId) { return nil, nil, nil, fmt.Errorf("entity tag must match started machine") } logger.Infof("would pick tools from %s", args.Tools) series := args.Tools.OneSeries() idString := fmt.Sprintf("%s-%d", e.name, estate.maxId) addrs := network.NewAddresses(idString+".dns", "127.0.0.1") if estate.preferIPv6 { addrs = append(addrs, network.NewAddress(fmt.Sprintf("fc00::%x", estate.maxId+1), network.ScopeUnknown)) } logger.Debugf("StartInstance addresses: %v", addrs) i := &dummyInstance{ id: instance.Id(idString), addresses: addrs, ports: make(map[network.Port]bool), machineId: machineId, series: series, firewallMode: e.Config().FirewallMode(), state: estate, } var hc *instance.HardwareCharacteristics // To match current system capability, only provide hardware characteristics for // environ machines, not containers. if state.ParentId(machineId) == "" { // We will just assume the instance hardware characteristics exactly matches // the supplied constraints (if specified). hc = &instance.HardwareCharacteristics{ Arch: args.Constraints.Arch, Mem: args.Constraints.Mem, RootDisk: args.Constraints.RootDisk, CpuCores: args.Constraints.CpuCores, CpuPower: args.Constraints.CpuPower, Tags: args.Constraints.Tags, } // Fill in some expected instance hardware characteristics if constraints not specified. if hc.Arch == nil { arch := "amd64" hc.Arch = &arch } if hc.Mem == nil { mem := uint64(1024) hc.Mem = &mem } if hc.RootDisk == nil { disk := uint64(8192) hc.RootDisk = &disk } if hc.CpuCores == nil { cores := uint64(1) hc.CpuCores = &cores } } // Simulate networks added when requested. networks := append(args.Constraints.IncludeNetworks(), args.MachineConfig.Networks...) networkInfo := make([]network.Info, len(networks)) for i, netName := range networks { if strings.HasPrefix(netName, "bad-") { // Simulate we didn't get correct information for the network. networkInfo[i] = network.Info{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: "invalid", } } else { networkInfo[i] = network.Info{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: fmt.Sprintf("0.%d.2.0/24", i+1), InterfaceName: fmt.Sprintf("eth%d", i), VLANTag: i, MACAddress: fmt.Sprintf("aa:bb:cc:dd:ee:f%d", i), } } } estate.insts[i.id] = i estate.maxId++ estate.ops <- OpStartInstance{ Env: e.name, MachineId: machineId, MachineNonce: args.MachineConfig.MachineNonce, Constraints: args.Constraints, Networks: args.MachineConfig.Networks, NetworkInfo: networkInfo, Instance: i, Info: args.MachineConfig.MongoInfo, APIInfo: args.MachineConfig.APIInfo, Secret: e.ecfg().secret(), } return i, hc, networkInfo, nil }
// StartInstance is specified in the InstanceBroker interface. func (e *environ) StartInstance(args environs.StartInstanceParams) (*environs.StartInstanceResult, error) { defer delay() machineId := args.InstanceConfig.MachineId logger.Infof("dummy startinstance, machine %s", machineId) if err := e.checkBroken("StartInstance"); err != nil { return nil, err } estate, err := e.state() if err != nil { return nil, err } estate.mu.Lock() defer estate.mu.Unlock() // check if an error has been injected on the transientErrorInjection channel (testing purposes) select { case injectedError := <-transientErrorInjection: return nil, injectedError default: } if args.InstanceConfig.MachineNonce == "" { return nil, errors.New("cannot start instance: missing machine nonce") } if _, ok := e.Config().CACert(); !ok { return nil, errors.New("no CA certificate in model configuration") } if args.InstanceConfig.MongoInfo.Tag != names.NewMachineTag(machineId) { return nil, errors.New("entity tag must match started machine") } if args.InstanceConfig.APIInfo.Tag != names.NewMachineTag(machineId) { return nil, errors.New("entity tag must match started machine") } logger.Infof("would pick tools from %s", args.Tools) series := args.Tools.OneSeries() idString := fmt.Sprintf("%s-%d", e.name, estate.maxId) addrs := network.NewAddresses(idString+".dns", "127.0.0.1") if estate.preferIPv6 { addrs = append(addrs, network.NewAddress(fmt.Sprintf("fc00::%x", estate.maxId+1))) } logger.Debugf("StartInstance addresses: %v", addrs) i := &dummyInstance{ id: instance.Id(idString), addresses: addrs, ports: make(map[network.PortRange]bool), machineId: machineId, series: series, firewallMode: e.Config().FirewallMode(), state: estate, } var hc *instance.HardwareCharacteristics // To match current system capability, only provide hardware characteristics for // environ machines, not containers. if state.ParentId(machineId) == "" { // We will just assume the instance hardware characteristics exactly matches // the supplied constraints (if specified). hc = &instance.HardwareCharacteristics{ Arch: args.Constraints.Arch, Mem: args.Constraints.Mem, RootDisk: args.Constraints.RootDisk, CpuCores: args.Constraints.CpuCores, CpuPower: args.Constraints.CpuPower, Tags: args.Constraints.Tags, } // Fill in some expected instance hardware characteristics if constraints not specified. if hc.Arch == nil { arch := "amd64" hc.Arch = &arch } if hc.Mem == nil { mem := uint64(1024) hc.Mem = &mem } if hc.RootDisk == nil { disk := uint64(8192) hc.RootDisk = &disk } if hc.CpuCores == nil { cores := uint64(1) hc.CpuCores = &cores } } // Simulate subnetsToZones gets populated when spaces given in constraints. spaces := args.Constraints.IncludeSpaces() var subnetsToZones map[network.Id][]string for isp := range spaces { // Simulate 2 subnets per space. if subnetsToZones == nil { subnetsToZones = make(map[network.Id][]string) } for isn := 0; isn < 2; isn++ { providerId := fmt.Sprintf("subnet-%d", isp+isn) zone := fmt.Sprintf("zone%d", isp+isn) subnetsToZones[network.Id(providerId)] = []string{zone} } } // Simulate creating volumes when requested. volumes := make([]storage.Volume, len(args.Volumes)) for iv, v := range args.Volumes { persistent, _ := v.Attributes["persistent"].(bool) volumes[iv] = storage.Volume{ Tag: names.NewVolumeTag(strconv.Itoa(iv + 1)), VolumeInfo: storage.VolumeInfo{ Size: v.Size, Persistent: persistent, }, } } estate.insts[i.id] = i estate.maxId++ estate.ops <- OpStartInstance{ Env: e.name, MachineId: machineId, MachineNonce: args.InstanceConfig.MachineNonce, PossibleTools: args.Tools, Constraints: args.Constraints, SubnetsToZones: subnetsToZones, Volumes: volumes, Instance: i, Jobs: args.InstanceConfig.Jobs, Info: args.InstanceConfig.MongoInfo, APIInfo: args.InstanceConfig.APIInfo, AgentEnvironment: args.InstanceConfig.AgentEnvironment, Secret: e.ecfg().secret(), } return &environs.StartInstanceResult{ Instance: i, Hardware: hc, }, nil }