// Move moves an object stored at sourcePath to destPath, removing the // original object. func (d *driver) Move(context ctx.Context, sourcePath string, destPath string) error { prefix := d.pathToDirKey(sourcePath) gcsContext := d.context(context) keys, err := d.listAll(gcsContext, prefix) if err != nil { return err } if len(keys) > 0 { destPrefix := d.pathToDirKey(destPath) copies := make([]string, 0, len(keys)) sort.Strings(keys) var err error for _, key := range keys { dest := destPrefix + key[len(prefix):] _, err = storage.CopyObject(gcsContext, d.bucket, key, d.bucket, dest, nil) if err == nil { copies = append(copies, dest) } else { break } } // if an error occurred, attempt to cleanup the copies made if err != nil { for i := len(copies) - 1; i >= 0; i-- { _ = storage.DeleteObject(gcsContext, d.bucket, copies[i]) } return err } // delete originals for i := len(keys) - 1; i >= 0; i-- { err2 := storage.DeleteObject(gcsContext, d.bucket, keys[i]) if err2 != nil { err = err2 } } return err } _, err = storage.CopyObject(gcsContext, d.bucket, d.pathToKey(sourcePath), d.bucket, d.pathToKey(destPath), nil) if err != nil { if status := err.(*googleapi.Error); status != nil { if status.Code == http.StatusNotFound { return storagedriver.PathNotFoundError{Path: sourcePath} } } return err } return storage.DeleteObject(gcsContext, d.bucket, d.pathToKey(sourcePath)) }
func storageCopyObject(context context.Context, srcBucket, srcName string, destBucket, destName string, attrs *storage.ObjectAttrs) (*storage.Object, error) { var obj *storage.Object err := retry(5, func() error { var err error obj, err = storage.CopyObject(context, srcBucket, srcName, destBucket, destName, attrs) return err }) return obj, err }
func ExampleCopyObject() { ctx := Example_auth() o, err := storage.CopyObject(ctx, "bucketname", "file1", "another-bucketname", "file2", nil) if err != nil { log.Fatal(err) } log.Println("copied file:", o) }
// Rename implements part of the VFS interface. func (s FS) Rename(ctx context.Context, oldPath, newPath string) error { if _, err := storage.CopyObject(ctx, s.Bucket, oldPath, s.Bucket, newPath, &storage.ObjectAttrs{ ContentType: "application/octet-stream", }); err != nil { return fmt.Errorf("error copying file during rename: %v", err) } if err := storage.DeleteObject(ctx, s.Bucket, oldPath); err != nil { return fmt.Errorf("error deleting old file during rename: %v", err) } return nil }
// copyFile copies a file in Google Cloud Storage. func (d *demo) copyFile(fileName string) { copyName := fileName + "-copy" fmt.Fprintf(d.w, "Copying file /%v/%v to /%v/%v:\n", bucket, fileName, bucket, copyName) obj, err := storage.CopyObject(d.ctx, bucket, fileName, bucket, copyName, nil) if err != nil { d.errorf("copyFile: unable to copy /%v/%v to bucket %q, file %q: %v", bucket, fileName, bucket, copyName, err) return } d.cleanUp = append(d.cleanUp, copyName) d.dumpStats(obj) }
// copyFile copies a file in Google Cloud Storage. func (d *demo) copyFile(fileName string) { copyName := fileName + "-copy" fmt.Fprintf(d.w, "Copying file /%v/%v to /%v/%v:\n", bucket, fileName, bucket, copyName) attrs := storage.ObjectAttrs{ Name: copyName, ContentType: "text/plain", Metadata: map[string]string{ "x-goog-meta-foo-copy": "foo-copy", "x-goog-meta-bar-copy": "bar-copy", }, } obj, err := storage.CopyObject(d.ctx, bucket, fileName, bucket, attrs) if err != nil { d.errorf("copyFile: unable to copy /%v/%v to bucket %q, file %q: %v", bucket, fileName, bucket, copyName, err) return } d.cleanUp = append(d.cleanUp, copyName) d.dumpStats(obj) }
func uploadDockerImage() { proj := "camlistore-website" bucket := "camlistore-release" versionedTarball := "docker/camlistored-" + *rev + ".tar.gz" tarball := "docker/camlistored.tar.gz" log.Printf("Uploading %s/%s ...", bucket, versionedTarball) ts, err := tokenSource(bucket) if err != nil { log.Fatal(err) } httpClient := oauth2.NewClient(oauth2.NoContext, ts) ctx := cloud.NewContext(proj, httpClient) w := storage.NewWriter(ctx, bucket, versionedTarball) // If you don't give the owners access, the web UI seems to // have a bug and doesn't have access to see that it's public, so // won't render the "Shared Publicly" link. So we do that, even // though it's dumb and unnecessary otherwise: acl := append(w.ACL, storage.ACLRule{Entity: storage.ACLEntity("project-owners-" + proj), Role: storage.RoleOwner}) acl = append(acl, storage.ACLRule{Entity: storage.AllUsers, Role: storage.RoleReader}) w.ACL = acl w.CacheControl = "no-cache" // TODO: remove for non-tip releases? set expirations? w.ContentType = "application/x-gtar" dockerSave := exec.Command("docker", "save", serverImage) dockerSave.Stderr = os.Stderr tar, err := dockerSave.StdoutPipe() if err != nil { log.Fatal(err) } targz, pw := io.Pipe() go func() { zw := gzip.NewWriter(pw) n, err := io.Copy(zw, tar) if err != nil { log.Fatalf("Error copying to gzip writer: after %d bytes, %v", n, err) } if err := zw.Close(); err != nil { log.Fatalf("gzip.Close: %v", err) } pw.CloseWithError(err) }() if err := dockerSave.Start(); err != nil { log.Fatalf("Error starting docker save %v: %v", serverImage, err) } if _, err := io.Copy(w, targz); err != nil { log.Fatalf("io.Copy: %v", err) } if err := w.Close(); err != nil { log.Fatalf("closing GCS storage writer: %v", err) } if err := dockerSave.Wait(); err != nil { log.Fatalf("Error waiting for docker save %v: %v", serverImage, err) } log.Printf("Uploaded tarball to %s", versionedTarball) log.Printf("Copying tarball to %s/%s ...", bucket, tarball) // TODO(mpl): 2015-05-12: update google.golang.org/cloud/storage so we // can specify the dest name in CopyObject, and we get the ACLs from the // src for free too I think. if _, err := storage.CopyObject(ctx, bucket, versionedTarball, bucket, storage.ObjectAttrs{ Name: tarball, ACL: acl, ContentType: "application/x-gtar", }); err != nil { log.Fatalf("Error uploading %v: %v", tarball, err) } log.Printf("Uploaded tarball to %s", tarball) }