Exemple #1
0
func (s *configureSuite) getCloudConfig(c *gc.C, stateServer bool, vers version.Binary) cloudinit.CloudConfig {
	var icfg *instancecfg.InstanceConfig
	var err error
	if stateServer {
		icfg, err = instancecfg.NewBootstrapInstanceConfig(constraints.Value{}, vers.Series)
		c.Assert(err, jc.ErrorIsNil)
		icfg.InstanceId = "instance-id"
		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobManageEnviron, multiwatcher.JobHostUnits}
	} else {
		icfg, err = instancecfg.NewInstanceConfig("0", "ya", imagemetadata.ReleasedStream, vers.Series, true, nil, nil, nil)
		c.Assert(err, jc.ErrorIsNil)
		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobHostUnits}
	}
	icfg.Tools = &tools.Tools{
		Version: vers,
		URL:     "http://testing.invalid/tools.tar.gz",
	}
	environConfig := testConfig(c, stateServer, vers)
	err = instancecfg.FinishInstanceConfig(icfg, environConfig)
	c.Assert(err, jc.ErrorIsNil)
	cloudcfg, err := cloudinit.New(icfg.Series)
	c.Assert(err, jc.ErrorIsNil)
	udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg)
	c.Assert(err, jc.ErrorIsNil)
	err = udata.Configure()
	c.Assert(err, jc.ErrorIsNil)
	return cloudcfg
}
Exemple #2
0
func (s *CloudInitSuite) TestWindowsUserdataEncoding(c *gc.C) {
	series := "win8"
	metricsSpoolDir := must(paths.MetricsSpoolDir("win8"))
	toolsList := tools.List{
		&tools.Tools{
			URL:     "http://foo.com/tools/released/juju1.2.3-win8-amd64.tgz",
			Version: version.MustParseBinary("1.2.3-win8-amd64"),
			Size:    10,
			SHA256:  "1234",
		},
	}
	dataDir, err := paths.DataDir(series)
	c.Assert(err, jc.ErrorIsNil)
	logDir, err := paths.LogDir(series)
	c.Assert(err, jc.ErrorIsNil)

	cfg := instancecfg.InstanceConfig{
		ControllerTag:    testing.ControllerTag,
		MachineId:        "10",
		AgentEnvironment: map[string]string{agent.ProviderType: "dummy"},
		Series:           series,
		Jobs:             []multiwatcher.MachineJob{multiwatcher.JobHostUnits},
		MachineNonce:     "FAKE_NONCE",
		APIInfo: &api.Info{
			Addrs:    []string{"state-addr.testing.invalid:54321"},
			Password: "******",
			CACert:   "CA CERT\n" + testing.CACert,
			Tag:      names.NewMachineTag("10"),
			ModelTag: testing.ModelTag,
		},
		MachineAgentServiceName: "jujud-machine-10",
		DataDir:                 dataDir,
		LogDir:                  path.Join(logDir, "juju"),
		MetricsSpoolDir:         metricsSpoolDir,
		CloudInitOutputLog:      path.Join(logDir, "cloud-init-output.log"),
	}
	err = cfg.SetTools(toolsList)
	c.Assert(err, jc.ErrorIsNil)

	ci, err := cloudinit.New("win8")
	c.Assert(err, jc.ErrorIsNil)

	udata, err := cloudconfig.NewUserdataConfig(&cfg, ci)
	c.Assert(err, jc.ErrorIsNil)

	err = udata.Configure()
	c.Assert(err, jc.ErrorIsNil)

	data, err := ci.RenderYAML()
	c.Assert(err, jc.ErrorIsNil)

	cicompose, err := cloudinit.New("win8")
	c.Assert(err, jc.ErrorIsNil)

	base64Data := base64.StdEncoding.EncodeToString(utils.Gzip(data))
	got := []byte(fmt.Sprintf(cloudconfig.UserDataScript, base64Data))
	expected, err := providerinit.ComposeUserData(&cfg, cicompose, openstack.OpenstackRenderer{})
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(string(got), gc.Equals, string(expected))
}
Exemple #3
0
func (*instancecfgSuite) TestAgentVersion(c *gc.C) {
	var icfg instancecfg.InstanceConfig
	list := coretools.List{
		&coretools.Tools{Version: version.MustParseBinary("2.3.4-trusty-amd64")},
	}
	err := icfg.SetTools(list)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(icfg.AgentVersion(), gc.Equals, list[0].Version)
}
Exemple #4
0
func (*instancecfgSuite) TestSetToolsDifferentVersions(c *gc.C) {
	var icfg instancecfg.InstanceConfig
	list := coretools.List{
		&coretools.Tools{Version: version.MustParseBinary("2.3.4-trusty-amd64")},
		&coretools.Tools{Version: version.MustParseBinary("2.3.5-trusty-amd64")},
	}
	err := icfg.SetTools(list)
	c.Assert(err, gc.ErrorMatches, `tools info mismatch.*2\.3\.4.*2\.3\.5.*`)
	c.Assert(icfg.ToolsList(), gc.HasLen, 0)
}
Exemple #5
0
func (*instancecfgSuite) TestSetToolsSameVersions(c *gc.C) {
	var icfg instancecfg.InstanceConfig
	list := coretools.List{
		&coretools.Tools{Version: version.MustParseBinary("2.3.4-trusty-amd64")},
		&coretools.Tools{Version: version.MustParseBinary("2.3.4-trusty-amd64")},
	}
	err := icfg.SetTools(list)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(icfg.ToolsList(), jc.DeepEquals, list)
}
Exemple #6
0
func assocProvInfoAndMachCfg(
	provInfo *params.ProvisioningInfo,
	instanceConfig *instancecfg.InstanceConfig,
) *provisioningInfo {

	instanceConfig.Tags = provInfo.Tags

	if len(provInfo.Jobs) > 0 {
		instanceConfig.Jobs = provInfo.Jobs
	}

	return &provisioningInfo{
		Constraints:    provInfo.Constraints,
		Series:         provInfo.Series,
		Placement:      provInfo.Placement,
		InstanceConfig: instanceConfig,
		SubnetsToZones: provInfo.SubnetsToZones,
	}
}
Exemple #7
0
func (s *configureSuite) getCloudConfig(c *gc.C, controller bool, vers version.Binary) cloudinit.CloudConfig {
	var icfg *instancecfg.InstanceConfig
	var err error
	modelConfig := testConfig(c, controller, vers)
	if controller {
		icfg, err = instancecfg.NewBootstrapInstanceConfig(
			coretesting.FakeControllerConfig(),
			constraints.Value{}, constraints.Value{},
			vers.Series, "",
		)
		c.Assert(err, jc.ErrorIsNil)
		icfg.APIInfo = &api.Info{
			Password: "******",
			CACert:   coretesting.CACert,
			ModelTag: coretesting.ModelTag,
		}
		icfg.Controller.MongoInfo = &mongo.MongoInfo{
			Password: "******", Info: mongo.Info{CACert: coretesting.CACert},
		}
		icfg.Bootstrap.ControllerModelConfig = modelConfig
		icfg.Bootstrap.BootstrapMachineInstanceId = "instance-id"
		icfg.Bootstrap.HostedModelConfig = map[string]interface{}{
			"name": "hosted-model",
		}
		icfg.Bootstrap.StateServingInfo = params.StateServingInfo{
			Cert:         coretesting.ServerCert,
			PrivateKey:   coretesting.ServerKey,
			CAPrivateKey: coretesting.CAKey,
			StatePort:    123,
			APIPort:      456,
		}
		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobManageModel, multiwatcher.JobHostUnits}
		icfg.Bootstrap.StateServingInfo = params.StateServingInfo{
			Cert:         coretesting.ServerCert,
			PrivateKey:   coretesting.ServerKey,
			CAPrivateKey: coretesting.CAKey,
			StatePort:    123,
			APIPort:      456,
		}
	} else {
		icfg, err = instancecfg.NewInstanceConfig(coretesting.ControllerTag, "0", "ya", imagemetadata.ReleasedStream, vers.Series, nil)
		c.Assert(err, jc.ErrorIsNil)
		icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobHostUnits}
	}
	err = icfg.SetTools(tools.List{
		&tools.Tools{
			Version: vers,
			URL:     "http://testing.invalid/tools.tar.gz",
		},
	})
	err = instancecfg.FinishInstanceConfig(icfg, modelConfig)
	c.Assert(err, jc.ErrorIsNil)
	cloudcfg, err := cloudinit.New(icfg.Series)
	c.Assert(err, jc.ErrorIsNil)
	udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg)
	c.Assert(err, jc.ErrorIsNil)
	err = udata.Configure()
	c.Assert(err, jc.ErrorIsNil)
	return cloudcfg
}
Exemple #8
0
func (*instancecfgSuite) TestAgentVersionZero(c *gc.C) {
	var icfg instancecfg.InstanceConfig
	c.Assert(icfg.AgentVersion(), gc.Equals, version.Binary{})
}
Exemple #9
0
// finishBootstrap converts the machine config to cloud-config,
// converts that to a script, and then executes it locally.
func (env *localEnviron) finishBootstrap(ctx environs.BootstrapContext, icfg *instancecfg.InstanceConfig) error {
	icfg.InstanceId = bootstrapInstanceId
	icfg.DataDir = env.config.rootDir()
	icfg.LogDir = fmt.Sprintf("/var/log/juju-%s", env.config.namespace())
	icfg.CloudInitOutputLog = filepath.Join(icfg.DataDir, "cloud-init-output.log")

	// No JobManageNetworking added in order not to change the network
	// configuration of the user's machine.
	icfg.Jobs = []multiwatcher.MachineJob{multiwatcher.JobManageEnviron}

	icfg.MachineAgentServiceName = env.machineAgentServiceName()
	icfg.AgentEnvironment = map[string]string{
		agent.Namespace: env.config.namespace(),
		agent.LxcBridge: env.config.networkBridge(),

		// The local provider only supports a single state server,
		// so we make the oplog size to a small value. This makes
		// the preallocation faster with no disadvantage.
		agent.MongoOplogSize: "1", // 1MB
	}

	if err := instancecfg.FinishInstanceConfig(icfg, env.Config()); err != nil {
		return errors.Trace(err)
	}

	// Since Juju's state machine is currently the host machine
	// for local providers, don't stomp on it.
	cfgAttrs := env.config.AllAttrs()
	if val, ok := cfgAttrs["enable-os-refresh-update"].(bool); !ok {
		logger.Infof("local provider; disabling refreshing OS updates.")
		icfg.EnableOSRefreshUpdate = false
	} else {
		icfg.EnableOSRefreshUpdate = val
	}
	if val, ok := cfgAttrs["enable-os-upgrade"].(bool); !ok {
		logger.Infof("local provider; disabling OS upgrades.")
		icfg.EnableOSUpgrade = false
	} else {
		icfg.EnableOSUpgrade = val
	}

	// don't write proxy or mirror settings for local machine
	icfg.AptProxySettings = proxy.Settings{}
	icfg.ProxySettings = proxy.Settings{}
	icfg.AptMirror = ""

	cloudcfg, err := cloudinit.New(icfg.Series)
	if err != nil {
		return errors.Trace(err)
	}
	cloudcfg.SetSystemUpdate(icfg.EnableOSRefreshUpdate)
	cloudcfg.SetSystemUpgrade(icfg.EnableOSUpgrade)

	localLogDir := filepath.Join(icfg.DataDir, "log")
	if err := os.RemoveAll(localLogDir); err != nil {
		return errors.Trace(err)
	}
	if err := symlink.New(icfg.LogDir, localLogDir); err != nil {
		return errors.Trace(err)
	}
	if err := os.Remove(icfg.CloudInitOutputLog); err != nil && !os.IsNotExist(err) {
		return errors.Trace(err)
	}
	cloudcfg.AddScripts(
		fmt.Sprintf("rm -fr %s", icfg.LogDir),
	)
	udata, err := cloudconfig.NewUserdataConfig(icfg, cloudcfg)
	if err != nil {
		return errors.Trace(err)
	}
	if err := udata.ConfigureJuju(); err != nil {
		return errors.Trace(err)
	}
	return executeCloudConfig(ctx, icfg, cloudcfg)
}
Exemple #10
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
}
Exemple #11
0
func (manager *containerManager) CreateContainer(
	instanceConfig *instancecfg.InstanceConfig,
	series string,
	networkConfig *container.NetworkConfig,
	storageConfig *container.StorageConfig,
) (instance.Instance, *instance.HardwareCharacteristics, error) {

	name := names.NewMachineTag(instanceConfig.MachineId).String()
	if manager.name != "" {
		name = fmt.Sprintf("%s-%s", manager.name, name)
	}

	// Set the MachineContainerHostname to match the name returned by virsh list
	instanceConfig.MachineContainerHostname = 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, 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(instanceConfig.Constraints)
	startParams.Arch = version.Current.Arch
	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 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", instanceConfig.Constraints)
	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
}
Exemple #12
0
func finalizeInstanceBootstrapConfig(
	ctx environs.BootstrapContext,
	icfg *instancecfg.InstanceConfig,
	args BootstrapParams,
	cfg *config.Config,
	customImageMetadata []*imagemetadata.ImageMetadata,
) error {
	if icfg.APIInfo != nil || icfg.Controller.MongoInfo != nil {
		return errors.New("machine configuration already has api/state info")
	}
	controllerCfg := icfg.Controller.Config
	caCert, hasCACert := controllerCfg.CACert()
	if !hasCACert {
		return errors.New("controller configuration has no ca-cert")
	}
	icfg.APIInfo = &api.Info{
		Password: args.AdminSecret,
		CACert:   caCert,
		ModelTag: names.NewModelTag(cfg.UUID()),
	}
	icfg.Controller.MongoInfo = &mongo.MongoInfo{
		Password: args.AdminSecret,
		Info:     mongo.Info{CACert: caCert},
	}

	// These really are directly relevant to running a controller.
	// Initially, generate a controller certificate with no host IP
	// addresses in the SAN field. Once the controller is up and the
	// NIC addresses become known, the certificate can be regenerated.
	cert, key, err := controller.GenerateControllerCertAndKey(caCert, args.CAPrivateKey, nil)
	if err != nil {
		return errors.Annotate(err, "cannot generate controller certificate")
	}
	icfg.Bootstrap.StateServingInfo = params.StateServingInfo{
		StatePort:    controllerCfg.StatePort(),
		APIPort:      controllerCfg.APIPort(),
		Cert:         string(cert),
		PrivateKey:   string(key),
		CAPrivateKey: args.CAPrivateKey,
	}
	if _, ok := cfg.AgentVersion(); !ok {
		return errors.New("controller model configuration has no agent-version")
	}

	icfg.Bootstrap.ControllerModelConfig = cfg
	icfg.Bootstrap.CustomImageMetadata = customImageMetadata
	icfg.Bootstrap.ControllerCloudName = args.CloudName
	icfg.Bootstrap.ControllerCloud = args.Cloud
	icfg.Bootstrap.ControllerCloudRegion = args.CloudRegion
	icfg.Bootstrap.ControllerCloudCredential = args.CloudCredential
	icfg.Bootstrap.ControllerCloudCredentialName = args.CloudCredentialName
	icfg.Bootstrap.ControllerConfig = args.ControllerConfig
	icfg.Bootstrap.ControllerInheritedConfig = args.ControllerInheritedConfig
	icfg.Bootstrap.RegionInheritedConfig = args.Cloud.RegionConfig
	icfg.Bootstrap.HostedModelConfig = args.HostedModelConfig
	icfg.Bootstrap.Timeout = args.DialOpts.Timeout
	icfg.Bootstrap.GUI = guiArchive(args.GUIDataSourceBaseURL, func(msg string) {
		ctx.Infof(msg)
	})
	return nil
}