func (suite) TestParseBinary(c *C) { for i, test := range parseBinaryTests { c.Logf("test 1: %d", i) got, err := version.ParseBinary(test.v) if test.err != "" { c.Assert(err, ErrorMatches, test.err) } else { c.Assert(err, IsNil) c.Assert(got, Equals, test.expect) } } for i, test := range parseTests { c.Logf("test 2: %d", i) v := test.v + "-a-b" got, err := version.ParseBinary(v) expect := version.Binary{ Number: test.expect, Series: "a", Arch: "b", } if test.err != "" { c.Assert(err, ErrorMatches, strings.Replace(test.err, "version", "binary version", 1)) } else { c.Assert(err, IsNil) c.Assert(got, Equals, expect) c.Check(got.IsDev(), Equals, test.dev) } } }
// listTools is like ListTools, but only returns the tools from // a particular storage. func listTools(store StorageReader, majorVersion int) ([]*state.Tools, error) { dir := fmt.Sprintf("%s%d.", toolPrefix, majorVersion) names, err := store.List(dir) if err != nil { return nil, err } var toolsList []*state.Tools for _, name := range names { if !strings.HasPrefix(name, toolPrefix) || !strings.HasSuffix(name, ".tgz") { log.Printf("environs: unexpected tools file found %q", name) continue } vers := name[len(toolPrefix) : len(name)-len(".tgz")] var t state.Tools t.Binary, err = version.ParseBinary(vers) if err != nil { log.Printf("environs: failed to parse %q: %v", vers, err) continue } if t.Major != majorVersion { log.Printf("environs: tool %q found in wrong directory %q", name, dir) continue } t.URL, err = store.URL(name) if err != nil { log.Printf("environs: cannot get URL for %q: %v", name, err) continue } toolsList = append(toolsList, &t) } return toolsList, nil }
// ReadList returns a List of the tools in store with the given major version. // If store contains no such tools, it returns ErrNoMatches. func ReadList(storage URLLister, majorVersion int) (List, error) { logger.Debugf("reading v%d.* tools", majorVersion) names, err := storage.List(toolPrefix) if err != nil { return nil, err } var list List var foundAnyTools bool for _, name := range names { if !strings.HasPrefix(name, toolPrefix) || !strings.HasSuffix(name, toolSuffix) { continue } var t state.Tools vers := name[len(toolPrefix) : len(name)-len(toolSuffix)] if t.Binary, err = version.ParseBinary(vers); err != nil { continue } foundAnyTools = true if t.Major != majorVersion { continue } logger.Debugf("found %s", vers) if t.URL, err = storage.URL(name); err != nil { return nil, err } list = append(list, &t) } if len(list) == 0 { if foundAnyTools { return nil, ErrNoMatches } return nil, ErrNoTools } return list, nil }
// bundleTools bundles all the current juju tools in gzipped tar // format to the given writer. // If forceVersion is not nil, a FORCE-VERSION file is included in // the tools bundle so it will lie about its current version number. func bundleTools(w io.Writer, forceVersion *version.Number) (version.Binary, error) { dir, err := ioutil.TempDir("", "juju-tools") if err != nil { return version.Binary{}, err } defer os.RemoveAll(dir) cmds := [][]string{ {"go", "install", "launchpad.net/juju-core/cmd/jujud", "launchpad.net/juju-core/cmd/jujuc"}, {"strip", dir + "/jujud", dir + "/jujuc"}, } env := setenv(os.Environ(), "GOBIN="+dir) for _, args := range cmds { cmd := exec.Command(args[0], args[1:]...) cmd.Env = env out, err := cmd.CombinedOutput() if err != nil { return version.Binary{}, fmt.Errorf("build command %q failed: %v; %s", args[0], err, out) } } if forceVersion != nil { if err := ioutil.WriteFile(filepath.Join(dir, "FORCE-VERSION"), []byte(forceVersion.String()), 0666); err != nil { return version.Binary{}, err } } cmd := exec.Command(filepath.Join(dir, "jujud"), "version") out, err := cmd.CombinedOutput() if err != nil { return version.Binary{}, fmt.Errorf("cannot get version from %q: %v; %s", cmd.Args[0], err, out) } tvs := strings.TrimSpace(string(out)) tvers, err := version.ParseBinary(tvs) if err != nil { return version.Binary{}, fmt.Errorf("invalid version %q printed by jujud", tvs) } err = archive(w, dir) if err != nil { return version.Binary{}, err } return tvers, err }
// bundleTools bundles all the current juju tools in gzipped tar // format to the given writer. // If forceVersion is not nil, a FORCE-VERSION file is included in // the tools bundle so it will lie about its current version number. func bundleTools(w io.Writer, forceVersion *version.Number) (version.Binary, error) { dir, err := ioutil.TempDir("", "juju-tools") if err != nil { return version.Binary{}, err } defer os.RemoveAll(dir) if err := copyExistingJujud(dir); err != nil { logger.Debugf("copy existing failed: %v", err) if err := buildJujud(dir); err != nil { return version.Binary{}, err } } if forceVersion != nil { logger.Debugf("forcing version to %s", forceVersion) if err := ioutil.WriteFile(filepath.Join(dir, "FORCE-VERSION"), []byte(forceVersion.String()), 0666); err != nil { return version.Binary{}, err } } cmd := exec.Command(filepath.Join(dir, "jujud"), "version") out, err := cmd.CombinedOutput() if err != nil { return version.Binary{}, fmt.Errorf("cannot get version from %q: %v; %s", cmd.Args[0], err, out) } tvs := strings.TrimSpace(string(out)) tvers, err := version.ParseBinary(tvs) if err != nil { return version.Binary{}, fmt.Errorf("invalid version %q printed by jujud", tvs) } err = archive(w, dir) if err != nil { return version.Binary{}, err } return tvers, err }