// SyncBuiltTools copies to storage a tools tarball and cloned copies for each series. func SyncBuiltTools(stor storage.Storage, builtTools *BuiltTools, fakeSeries ...string) (*coretools.Tools, error) { if err := cloneToolsForSeries(builtTools, fakeSeries...); err != nil { return nil, err } syncContext := &SyncContext{ Source: builtTools.Dir, Target: stor, AllVersions: true, Dev: builtTools.Version.IsDev(), MajorVersion: builtTools.Version.Major, MinorVersion: -1, } logger.Debugf("uploading tools to cloud storage") err := SyncTools(syncContext) if err != nil { return nil, err } url, err := stor.URL(builtTools.StorageName) if err != nil { return nil, err } return &coretools.Tools{ Version: builtTools.Version, URL: url, Size: builtTools.Size, SHA256: builtTools.Sha256Hash, }, nil }
func restoreBootstrapVerificationFile(c *gc.C, stor storage.Storage) { content := "juju-core storage writing verified: ok\n" contentReader := strings.NewReader(content) err := stor.Put("bootstrap-verify", contentReader, int64(len(content))) c.Assert(err, gc.IsNil) }
// CreateStateFile creates an empty state file on the given storage, and // returns its URL. func CreateStateFile(stor storage.Storage) (string, error) { err := putState(stor, []byte{}) if err != nil { return "", fmt.Errorf("cannot create initial state file: %v", err) } return stor.URL(StateFile) }
// RemoveFakeToolsMetadata deletes the fake simplestreams tools metadata from the supplied storage. func RemoveFakeToolsMetadata(c *gc.C, stor storage.Storage) { files := []string{simplestreams.UnsignedIndex, envtools.ProductMetadataPath} for _, file := range files { toolspath := path.Join("tools", file) err := stor.Remove(toolspath) c.Check(err, gc.IsNil) } }
// RemoveTools deletes all tools from the supplied storage. func RemoveTools(c *gc.C, stor storage.Storage) { names, err := storage.List(stor, "tools/releases/juju-") c.Assert(err, gc.IsNil) c.Logf("removing files: %v", names) for _, name := range names { err = stor.Remove(name) c.Check(err, gc.IsNil) } RemoveFakeToolsMetadata(c, stor) }
// VerifyStorage writes the bootstrap init file to the storage to indicate // that the storage is writable. func VerifyStorage(stor storage.Storage) error { reader := strings.NewReader(verificationContent) err := stor.Put(VerificationFilename, reader, int64(len(verificationContent))) if err != nil { logger.Warningf("failed to write bootstrap-verify file: %v", err) return VerifyStorageError } return nil }
func uploadMetadataFile(stor storage.Storage, metadataDir, fileName string, size int64) error { fullSourceFilename := filepath.Join(metadataDir, fileName) logger.Debugf("uploading metadata file %s", fileName) f, err := os.Open(fullSourceFilename) if err != nil { return err } defer f.Close() destMetadataDir := path.Join(storage.BaseImagesPath, simplestreams.StreamsDir) return stor.Put(path.Join(destMetadataDir, fileName), f, size) }
func UseTestImageData(stor storage.Storage, cred *identity.Credentials) { // Put some image metadata files into the public storage. t := template.Must(template.New("").Parse(indexData)) var metadata bytes.Buffer if err := t.Execute(&metadata, cred); err != nil { panic(fmt.Errorf("cannot generate index metdata: %v", err)) } data := metadata.Bytes() stor.Put(simplestreams.DefaultIndexPath+".json", bytes.NewReader(data), int64(len(data))) stor.Put( productMetadatafile, strings.NewReader(imagesData), int64(len(imagesData))) }
func storageCopy(source storage.Storage, sourcePath string, target storage.Storage, targetPath string) error { rc, err := storage.Get(source, sourcePath) if err != nil { return err } var buf bytes.Buffer _, err = io.Copy(&buf, rc) rc.Close() if err != nil { return err } return target.Put(targetPath, &buf, int64(buf.Len())) }
func uploadFakeToolsVersion(stor storage.Storage, vers version.Binary) (*coretools.Tools, error) { logger.Infof("uploading FAKE tools %s", vers) tgz, checksum := coretesting.TarGz( coretesting.NewTarFile("jujud", 0777, "jujud contents "+vers.String())) size := int64(len(tgz)) name := envtools.StorageName(vers) if err := stor.Put(name, bytes.NewReader(tgz), size); err != nil { return nil, err } url, err := stor.URL(name) if err != nil { return nil, err } return &coretools.Tools{URL: url, Version: vers, Size: size, SHA256: checksum}, nil }
// RemoveFakeTools deletes the fake tools from the supplied storage. func RemoveFakeTools(c *gc.C, stor storage.Storage) { c.Logf("removing fake tools") toolsVersion := version.Current name := envtools.StorageName(toolsVersion) err := stor.Remove(name) c.Check(err, gc.IsNil) defaultSeries := coretesting.FakeDefaultSeries if version.Current.Series != defaultSeries { toolsVersion.Series = defaultSeries name := envtools.StorageName(toolsVersion) err := stor.Remove(name) c.Check(err, gc.IsNil) } RemoveFakeToolsMetadata(c, stor) }
// copyOneToolsPackage copies one tool from the source to the target. func copyOneToolsPackage(tool *coretools.Tools, dest storage.Storage) error { toolsName := envtools.StorageName(tool.Version) logger.Infof("copying %v", toolsName) resp, err := utils.GetValidatingHTTPClient().Get(tool.URL) if err != nil { return err } buf := &bytes.Buffer{} srcFile := resp.Body defer srcFile.Close() tool.SHA256, tool.Size, err = utils.ReadSHA256(io.TeeReader(srcFile, buf)) if err != nil { return err } sizeInKB := (tool.Size + 512) / 1024 logger.Infof("downloaded %v (%dkB), uploading", toolsName, sizeInKB) logger.Infof("download %dkB, uploading", sizeInKB) return dest.Put(toolsName, buf, tool.Size) }
// writeMetadata generates some basic simplestreams metadata using the specified cloud and image details and writes // it to the supplied store. func writeMetadata(metadata []*ImageMetadata, cloudSpec []simplestreams.CloudSpec, metadataStore storage.Storage) error { index, products, err := MarshalImageMetadataJSON(metadata, cloudSpec, time.Now()) if err != nil { return err } metadataInfo := []MetadataFile{ {simplestreams.UnsignedIndex, index}, {ProductMetadataPath, products}, } for _, md := range metadataInfo { err = metadataStore.Put( filepath.Join(storage.BaseImagesPath, md.Path), bytes.NewReader(md.Data), int64(len(md.Data))) if err != nil { return err } } return nil }
// WriteMetadata writes the given tools metadata to the given storage. func WriteMetadata(stor storage.Storage, metadata []*ToolsMetadata, writeMirrors ShouldWriteMirrors) error { updated := time.Now() index, products, err := MarshalToolsMetadataJSON(metadata, updated) if err != nil { return err } metadataInfo := []MetadataFile{ {simplestreams.UnsignedIndex, index}, {ProductMetadataPath, products}, } if writeMirrors { mirrorsUpdated := updated.Format("20060102") // YYYYMMDD mirrorsInfo := strings.Replace(PublicMirrorsInfo, "{{updated}}", mirrorsUpdated, -1) metadataInfo = append(metadataInfo, MetadataFile{simplestreams.UnsignedMirror, []byte(mirrorsInfo)}) } for _, md := range metadataInfo { logger.Infof("Writing %s", "tools/"+md.Path) err = stor.Put(path.Join(storage.BaseToolsPath, md.Path), bytes.NewReader(md.Data), int64(len(md.Data))) if err != nil { return err } } return nil }
func checkRemoveAll(c *gc.C, stor storage.Storage) { contents := []byte("File contents.") aFile := "a-file.txt" err := stor.Put(aFile, bytes.NewBuffer(contents), int64(len(contents))) c.Assert(err, gc.IsNil) err = stor.Put("empty-file", bytes.NewBuffer(nil), 0) c.Assert(err, gc.IsNil) err = stor.RemoveAll() c.Assert(err, gc.IsNil) files, err := storage.List(stor, "") c.Assert(err, gc.IsNil) c.Check(files, gc.HasLen, 0) _, err = storage.Get(stor, aFile) c.Assert(err, gc.NotNil) c.Check(err, gc.ErrorMatches, fmt.Sprintf("file %q not found", aFile)) }
// UploadToStorage uploads tools and metadata for the specified versions to storage. func UploadToStorage(c *gc.C, stor storage.Storage, versions ...version.Binary) map[version.Binary]string { uploaded := map[version.Binary]string{} if len(versions) == 0 { return uploaded } var err error for _, vers := range versions { filename := fmt.Sprintf("tools/releases/tools-%s.tar.gz", vers.String()) // Put a file in images since the dummy storage provider requires a // file to exist before the URL can be found. This is to ensure it behaves // the same way as MAAS. err = stor.Put(filename, strings.NewReader("dummy"), 5) c.Assert(err, gc.IsNil) uploaded[vers], err = stor.URL(filename) c.Assert(err, gc.IsNil) } objects := generateMetadata(c, versions...) for _, object := range objects { toolspath := path.Join("tools", object.path) err = stor.Put(toolspath, bytes.NewReader(object.data), int64(len(object.data))) c.Assert(err, gc.IsNil) } return uploaded }
// DeleteStateFile deletes the state file on the given storage. func DeleteStateFile(stor storage.Storage) error { return stor.Remove(StateFile) }
func RemoveTestImageData(stor storage.Storage) { stor.Remove(simplestreams.DefaultIndexPath + ".json") stor.Remove(productMetadatafile) }