func getUsedTools(model description.Model) []params.SerializedModelTools { // Iterate through the model for all tools, and make a map of them. usedVersions := make(map[version.Binary]bool) // It is most likely that the preconditions will limit the number of // tools versions in use, but that is not relied on here. for _, machine := range model.Machines() { addToolsVersionForMachine(machine, usedVersions) } for _, application := range model.Applications() { for _, unit := range application.Units() { tools := unit.Tools() usedVersions[tools.Version()] = true } } out := make([]params.SerializedModelTools, 0, len(usedVersions)) for v := range usedVersions { out = append(out, params.SerializedModelTools{ Version: v.String(), URI: common.ToolsURL("", v), }) } return out }
// handleUpload uploads the tools data from the reader to env storage as the specified version. func (h *toolsUploadHandler) handleUpload(r io.Reader, toolsVersions []version.Binary, serverRoot string, st *state.State) (*tools.Tools, error) { // Check if changes are allowed and the command may proceed. blockChecker := common.NewBlockChecker(st) if err := blockChecker.ChangeAllowed(); err != nil { return nil, errors.Trace(err) } storage, err := st.ToolsStorage() if err != nil { return nil, err } defer storage.Close() // Read the tools tarball from the request, calculating the sha256 along the way. data, sha256, err := readAndHash(r) if err != nil { return nil, err } if len(data) == 0 { return nil, errors.BadRequestf("no tools uploaded") } // TODO(wallyworld): check integrity of tools tarball. // Store tools and metadata in tools storage. for _, v := range toolsVersions { metadata := binarystorage.Metadata{ Version: v.String(), Size: int64(len(data)), SHA256: sha256, } logger.Debugf("uploading tools %+v to storage", metadata) if err := storage.Add(bytes.NewReader(data), metadata); err != nil { return nil, err } } tools := &tools.Tools{ Version: toolsVersions[0], Size: int64(len(data)), SHA256: sha256, URL: common.ToolsURL(serverRoot, toolsVersions[0]), } return tools, nil }
// handleUpload uploads the tools data from the reader to env storage as the specified version. func (h *toolsUploadHandler) handleUpload(r io.Reader, toolsVersions []version.Binary, serverRoot string) (*tools.Tools, error) { storage, err := h.state.ToolsStorage() if err != nil { return nil, err } defer storage.Close() // Read the tools tarball from the request, calculating the sha256 along the way. data, sha256, err := readAndHash(r) if err != nil { return nil, err } if len(data) == 0 { return nil, errors.New("no tools uploaded") } // TODO(wallyworld): check integrity of tools tarball. // Store tools and metadata in toolstorage. for _, v := range toolsVersions { metadata := toolstorage.Metadata{ Version: v, Size: int64(len(data)), SHA256: sha256, } logger.Debugf("uploading tools %+v to storage", metadata) if err := storage.AddTools(bytes.NewReader(data), metadata); err != nil { return nil, err } } tools := &tools.Tools{ Version: toolsVersions[0], Size: int64(len(data)), SHA256: sha256, URL: common.ToolsURL(serverRoot, toolsVersions[0]), } return tools, nil }