func (s *BootstrapSuite) testToolsMetadata(c *gc.C, exploded bool) { envtesting.RemoveFakeToolsMetadata(c, s.toolsStorage) _, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.b64yamlEnvcfg, "--instance-id", string(s.instanceId)) c.Assert(err, jc.ErrorIsNil) err = cmd.Run(nil) c.Assert(err, jc.ErrorIsNil) // We don't write metadata at bootstrap anymore. simplestreamsMetadata, err := envtools.ReadMetadata(s.toolsStorage, "released") c.Assert(err, jc.ErrorIsNil) c.Assert(simplestreamsMetadata, gc.HasLen, 0) // The tools should have been added to tools storage, and // exploded into each of the supported series of // the same operating system if the tools were uploaded. st, err := state.Open(testing.EnvironmentTag, &mongo.MongoInfo{ Info: mongo.Info{ Addrs: []string{gitjujutesting.MgoServer.Addr()}, CACert: testing.CACert, }, Password: testPasswordHash(), }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() expectedSeries := make(set.Strings) if exploded { for _, ser := range series.SupportedSeries() { os, err := series.GetOSFromSeries(ser) c.Assert(err, jc.ErrorIsNil) hostos, err := series.GetOSFromSeries(version.Current.Series) c.Assert(err, jc.ErrorIsNil) if os == hostos { expectedSeries.Add(ser) } } } else { expectedSeries.Add(series.HostSeries()) } storage, err := st.ToolsStorage() c.Assert(err, jc.ErrorIsNil) defer storage.Close() metadata, err := storage.AllMetadata() c.Assert(err, jc.ErrorIsNil) c.Assert(metadata, gc.HasLen, expectedSeries.Size()) for _, m := range metadata { c.Assert(expectedSeries.Contains(m.Version.Series), jc.IsTrue) } }
func getContainerInstance() (cont []ContainerInstance, err error) { current_os, err := series.GetOSFromSeries(series.HostSeries()) if err != nil { return nil, err } switch current_os { case jujuos.CentOS: cont = []ContainerInstance{ {instance.LXC, [][]string{ {"lxc"}, {"cloud-image-utils"}, }}, {instance.KVM, [][]string{ {"uvtool-libvirt"}, {"uvtool"}, }}, } default: cont = []ContainerInstance{ {instance.LXC, [][]string{ {"--target-release", "precise-updates/cloud-tools", "lxc"}, {"--target-release", "precise-updates/cloud-tools", "cloud-image-utils"}, }}, {instance.KVM, [][]string{ {"uvtool-libvirt"}, {"uvtool"}, }}, } } return cont, nil }
func (*CurrentSuite) TestCurrentSeries(c *gc.C) { s := series.HostSeries() if s == "unknown" { s = "n/a" } out, err := exec.Command("lsb_release", "-c").CombinedOutput() if err != nil { // If the command fails (for instance if we're running on some other // platform) then CurrentSeries should be unknown. switch runtime.GOOS { case "darwin": c.Check(s, gc.Matches, `mavericks|mountainlion|lion|snowleopard`) case "windows": c.Check(s, gc.Matches, `win2012hvr2|win2012hv|win2012|win2012r2|win8|win81|win7`) default: current_os, err := series.GetOSFromSeries(s) c.Assert(err, gc.IsNil) if s != "n/a" { // There is no lsb_release command on CentOS. if current_os == os.CentOS { c.Check(s, gc.Matches, `centos7`) } } } } else { c.Assert(string(out), gc.Equals, "Codename:\t"+s+"\n") } }
// UserdataConfig is supposed to take in an instanceConfig as well as a // cloudinit.cloudConfig and add attributes in the cloudinit structure based on // the values inside instanceConfig and on the series func NewUserdataConfig(icfg *instancecfg.InstanceConfig, conf cloudinit.CloudConfig) (UserdataConfig, error) { // TODO(ericsnow) bug #1426217 // Protect icfg and conf better. operatingSystem, err := series.GetOSFromSeries(icfg.Series) if err != nil { return nil, err } base := baseConfigure{ tag: names.NewMachineTag(icfg.MachineId), icfg: icfg, conf: conf, os: operatingSystem, } switch operatingSystem { case os.Ubuntu: return &unixConfigure{base}, nil case os.CentOS: return &unixConfigure{base}, nil case os.Windows: return &windowsConfigure{base}, nil default: return nil, errors.NotSupportedf("OS %s", icfg.Series) } }
func versionInitSystem(ser string) (string, error) { seriesos, err := series.GetOSFromSeries(ser) if err != nil { notFound := errors.NotFoundf("init system for series %q", ser) return "", errors.Wrap(err, notFound) } switch seriesos { case os.Windows: return InitSystemWindows, nil case os.Ubuntu: switch ser { case "precise", "quantal", "raring", "saucy", "trusty", "utopic": return InitSystemUpstart, nil default: // vivid and later if featureflag.Enabled(feature.LegacyUpstart) { return InitSystemUpstart, nil } return InitSystemSystemd, nil } case os.CentOS: return InitSystemSystemd, nil } return "", errors.NotFoundf("unknown os %q (from series %q), init system", seriesos, ser) }
func (w *unixConfigure) setDataDirPermissions() string { seriesos, _ := series.GetOSFromSeries(w.icfg.Series) var user string switch seriesos { case os.CentOS: user = "******" default: user = "******" } return fmt.Sprintf("chown %s:adm %s", user, w.icfg.LogDir) }
func (s *supportedSeriesSuite) TestGetOSFromSeries(c *gc.C) { for _, t := range getOSFromSeriesTests { got, err := series.GetOSFromSeries(t.series) if t.err != "" { c.Assert(err, gc.ErrorMatches, t.err) } else { c.Check(err, jc.ErrorIsNil) c.Assert(got, gc.Equals, t.want) } } }
// osVal will lookup the value of the key valname // in the apropriate map, based on the series. This will // help reduce boilerplate code func osVal(ser string, valname osVarType) (string, error) { os, err := series.GetOSFromSeries(ser) if err != nil { return "", err } switch os { case jujuos.Windows: return winVals[valname], nil default: return nixVals[valname], nil } }
func (w *proxyWorker) writeEnvironment() error { // TODO(dfc) this should be replaced with a switch on os.HostOS() osystem, err := series.GetOSFromSeries(series.HostSeries()) if err != nil { return err } switch osystem { case os.Windows: return w.writeEnvironmentToRegistry() default: return w.writeEnvironmentFile() } }
// binary returns the tools metadata's binary version, which may be used for // map lookup. It is possible for a binary to have an unkown OS. func (t *ToolsMetadata) binary() (version.Binary, error) { num, err := version.Parse(t.Version) if err != nil { return version.Binary{}, errors.Trace(err) } toolsOS, err := series.GetOSFromSeries(t.Release) if err != nil && !series.IsUnknownOSForSeriesError(err) { return version.Binary{}, errors.Trace(err) } return version.Binary{ Number: num, Series: t.Release, Arch: t.Arch, OS: toolsOS, }, nil }
// locallyBuildableTools returns the list of tools that // can be built locally, for series of the same OS. func locallyBuildableTools() (buildable coretools.List) { for _, ser := range series.SupportedSeries() { if os, err := series.GetOSFromSeries(ser); err != nil || os != version.Current.OS { continue } binary := version.Binary{ Number: version.Current.Number, Series: ser, Arch: arch.HostArch(), OS: version.Current.OS, } // Increment the build number so we know it's a development build. binary.Build++ buildable = append(buildable, &coretools.Tools{Version: binary}) } return buildable }
// ParseBinary parses a binary version of the form "1.2.3-series-arch". func ParseBinary(s string) (Binary, error) { m := binaryPat.FindStringSubmatch(s) if m == nil { return Binary{}, fmt.Errorf("invalid binary version %q", s) } var v Binary v.Major = atoi(m[1]) v.Minor = atoi(m[2]) v.Tag = m[4] v.Patch = atoi(m[5]) if m[6] != "" { v.Build = atoi(m[6][1:]) } v.Series = m[7] v.Arch = m[8] var err error v.OS, err = series.GetOSFromSeries(v.Series) return v, err }
// New returns a new Config with no options set. func New(ser string) (CloudConfig, error) { seriesos, err := series.GetOSFromSeries(ser) if err != nil { return nil, err } switch seriesos { case os.Windows: renderer, _ := shell.NewRenderer("powershell") return &windowsCloudConfig{ &cloudConfig{ series: ser, renderer: renderer, attrs: make(map[string]interface{}), }, }, nil case os.Ubuntu: renderer, _ := shell.NewRenderer("bash") return &ubuntuCloudConfig{ &cloudConfig{ series: ser, paccmder: commands.NewAptPackageCommander(), pacconfer: config.NewAptPackagingConfigurer(ser), renderer: renderer, attrs: make(map[string]interface{}), }, }, nil case os.CentOS: renderer, _ := shell.NewRenderer("bash") return ¢OSCloudConfig{ &cloudConfig{ series: ser, paccmder: commands.NewYumPackageCommander(), pacconfer: config.NewYumPackagingConfigurer(ser), renderer: renderer, attrs: make(map[string]interface{}), }, }, nil default: return nil, errors.NotFoundf("cloudconfig for series %q", ser) } }
func (c *baseConfigure) addMachineAgentToBoot() error { svc, err := c.icfg.InitService(c.conf.ShellRenderer()) if err != nil { return errors.Trace(err) } // Make the agent run via a symbolic link to the actual tools // directory, so it can upgrade itself without needing to change // the init script. toolsDir := c.icfg.ToolsDir(c.conf.ShellRenderer()) c.conf.AddScripts(c.toolsSymlinkCommand(toolsDir)) name := c.tag.String() cmds, err := svc.InstallCommands() if err != nil { return errors.Annotatef(err, "cannot make cloud-init init script for the %s agent", name) } startCmds, err := svc.StartCommands() if err != nil { return errors.Annotatef(err, "cannot make cloud-init init script for the %s agent", name) } cmds = append(cmds, startCmds...) svcName := c.icfg.MachineAgentServiceName // TODO (gsamfira): This is temporary until we find a cleaner way to fix // cloudinit.LogProgressCmd to not add >&9 on Windows. targetOS, err := series.GetOSFromSeries(c.icfg.Series) if err != nil { return err } if targetOS != os.Windows { c.conf.AddRunCmd(cloudinit.LogProgressCmd("Starting Juju machine agent (%s)", svcName)) } c.conf.AddScripts(cmds...) return nil }
func (s *ContainerSetupSuite) assertContainerInitialised(c *gc.C, cont ContainerInstance, addressable bool) { // A noop worker callback. startProvisionerWorker := func(runner worker.Runner, containerType instance.ContainerType, pr *apiprovisioner.State, cfg agent.Config, broker environs.InstanceBroker, toolsFinder provisioner.ToolsFinder) error { return nil } s.PatchValue(&provisioner.StartProvisioner, startProvisionerWorker) current_os, err := series.GetOSFromSeries(series.HostSeries()) c.Assert(err, jc.ErrorIsNil) var ser string var expected_initial []string switch current_os { case jujuos.CentOS: ser = "centos7" expected_initial = []string{ "yum", "--assumeyes", "--debuglevel=1", "install"} default: ser = "precise" expected_initial = []string{ "apt-get", "--option=Dpkg::Options::=--force-confold", "--option=Dpkg::options::=--force-unsafe-io", "--assume-yes", "--quiet", "install"} } // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ Series: ser, // precise requires special apt parameters, so we use that series here. 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) err = m.SetAgentVersion(version.Current) c.Assert(err, jc.ErrorIsNil) // Before starting /etc/default/lxc-net should be missing. c.Assert(s.fakeLXCNet, jc.DoesNotExist) s.createContainer(c, m, cont.ctype) // Only feature-flagged addressable containers modify lxc-net. if addressable { // After initialisation starts, but before running the // initializer, lxc-net should be created if cont.ctype is LXC, as the // dummy provider supports static address allocation by default. if cont.ctype == instance.LXC { AssertFileContains(c, s.fakeLXCNet, provisioner.EtcDefaultLXCNet) defer os.Remove(s.fakeLXCNet) } else { c.Assert(s.fakeLXCNet, jc.DoesNotExist) } } for _, pack := range cont.packages { cmd := <-s.aptCmdChan expected := append(expected_initial, pack...) c.Assert(cmd.Args, gc.DeepEquals, expected) } }
func (s *supportedSeriesSuite) TestUnknownOSFromSeries(c *gc.C) { _, err := series.GetOSFromSeries("Xuanhuaceratops") c.Assert(err, jc.Satisfies, series.IsUnknownOSForSeriesError) c.Assert(err, gc.ErrorMatches, `unknown OS for series: "Xuanhuaceratops"`) }