func (s *toolsSuite) testFindToolsExact(c *gc.C, t common.ToolsStorageGetter, inStorage bool, develVersion bool) { var called bool s.PatchValue(common.EnvtoolsFindTools, func(e environs.Environ, major, minor int, stream string, filter coretools.Filter) (list coretools.List, err error) { called = true c.Assert(filter.Number, gc.Equals, version.Current) c.Assert(filter.Series, gc.Equals, series.HostSeries()) c.Assert(filter.Arch, gc.Equals, arch.HostArch()) if develVersion { c.Assert(stream, gc.Equals, "devel") } else { c.Assert(stream, gc.Equals, "released") } return nil, errors.NotFoundf("tools") }) toolsFinder := common.NewToolsFinder(s.State, t, sprintfURLGetter("tools:%s")) result, err := toolsFinder.FindTools(params.FindToolsParams{ Number: version.Current, MajorVersion: -1, MinorVersion: -1, Series: series.HostSeries(), Arch: arch.HostArch(), }) c.Assert(err, jc.ErrorIsNil) if inStorage { c.Assert(result.Error, gc.IsNil) c.Assert(called, jc.IsFalse) } else { c.Assert(result.Error, gc.ErrorMatches, "tools not found") c.Assert(called, jc.IsTrue) } }
// DefaultVersions returns a slice of unique 'versions' for the current // environment's preferred series and host architecture, as well supported LTS // series for the host architecture. Additionally, it ensures that 'versions' // for amd64 are returned if that is not the current host's architecture. func DefaultVersions(conf *config.Config) []version.Binary { var versions []version.Binary supported := series.SupportedLts() defaultSeries := set.NewStrings(supported...) defaultSeries.Add(config.PreferredSeries(conf)) defaultSeries.Add(series.HostSeries()) agentVersion, set := conf.AgentVersion() if !set { agentVersion = jujuversion.Current } for _, s := range defaultSeries.Values() { versions = append(versions, version.Binary{ Number: agentVersion, Arch: arch.HostArch(), Series: s, }) if arch.HostArch() != "amd64" { versions = append(versions, version.Binary{ Number: agentVersion, Arch: "amd64", Series: s, }) } } return versions }
func (env *environ) finishInstanceConfig(args environs.StartInstanceParams) error { // TODO(natefinch): This is only correct so long as the lxd is running on // the local machine. If/when we support a remote lxd environment, we'll // need to change this to match the arch of the remote machine. tools, err := args.Tools.Match(tools.Filter{Arch: arch.HostArch()}) if err != nil { return errors.Trace(err) } if len(tools) == 0 { return errors.Errorf("No tools available for architecture %q", arch.HostArch()) } if err := args.InstanceConfig.SetTools(tools); err != nil { return errors.Trace(err) } logger.Debugf("tools: %#v", args.InstanceConfig.ToolsList()) if err := instancecfg.FinishInstanceConfig(args.InstanceConfig, env.ecfg.Config); err != nil { return errors.Trace(err) } // TODO: evaluate the impact of setting the constraints on the // instanceConfig for all machines rather than just controller nodes. // This limitation is why the constraints are assigned directly here. args.InstanceConfig.Constraints = args.Constraints args.InstanceConfig.AgentEnvironment[agent.Namespace] = env.ecfg.namespace() return nil }
// Bootstrap is specified in the Environ interface. func (env *localEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) (*environs.BootstrapResult, error) { if err := ensureNotRoot(); err != nil { return nil, err } // Make sure there are tools available for the // host's architecture and series. if _, err := args.AvailableTools.Match(tools.Filter{ Arch: arch.HostArch(), Series: series.HostSeries(), }); err != nil { return nil, err } cfg, err := env.Config().Apply(map[string]interface{}{ // Record the bootstrap IP, so the containers know where to go for storage. "bootstrap-ip": env.bridgeAddress, }) if err == nil { err = env.SetConfig(cfg) } if err != nil { logger.Errorf("failed to apply bootstrap-ip to config: %v", err) return nil, err } result := &environs.BootstrapResult{ Arch: arch.HostArch(), Series: series.HostSeries(), Finalize: env.finishBootstrap, } return result, nil }
func (s *localJujuTestSuite) testBootstrap(c *gc.C, cfg *config.Config) environs.Environ { ctx := envtesting.BootstrapContext(c) environ, err := local.Provider.PrepareForBootstrap(ctx, cfg) c.Assert(err, jc.ErrorIsNil) availableTools := coretools.List{&coretools.Tools{ Version: version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), }, URL: "http://testing.invalid/tools.tar.gz", }} result, err := environ.Bootstrap(ctx, environs.BootstrapParams{ AvailableTools: availableTools, }) c.Assert(err, jc.ErrorIsNil) icfg, err := instancecfg.NewBootstrapInstanceConfig( constraints.Value{}, constraints.Value{}, "quantal", "", ) c.Assert(err, jc.ErrorIsNil) icfg.Tools = availableTools[0] err = result.Finalize(ctx, icfg) c.Assert(err, jc.ErrorIsNil) return environ }
func (s *ContainerSetupSuite) TestLxcContainerUsesImageURL(c *gc.C) { // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) c.Assert(err, jc.ErrorIsNil) err = m.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.KVM}) c.Assert(err, jc.ErrorIsNil) current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } err = m.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) brokerCalled := false newlxcbroker := func(api provisioner.APICalls, agentConfig agent.Config, managerConfig container.ManagerConfig, imageURLGetter container.ImageURLGetter, enableNAT bool, defaultMTU int) (environs.InstanceBroker, error) { imageURL, err := imageURLGetter.ImageURL(instance.LXC, "trusty", "amd64") c.Assert(err, jc.ErrorIsNil) c.Assert(imageURL, gc.Equals, "imageURL") c.Assert(imageURLGetter.CACert(), gc.DeepEquals, []byte("cert")) brokerCalled = true return nil, fmt.Errorf("lxc broker error") } s.PatchValue(&provisioner.NewLxcBroker, newlxcbroker) s.createContainer(c, m, instance.LXC) c.Assert(brokerCalled, jc.IsTrue) }
func (s *UpgradeSuite) SetUpTest(c *gc.C) { s.StateSuite.SetUpTest(c) s.preUpgradeError = false // Most of these tests normally finish sub-second on a fast machine. // If any given test hits a minute, we have almost certainly become // wedged, so dump the logs. coretesting.DumpTestLogsAfter(time.Minute, c, s) s.oldVersion = version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } s.oldVersion.Major = 1 s.oldVersion.Minor = 16 // Don't wait so long in tests. s.PatchValue(&UpgradeStartTimeoutMaster, time.Duration(time.Millisecond*50)) s.PatchValue(&UpgradeStartTimeoutSecondary, time.Duration(time.Millisecond*60)) // Allow tests to make the API connection appear to be dead. s.connectionDead = false s.PatchValue(&cmdutil.ConnectionIsDead, func(loggo.Logger, cmdutil.Pinger) bool { return s.connectionDead }) s.machineIsMaster = true fakeIsMachineMaster := func(*state.State, string) (bool, error) { return s.machineIsMaster, nil } s.PatchValue(&IsMachineMaster, fakeIsMachineMaster) }
// validateUploadAllowed returns an error if an attempt to upload tools should // not be allowed. func validateUploadAllowed(env environs.Environ, toolsArch, toolsSeries *string, validator constraints.Validator) error { // Now check that the architecture and series for which we are setting up an // environment matches that from which we are bootstrapping. hostArch := arch.HostArch() // We can't build tools for a different architecture if one is specified. if toolsArch != nil && *toolsArch != hostArch { return fmt.Errorf("cannot use agent built for %q using a machine running on %q", *toolsArch, hostArch) } hostOS := jujuos.HostOS() if toolsSeries != nil { toolsSeriesOS, err := series.GetOSFromSeries(*toolsSeries) if err != nil { return errors.Trace(err) } if !toolsSeriesOS.EquivalentTo(hostOS) { return errors.Errorf("cannot use agent built for %q using a machine running %q", *toolsSeries, hostOS) } } // If no architecture is specified, ensure the target provider supports instances matching our architecture. if _, err := validator.Validate(constraints.Value{Arch: &hostArch}); err != nil { return errors.Errorf( "model %q of type %s does not support instances running on %q", env.Config().Name(), env.Config().Type(), hostArch, ) } return nil }
func (s *BootstrapSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.PatchValue(&sshGenerateKey, func(name string) (string, string, error) { return "private-key", "public-key", nil }) s.MgoSuite.SetUpTest(c) s.dataDir = c.MkDir() s.logDir = c.MkDir() s.mongoOplogSize = "1234" s.fakeEnsureMongo = agenttesting.InstallFakeEnsureMongo(s) s.PatchValue(&maybeInitiateMongoServer, s.fakeEnsureMongo.InitiateMongo) // Create fake tools.tar.gz and downloaded-tools.txt. current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } toolsDir := filepath.FromSlash(agenttools.SharedToolsDir(s.dataDir, current)) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(filepath.Join(toolsDir, "tools.tar.gz"), nil, 0644) c.Assert(err, jc.ErrorIsNil) s.writeDownloadedTools(c, &tools.Tools{Version: current}) }
func (factory *Factory) makeMachineReturningPassword(c *gc.C, params *MachineParams, setProvisioned bool) (*state.Machine, string) { machineTemplate := state.MachineTemplate{ Series: params.Series, Jobs: params.Jobs, Volumes: params.Volumes, Filesystems: params.Filesystems, Constraints: params.Constraints, } machine, err := factory.st.AddOneMachine(machineTemplate) c.Assert(err, jc.ErrorIsNil) if setProvisioned { err = machine.SetProvisioned(params.InstanceId, params.Nonce, params.Characteristics) c.Assert(err, jc.ErrorIsNil) } err = machine.SetPassword(params.Password) c.Assert(err, jc.ErrorIsNil) if len(params.Addresses) > 0 { err := machine.SetProviderAddresses(params.Addresses...) c.Assert(err, jc.ErrorIsNil) } current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } err = machine.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) return machine, params.Password }
// MakeMachineNested will make a machine nested in the machine with ID given. func (factory *Factory) MakeMachineNested(c *gc.C, parentId string, params *MachineParams) *state.Machine { params = factory.paramsFillDefaults(c, params) machineTemplate := state.MachineTemplate{ Series: params.Series, Jobs: params.Jobs, Volumes: params.Volumes, Filesystems: params.Filesystems, Constraints: params.Constraints, } m, err := factory.st.AddMachineInsideMachine( machineTemplate, parentId, instance.LXD, ) c.Assert(err, jc.ErrorIsNil) err = m.SetProvisioned(params.InstanceId, params.Nonce, params.Characteristics) c.Assert(err, jc.ErrorIsNil) current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } err = m.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) return m }
func (s *upgradeSuite) SetUpTest(c *gc.C) { s.AgentSuite.SetUpTest(c) s.oldVersion = version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } s.oldVersion.Major = 1 s.oldVersion.Minor = 16 // Don't wait so long in tests. s.PatchValue(&upgradesteps.UpgradeStartTimeoutMaster, time.Duration(time.Millisecond*50)) s.PatchValue(&upgradesteps.UpgradeStartTimeoutSecondary, time.Duration(time.Millisecond*60)) // Ensure we don't fail disk space check. s.PatchValue(&upgrades.MinDiskSpaceMib, uint64(0)) // Consume apt-get commands that get run before upgrades. aptCmds := s.AgentSuite.HookCommandOutput(&pacman.CommandOutput, nil, nil) go func() { for _ = range aptCmds { } }() // TODO(mjs) - the following should maybe be part of AgentSuite.SetUpTest() s.PatchValue(&cmdutil.EnsureMongoServer, func(mongo.EnsureServerParams) error { return nil }) s.PatchValue(&agentcmd.ProductionMongoWriteConcern, false) }
func (s *BootstrapSuite) TestMissingToolsUploadFailedError(c *gc.C) { buildToolsTarballAlwaysFails := func(forceVersion *version.Number, stream string) (*sync.BuiltTools, error) { return nil, fmt.Errorf("an error") } s.setupAutoUploadTest(c, "1.7.3", "precise") s.PatchValue(&sync.BuildToolsTarball, buildToolsTarballAlwaysFails) ctx, err := coretesting.RunCommand( c, s.newBootstrapCommand(), "devcontroller", "dummy-cloud/region-1", "--config", "default-series=raring", "--config", "agent-stream=proposed", "--auto-upgrade", ) c.Check(coretesting.Stderr(ctx), gc.Equals, fmt.Sprintf(` Creating Juju controller "local.devcontroller" on dummy-cloud/region-1 Bootstrapping model "admin" Starting new instance for initial controller Building tools to upload (1.7.3.1-raring-%s) `[1:], arch.HostArch())) c.Check(err, gc.ErrorMatches, "failed to bootstrap model: cannot upload bootstrap tools: an error") }
func (s *MachineSuite) assertAgentSetsToolsVersion(c *gc.C, job state.MachineJob) { vers := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } vers.Minor++ m, _, _ := s.primeAgentVersion(c, vers, job) a := s.newAgent(c, m) go func() { c.Check(a.Run(nil), jc.ErrorIsNil) }() defer func() { c.Check(a.Stop(), jc.ErrorIsNil) }() timeout := time.After(coretesting.LongWait) for done := false; !done; { select { case <-timeout: c.Fatalf("timeout while waiting for agent version to be set") case <-time.After(coretesting.ShortWait): c.Log("Refreshing") err := m.Refresh() c.Assert(err, jc.ErrorIsNil) c.Log("Fetching agent tools") agentTools, err := m.AgentTools() c.Assert(err, jc.ErrorIsNil) c.Logf("(%v vs. %v)", agentTools.Version, jujuversion.Current) if agentTools.Version.Minor != jujuversion.Current.Minor { continue } c.Assert(agentTools.Version.Number, gc.DeepEquals, jujuversion.Current) done = true } } }
func createContainer(c *gc.C, manager container.Manager, machineId string) instance.Instance { machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) instanceConfig, err := instancecfg.NewInstanceConfig(machineId, machineNonce, imagemetadata.ReleasedStream, "quantal", "", true, stateInfo, apiInfo) c.Assert(err, jc.ErrorIsNil) network := container.BridgeNetworkConfig("virbr0", 0, nil) err = instanceConfig.SetTools(tools.List{ &tools.Tools{ Version: version.MustParseBinary("2.3.4-foo-bar"), URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", }, }) c.Assert(err, jc.ErrorIsNil) environConfig := dummyConfig(c) err = instancecfg.FinishInstanceConfig(instanceConfig, environConfig) c.Assert(err, jc.ErrorIsNil) callback := func(settableStatus status.Status, info string, data map[string]interface{}) error { return nil } inst, hardware, err := manager.CreateContainer(instanceConfig, "precise", network, nil, callback) c.Assert(err, jc.ErrorIsNil) c.Assert(hardware, gc.NotNil) expected := fmt.Sprintf("arch=%s cpu-cores=1 mem=512M root-disk=8192M", arch.HostArch()) c.Assert(hardware.String(), gc.Equals, expected) return inst }
func (s *LXCDefaultMTUSuite) TestDefaultMTUPropagatedToNewLXCBroker(c *gc.C) { // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ Series: coretesting.FakeDefaultSeries, Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) c.Assert(err, jc.ErrorIsNil) err = m.SetSupportedContainers([]instance.ContainerType{instance.LXC, instance.KVM}) c.Assert(err, jc.ErrorIsNil) current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } err = m.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) brokerCalled := false newlxcbroker := func(api provisioner.APICalls, agentConfig agent.Config, managerConfig container.ManagerConfig, imageURLGetter container.ImageURLGetter, enableNAT bool, defaultMTU int) (environs.InstanceBroker, error) { brokerCalled = true c.Assert(defaultMTU, gc.Equals, 9000) return nil, fmt.Errorf("lxc broker error") } s.PatchValue(&provisioner.NewLxcBroker, newlxcbroker) s.createContainer(c, m, instance.LXC) c.Assert(brokerCalled, jc.IsTrue) }
func (s *ContainerSetupSuite) TestContainerInitLockError(c *gc.C) { m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ Series: coretesting.FakeDefaultSeries, Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) c.Assert(err, jc.ErrorIsNil) current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } err = m.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) err = os.RemoveAll(s.initLockDir) c.Assert(err, jc.ErrorIsNil) handler, runner := s.setupContainerWorker(c, m.Tag().(names.MachineTag)) runner.Kill() err = runner.Wait() c.Assert(err, jc.ErrorIsNil) _, err = handler.SetUp() c.Assert(err, jc.ErrorIsNil) err = handler.Handle([]string{"0/lxc/0"}) c.Assert(err, gc.ErrorMatches, ".*failed to acquire initialization lock:.*") }
func (s *UnitSuite) TestUpgrade(c *gc.C) { machine, unit, _, currentTools := s.primeAgent(c) agent := s.newAgent(c, unit) newVers := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } newVers.Patch++ envtesting.AssertUploadFakeToolsVersions( c, s.DefaultToolsStorage, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), newVers) // The machine agent downloads the tools; fake this by // creating downloaded-tools.txt in data-dir/tools/<version>. toolsDir := agenttools.SharedToolsDir(s.DataDir(), newVers) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) toolsPath := filepath.Join(toolsDir, "downloaded-tools.txt") testTools := tools.Tools{Version: newVers, URL: "http://testing.invalid/tools"} data, err := json.Marshal(testTools) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(toolsPath, data, 0644) c.Assert(err, jc.ErrorIsNil) // Set the machine agent version to trigger an upgrade. err = machine.SetAgentVersion(newVers) c.Assert(err, jc.ErrorIsNil) err = runWithTimeout(agent) envtesting.CheckUpgraderReadyError(c, err, &upgrader.UpgradeReadyError{ AgentName: unit.Tag().String(), OldTools: currentTools.Version, NewTools: newVers, DataDir: s.DataDir(), }) }
func (suite *maas2EnvironSuite) TestStartInstanceParams(c *gc.C) { var env *maasEnviron suite.injectController(&fakeController{ allocateMachineArgsCheck: func(args gomaasapi.AllocateMachineArgs) { c.Assert(args, gc.DeepEquals, gomaasapi.AllocateMachineArgs{ AgentName: env.ecfg().maasAgentName(), Zone: "foo", MinMemory: 8192, }) }, allocateMachine: newFakeMachine("Bruce Sterling", arch.HostArch(), ""), allocateMachineMatches: gomaasapi.ConstraintMatches{ Storage: map[string][]gomaasapi.BlockDevice{}, }, zones: []gomaasapi.Zone{&fakeZone{name: "foo"}}, }) suite.setupFakeTools(c) env = suite.makeEnviron(c, nil) params := environs.StartInstanceParams{ Placement: "zone=foo", Constraints: constraints.MustParse("mem=8G"), } result, err := testing.StartInstanceWithParams(env, "1", params) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Instance.Id(), gc.Equals, instance.Id("Bruce Sterling")) }
func (s *upgraderSuite) TestToolsForAgent(c *gc.C) { current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } agent := params.Entity{Tag: s.rawMachine.Tag().String()} // The machine must have its existing tools set before we query for the // next tools. This is so that we can grab Arch and Series without // having to pass it in again err := s.rawMachine.SetAgentVersion(current) c.Assert(err, jc.ErrorIsNil) args := params.Entities{Entities: []params.Entity{agent}} results, err := s.upgrader.Tools(args) c.Assert(err, jc.ErrorIsNil) assertTools := func() { c.Check(results.Results, gc.HasLen, 1) c.Assert(results.Results[0].Error, gc.IsNil) agentTools := results.Results[0].ToolsList[0] url := fmt.Sprintf("https://%s/model/%s/tools/%s", s.APIState.Addr(), coretesting.ModelTag.Id(), current) c.Check(agentTools.URL, gc.Equals, url) c.Check(agentTools.Version, gc.DeepEquals, current) } assertTools() }
// validateUploadAllowed returns an error if an attempt to upload tools should // not be allowed. func validateUploadAllowed(env environs.Environ, toolsArch *string) error { // Now check that the architecture for which we are setting up an // environment matches that from which we are bootstrapping. hostArch := arch.HostArch() // We can't build tools for a different architecture if one is specified. if toolsArch != nil && *toolsArch != hostArch { return fmt.Errorf("cannot build tools for %q using a machine running on %q", *toolsArch, hostArch) } // If no architecture is specified, ensure the target provider supports instances matching our architecture. supportedArchitectures, err := env.SupportedArchitectures() if err != nil { return fmt.Errorf( "no packaged tools available and cannot determine environment's supported architectures: %v", err) } archSupported := false for _, arch := range supportedArchitectures { if hostArch == arch { archSupported = true break } } if !archSupported { envType := env.Config().Type() return errors.Errorf("environment %q of type %s does not support instances running on %q", env.Config().Name(), envType, hostArch) } return nil }
func (s *upgraderSuite) TestSetTools(c *gc.C) { current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } _, err := s.rawMachine.AgentTools() c.Assert(err, jc.Satisfies, errors.IsNotFound) args := params.EntitiesVersion{ AgentTools: []params.EntityVersion{{ Tag: s.rawMachine.Tag().String(), Tools: ¶ms.Version{ Version: current, }}, }, } results, err := s.upgrader.SetTools(args) c.Assert(err, jc.ErrorIsNil) c.Assert(results.Results, gc.HasLen, 1) c.Assert(results.Results[0].Error, gc.IsNil) // Check that the new value actually got set, we must Refresh because // it was set on a different Machine object err = s.rawMachine.Refresh() c.Assert(err, jc.ErrorIsNil) realTools, err := s.rawMachine.AgentTools() c.Assert(err, jc.ErrorIsNil) c.Check(realTools.Version, gc.Equals, current) c.Check(realTools.URL, gc.Equals, "") }
// GetMockBuildTools returns a sync.BuildAgentTarballFunc implementation which generates // a fake tools tarball. func GetMockBuildTools(c *gc.C) sync.BuildAgentTarballFunc { return func(build bool, forceVersion *version.Number, stream string) (*sync.BuiltAgent, error) { vers := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } if forceVersion != nil { vers.Number = *forceVersion } tgz, checksum := coretesting.TarGz( coretesting.NewTarFile(names.Jujud, 0777, "jujud contents "+vers.String())) toolsDir, err := ioutil.TempDir("", "juju-tools-"+stream) c.Assert(err, jc.ErrorIsNil) name := "name" ioutil.WriteFile(filepath.Join(toolsDir, name), tgz, 0777) return &sync.BuiltAgent{ Dir: toolsDir, StorageName: name, Version: vers, Size: int64(len(tgz)), Sha256Hash: checksum, }, nil } }
func (s *toolsSuite) TestFindAvailableToolsCompleteNoValidate(c *gc.C) { s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) var allTools tools.List for _, series := range series.SupportedSeries() { binary := version.Binary{ Number: version.Current, Series: series, Arch: arch.HostArch(), } allTools = append(allTools, &tools.Tools{ Version: binary, URL: "http://testing.invalid/tools.tar.gz", }) } s.PatchValue(bootstrap.FindTools, func(_ environs.Environ, major, minor int, stream string, f tools.Filter) (tools.List, error) { return allTools, nil }) env := newEnviron("foo", useDefaultKeys, nil) availableTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false) c.Assert(err, jc.ErrorIsNil) c.Assert(availableTools, gc.HasLen, len(allTools)) c.Assert(env.supportedArchitecturesCount, gc.Equals, 0) }
func (s *toolsSuite) TestFindAvailableToolsSpecificVersion(c *gc.C) { currentVersion := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } currentVersion.Major = 2 currentVersion.Minor = 3 s.PatchValue(&version.Current, currentVersion.Number) var findToolsCalled int s.PatchValue(bootstrap.FindTools, func(_ environs.Environ, major, minor int, stream string, f tools.Filter) (tools.List, error) { c.Assert(f.Number.Major, gc.Equals, 10) c.Assert(f.Number.Minor, gc.Equals, 11) c.Assert(f.Number.Patch, gc.Equals, 12) c.Assert(stream, gc.Equals, "released") findToolsCalled++ return []*tools.Tools{ &tools.Tools{ Version: currentVersion, URL: "http://testing.invalid/tools.tar.gz", }, }, nil }) env := newEnviron("foo", useDefaultKeys, nil) toolsVersion := version.MustParse("10.11.12") result, err := bootstrap.FindAvailableTools(env, &toolsVersion, nil, nil, false) c.Assert(err, jc.ErrorIsNil) c.Assert(findToolsCalled, gc.Equals, 1) c.Assert(result, jc.DeepEquals, tools.List{ &tools.Tools{ Version: currentVersion, URL: "http://testing.invalid/tools.tar.gz", }, }) }
func (fix *SimpleToolsFixture) SetUp(c *gc.C, dataDir string) { fix.dataDir = dataDir fix.logDir = c.MkDir() current := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } toolsDir := tools.SharedToolsDir(fix.dataDir, current) err := os.MkdirAll(toolsDir, 0755) c.Assert(err, jc.ErrorIsNil) jujudPath := filepath.Join(toolsDir, "jujud") err = ioutil.WriteFile(jujudPath, []byte(fakeJujud), 0755) c.Assert(err, jc.ErrorIsNil) toolsPath := filepath.Join(toolsDir, "downloaded-tools.txt") testTools := coretools.Tools{Version: current, URL: "http://testing.invalid/tools"} data, err := json.Marshal(testTools) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(toolsPath, data, 0644) c.Assert(err, jc.ErrorIsNil) fix.binDir = c.MkDir() fix.origPath = os.Getenv("PATH") os.Setenv("PATH", fix.binDir+":"+fix.origPath) fix.makeBin(c, "status", `echo "blah stop/waiting"`) fix.makeBin(c, "stopped-status", `echo "blah stop/waiting"`) fix.makeBin(c, "started-status", `echo "blah start/running, process 666"`) fix.makeBin(c, "start", "cp $(which started-status) $(which status)") fix.makeBin(c, "stop", "cp $(which stopped-status) $(which status)") fix.data = svctesting.NewFakeServiceData() }
// populateTools stores uploaded tools in provider storage // and updates the tools metadata. func (c *BootstrapCommand) populateTools(st *state.State, env environs.Environ) error { agentConfig := c.CurrentConfig() dataDir := agentConfig.DataDir() current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } tools, err := agenttools.ReadTools(dataDir, current) if err != nil { return errors.Trace(err) } data, err := ioutil.ReadFile(filepath.Join( agenttools.SharedToolsDir(dataDir, current), "tools.tar.gz", )) if err != nil { return errors.Trace(err) } toolstorage, err := st.ToolsStorage() if err != nil { return errors.Trace(err) } defer toolstorage.Close() var toolsVersions []version.Binary if strings.HasPrefix(tools.URL, "file://") { // Tools were uploaded: clone for each series of the same OS. os, err := series.GetOSFromSeries(tools.Version.Series) if err != nil { return errors.Trace(err) } osSeries := series.OSSupportedSeries(os) for _, series := range osSeries { toolsVersion := tools.Version toolsVersion.Series = series toolsVersions = append(toolsVersions, toolsVersion) } } else { // Tools were downloaded from an external source: don't clone. toolsVersions = []version.Binary{tools.Version} } for _, toolsVersion := range toolsVersions { metadata := binarystorage.Metadata{ Version: toolsVersion.String(), Size: tools.Size, SHA256: tools.SHA256, } logger.Debugf("Adding tools: %v", toolsVersion) if err := toolstorage.Add(bytes.NewReader(data), metadata); err != nil { return errors.Trace(err) } } return nil }
func (s *uploadSuite) TestUploadAndForceVersion(c *gc.C) { vers := jujuversion.Current vers.Patch++ s.patchBundleTools(c, &vers) t, err := sync.Upload(s.targetStorage, "released", &vers) c.Assert(err, jc.ErrorIsNil) c.Assert(t.Version, gc.Equals, version.Binary{Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries()}) }
// PrimeStateAgent writes the configuration file and tools for // a state agent with the given entity name. It returns the agent's // configuration and the current tools. func (s *AgentSuite) PrimeStateAgent(c *gc.C, tag names.Tag, password string) (agent.ConfigSetterWriter, *coretools.Tools) { vers := version.Binary{ Number: version.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } return s.PrimeStateAgentVersion(c, tag, password, vers) }
func (s *badBuildSuite) assertEqualsCurrentVersion(c *gc.C, v version.Binary) { current := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: series.HostSeries(), } c.Assert(v, gc.Equals, current) }