// setupGUIArchive creates a Juju GUI tar.bz2 archive with the given version // and files and saves it into the given storage. The Juju GUI archive SHA256 // hash is returned. func setupGUIArchive(c *gc.C, storage binarystorage.Storage, vers string, files map[string]string) (hash string) { r, hash, size := makeGUIArchive(c, vers, files) err := storage.Add(r, binarystorage.Metadata{ Version: vers, Size: size, SHA256: hash, }) c.Assert(err, jc.ErrorIsNil) return hash }
// fetchAndCacheTools fetches tools with the specified version by searching for a URL // in simplestreams and GETting it, caching the result in tools storage before returning // to the caller. func (h *toolsDownloadHandler) fetchAndCacheTools(v version.Binary, stor binarystorage.Storage, st *state.State) (io.ReadCloser, error) { envcfg, err := st.ModelConfig() if err != nil { return nil, err } env, err := environs.New(envcfg) if err != nil { return nil, err } tools, err := envtools.FindExactTools(env, v.Number, v.Series, v.Arch) if err != nil { return nil, err } // No need to verify the server's identity because we verify the SHA-256 hash. logger.Infof("fetching %v tools from %v", v, tools.URL) resp, err := utils.GetNonValidatingHTTPClient().Get(tools.URL) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { msg := fmt.Sprintf("bad HTTP response: %v", resp.Status) if body, err := ioutil.ReadAll(resp.Body); err == nil { msg += fmt.Sprintf(" (%s)", bytes.TrimSpace(body)) } return nil, errors.New(msg) } data, sha256, err := readAndHash(resp.Body) if err != nil { return nil, err } if int64(len(data)) != tools.Size { return nil, errors.Errorf("size mismatch for %s", tools.URL) } if sha256 != tools.SHA256 { return nil, errors.Errorf("hash mismatch for %s", tools.URL) } // Cache tarball in tools storage before returning. metadata := binarystorage.Metadata{ Version: v.String(), Size: tools.Size, SHA256: tools.SHA256, } if err := stor.Add(bytes.NewReader(data), metadata); err != nil { return nil, errors.Annotate(err, "error caching tools") } return ioutil.NopCloser(bytes.NewReader(data)), nil }