func (s *varsSuite) TestBlankJujuXDGDataHomeEnvVar(c *gc.C) { s.PatchEnvironment(osenv.JujuXDGDataHomeEnvKey, "") if runtime.GOOS == "windows" { s.PatchEnvironment("APPDATA", `P:\foobar`) } else { s.PatchEnvironment("HOME", "/foobar") } c.Assert(osenv.JujuXDGDataHomeDir(), gc.Not(gc.Equals), "") if runtime.GOOS == "windows" { c.Assert(osenv.JujuXDGDataHomeDir(), gc.Equals, osenv.JujuXDGDataHomeWin()) } else { c.Assert(osenv.JujuXDGDataHomeDir(), gc.Equals, osenv.JujuXDGDataHomeLinux()) } }
// InitJujuXDGDataHome initializes the charm cache, environs/config and utils/ssh packages // to use default paths based on the $JUJU_DATA or $HOME environment variables. // This function should be called before running a Juju CLI command. func InitJujuXDGDataHome() error { jujuXDGDataHome := osenv.JujuXDGDataHomeDir() if jujuXDGDataHome == "" { return errors.New("cannot determine juju data home, required environment variables are not set") } charmrepo.CacheDir = osenv.JujuXDGDataHomePath("charmcache") if err := ssh.LoadClientKeys(osenv.JujuXDGDataHomePath("ssh")); err != nil { return errors.Annotate(err, "cannot load ssh client keys") } return nil }
func (s *ToolsMetadataSuite) TestPatchLevels(c *gc.C) { if runtime.GOOS == "windows" { c.Skip("Skipping on windows, test only set up for Linux tools") } currentVersion := jujuversion.Current currentVersion.Build = 0 versionStrings := []string{ currentVersion.String() + "-precise-amd64", currentVersion.String() + ".1-precise-amd64", } metadataDir := osenv.JujuXDGDataHomeDir() // default metadata dir toolstesting.MakeTools(c, metadataDir, "released", versionStrings) ctx := coretesting.Context(c) code := cmd.Main(newToolsMetadataCommand(), ctx, []string{"--stream", "released"}) c.Assert(code, gc.Equals, 0) output := ctx.Stdout.(*bytes.Buffer).String() expectedOutput := fmt.Sprintf(` Finding tools in .* .*Fetching tools from dir "released" to generate hash: %s .*Fetching tools from dir "released" to generate hash: %s .*Writing tools/streams/v1/index2\.json .*Writing tools/streams/v1/index\.json .*Writing tools/streams/v1/com\.ubuntu\.juju-released-tools\.json `[1:], regexp.QuoteMeta(versionStrings[0]), regexp.QuoteMeta(versionStrings[1])) c.Assert(output, gc.Matches, expectedOutput) metadata := toolstesting.ParseMetadataFromDir(c, metadataDir, "released", false) c.Assert(metadata, gc.HasLen, 2) filename := fmt.Sprintf("juju-%s-precise-amd64.tgz", currentVersion) size, sha256 := toolstesting.SHA256sum(c, filepath.Join(metadataDir, "tools", "released", filename)) c.Assert(metadata[0], gc.DeepEquals, &tools.ToolsMetadata{ Release: "precise", Version: currentVersion.String(), Arch: "amd64", Size: size, Path: "released/" + filename, FileType: "tar.gz", SHA256: sha256, }) filename = fmt.Sprintf("juju-%s.1-precise-amd64.tgz", currentVersion) size, sha256 = toolstesting.SHA256sum(c, filepath.Join(metadataDir, "tools", "released", filename)) c.Assert(metadata[1], gc.DeepEquals, &tools.ToolsMetadata{ Release: "precise", Version: currentVersion.String() + ".1", Arch: "amd64", Size: size, Path: "released/" + filename, FileType: "tar.gz", SHA256: sha256, }) }
func (s *MainSuite) TestFirstRun2xFrom1xOnUbuntu(c *gc.C) { if runtime.GOOS == "windows" { // This test can't work on Windows and shouldn't need to c.Skip("test doesn't work on Windows because Juju's 1.x and 2.x config directory are the same") } // Code should only run on ubuntu series, so patch out the series for // when non-ubuntu OSes run this test. s.PatchValue(&series.HostSeries, func() string { return "trusty" }) argChan := make(chan []string, 1) execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ Stdout: "1.25.0-trusty-amd64", Args: argChan, }) stub := &gitjujutesting.Stub{} s.PatchValue(&cloud.NewUpdateCloudsCommand, func() cmd.Command { return &stubCommand{stub: stub} }) // remove the new juju-home and create a fake old juju home. err := os.RemoveAll(osenv.JujuXDGDataHomeDir()) c.Assert(err, jc.ErrorIsNil) makeValidOldHome(c) var code int f := func() { code = main{ execCommand: execCommand, }.Run([]string{"juju", "version"}) } stdout, stderr := gitjujutesting.CaptureOutput(c, f) select { case args := <-argChan: c.Assert(args, gc.DeepEquals, []string{"juju-1", "version"}) default: c.Fatalf("Exec function not called.") } c.Check(code, gc.Equals, 0) c.Check(string(stderr), gc.Equals, fmt.Sprintf(` Welcome to Juju %s. If you meant to use Juju 1.25.0 you can continue using it with the command juju-1 e.g. 'juju-1 switch'. See https://jujucharms.com/docs/stable/introducing-2 for more details. Since Juju 2 is being run for the first time, downloading latest cloud information.`[1:]+"\n", jujuversion.Current)) checkVersionOutput(c, string(stdout)) }
func (c *toolsMetadataCommand) Run(context *cmd.Context) error { writer := loggo.NewMinimumLevelWriter( cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) loggo.RegisterWriter("toolsmetadata", writer) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuXDGDataHomeDir() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return err } // We now store the tools in a directory named after their stream, but the // legacy behaviour is to store all tools in a single "releases" directory. toolsDir := c.stream if c.stream == "" { fmt.Fprintln(context.Stdout, "No stream specified, defaulting to released tools in the releases directory.") c.stream = envtools.ReleasedStream toolsDir = envtools.LegacyReleaseDirectory } fmt.Fprintf(context.Stdout, "Finding tools in %s for stream %s.\n", c.metadataDir, c.stream) toolsList, err := envtools.ReadList(sourceStorage, toolsDir, -1, -1) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return err } toolsList, err = envtools.FindToolsForCloud(toolsDataSources(source), simplestreams.CloudSpec{}, c.stream, -1, -1, coretools.Filter{}) } if err != nil { return err } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return err } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return mergeAndWriteMetadata(targetStorage, toolsDir, c.stream, c.clean, toolsList, writeMirrors) }
func (s *ToolsMetadataSuite) TestGenerateLegacyRelease(c *gc.C) { metadataDir := osenv.JujuXDGDataHomeDir() // default metadata dir toolstesting.MakeTools(c, metadataDir, "releases", versionStrings) ctx := coretesting.Context(c) code := cmd.Main(newToolsMetadataCommand(), ctx, nil) c.Assert(code, gc.Equals, 0) output := ctx.Stdout.(*bytes.Buffer).String() c.Assert(output, gc.Matches, expectedOutputDirectoryLegacyReleased) metadata := toolstesting.ParseMetadataFromDir(c, metadataDir, "released", false) c.Assert(metadata, gc.HasLen, len(versionStrings)) obtainedVersionStrings := make([]string, len(versionStrings)) for i, metadata := range metadata { s := fmt.Sprintf("%s-%s-%s", metadata.Version, metadata.Release, metadata.Arch) obtainedVersionStrings[i] = s } c.Assert(obtainedVersionStrings, gc.DeepEquals, versionStrings) }
func (c *toolsMetadataCommand) Run(context *cmd.Context) error { writer := loggo.NewMinimumLevelWriter( cmd.NewCommandLogWriter("juju.environs.tools", context.Stdout, context.Stderr), loggo.INFO) loggo.RegisterWriter("toolsmetadata", writer) defer loggo.RemoveWriter("toolsmetadata") if c.metadataDir == "" { c.metadataDir = osenv.JujuXDGDataHomeDir() } else { c.metadataDir = context.AbsPath(c.metadataDir) } sourceStorage, err := filestorage.NewFileStorageReader(c.metadataDir) if err != nil { return errors.Trace(err) } fmt.Fprintf(context.Stdout, "Finding tools in %s for stream %s.\n", c.metadataDir, c.stream) toolsList, err := envtools.ReadList(sourceStorage, c.stream, -1, -1) if err == envtools.ErrNoTools { var source string source, err = envtools.ToolsURL(envtools.DefaultBaseURL) if err != nil { return errors.Trace(err) } toolsList, err = envtools.FindToolsForCloud(toolsDataSources(source), simplestreams.CloudSpec{}, c.stream, -1, -1, coretools.Filter{}) } if err != nil { return errors.Trace(err) } targetStorage, err := filestorage.NewFileStorageWriter(c.metadataDir) if err != nil { return errors.Trace(err) } writeMirrors := envtools.DoNotWriteMirrors if c.public { writeMirrors = envtools.WriteMirrors } return errors.Trace(mergeAndWriteMetadata(targetStorage, c.stream, c.stream, c.clean, toolsList, writeMirrors)) }
func (s *MainSuite) TestNoWarnWithNo1xOr2xData(c *gc.C) { // Code should only rnu on ubuntu series, so patch out the series for // when non-ubuntu OSes run this test. s.PatchValue(&series.HostSeries, func() string { return "trusty" }) argChan := make(chan []string, 1) // we shouldn't actually be running anything, but if we do, this will // provide some consistent results. execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ Stdout: "1.25.0-trusty-amd64", Args: argChan, }) stub := &gitjujutesting.Stub{} s.PatchValue(&cloud.NewUpdateCloudsCommand, func() cmd.Command { return &stubCommand{stub: stub} }) // remove the new juju-home. err := os.RemoveAll(osenv.JujuXDGDataHomeDir()) c.Assert(err, jc.ErrorIsNil) // create fake (empty) old juju home. path := c.MkDir() s.PatchEnvironment("JUJU_HOME", path) var code int stdout, stderr := gitjujutesting.CaptureOutput(c, func() { code = main{ execCommand: execCommand, }.Run([]string{"juju", "version"}) }) c.Assert(code, gc.Equals, 0) assertNoArgs(c, argChan) c.Check(string(stderr), gc.Equals, ` Since Juju 2 is being run for the first time, downloading latest cloud information.`[1:]+"\n") checkVersionOutput(c, string(stdout)) }
func (s *MainSuite) TestFirstRun2xFrom1xNotUbuntu(c *gc.C) { // Code should only run on ubuntu series, so pretend to be something else. s.PatchValue(&series.HostSeries, func() string { return "win8" }) argChan := make(chan []string, 1) // we shouldn't actually be running anything, but if we do, this will // provide some consistent results. execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ Stdout: "1.25.0-trusty-amd64", Args: argChan, }) stub := &gitjujutesting.Stub{} s.PatchValue(&cloud.NewUpdateCloudsCommand, func() cmd.Command { return &stubCommand{stub: stub} }) // remove the new juju-home and create a fake old juju home. err := os.RemoveAll(osenv.JujuXDGDataHomeDir()) c.Assert(err, jc.ErrorIsNil) makeValidOldHome(c) var code int stdout, stderr := gitjujutesting.CaptureOutput(c, func() { code = main{ execCommand: execCommand, }.Run([]string{"juju", "version"}) }) c.Assert(code, gc.Equals, 0) assertNoArgs(c, argChan) c.Check(string(stderr), gc.Equals, ` Since Juju 2 is being run for the first time, downloading latest cloud information.`[1:]+"\n") checkVersionOutput(c, string(stdout)) }
func juju2xConfigDataExists() bool { _, err := os.Stat(osenv.JujuXDGDataHomeDir()) return err == nil }
func (s *MainSuite) TestFirstRunUpdateCloud(c *gc.C) { // remove the juju-home. err := os.RemoveAll(osenv.JujuXDGDataHomeDir()) c.Assert(err, jc.ErrorIsNil) s.assertRunCommandUpdateCloud(c, "Run") }
func (s *JujuXDGDataHomeSuite) TestHomePath(c *gc.C) { testJujuHome := c.MkDir() osenv.SetJujuXDGDataHome(testJujuHome) envPath := osenv.JujuXDGDataHomeDir() c.Assert(envPath, gc.Equals, testJujuHome) }
func (s *varsSuite) TestJujuXDGDataHomeEnvVar(c *gc.C) { path := "/foo/bar/baz" s.PatchEnvironment(osenv.JujuXDGDataHomeEnvKey, path) c.Assert(osenv.JujuXDGDataHomeDir(), gc.Equals, path) }