func (c *initCmd) clientConfigFromServer() (*clientconfig.Config, error) { if c.noconfig { log.Print("--userpass and --noconfig are mutually exclusive") return nil, cmdmain.ErrUsage } server := client.ExplicitServer() if server == "" { log.Print("--userpass requires --server") return nil, cmdmain.ErrUsage } fields := strings.Split(c.userPass, ":") if len(fields) != 2 { log.Printf("wrong userpass; wanted username:password, got %q", c.userPass) return nil, cmdmain.ErrUsage } cl := client.NewFromParams(server, auth.NewBasicAuth(fields[0], fields[1]), client.OptionInsecure(c.insecureTLS)) helpRoot, err := cl.HelpRoot() if err != nil { return nil, err } var cc clientconfig.Config if err := cl.GetJSON(helpRoot+"?clientConfig=true", &cc); err != nil { return nil, err } return &cc, nil }
func (c *syncCmd) syncAll() error { if c.loop { return cmdmain.UsageError("--all can't be used with --loop") } if c.third != "" { return cmdmain.UsageError("--all can't be used with --thirdleg") } if c.dest != "" { return cmdmain.UsageError("--all can't be used with --dest") } dc := c.discoClient() dc.SetLogger(c.logger) syncHandlers, err := dc.SyncHandlers() if err != nil { return fmt.Errorf("sync handlers discovery failed: %v", err) } if c.verbose { log.Printf("To be synced:\n") for _, sh := range syncHandlers { log.Printf("%v -> %v", sh.From, sh.To) } } for _, sh := range syncHandlers { from := client.New(sh.From, client.OptionInsecure(c.insecureTLS)) from.SetLogger(c.logger) if err := from.SetupAuth(); err != nil { return fmt.Errorf("could not setup auth for connecting to %v: %v", sh.From, err) } to := client.New(sh.To, client.OptionInsecure(c.insecureTLS)) to.SetLogger(c.logger) if err := to.SetupAuth(); err != nil { return fmt.Errorf("could not setup auth for connecting to %v: %v", sh.To, err) } if c.verbose { log.Printf("Now syncing: %v -> %v", sh.From, sh.To) } stats, err := c.doPass(from, to, nil) if c.verbose { log.Printf("sync stats, blobs: %d, bytes %d\n", stats.BlobsCopied, stats.BytesCopied) } if err != nil { return err } } return nil }
// which is one of "src", "dest", or "thirdleg" func (c *syncCmd) storageFromParam(which storageType, val string) (blobserver.Storage, error) { var httpClient *http.Client if val == "" { switch which { case storageThird: return nil, nil case storageSource: discl := c.discoClient() discl.SetLogger(c.logger) src, err := discl.BlobRoot() if err != nil { return nil, fmt.Errorf("Failed to discover source server's blob path: %v", err) } val = src httpClient = discl.HTTPClient() } if val == "" { return nil, cmdmain.UsageError("No --" + string(which) + " flag value specified") } } if which == storageDest && val == "stdout" { return nil, nil } if looksLikePath(val) { disk, err := localdisk.New(val) if err != nil { return nil, fmt.Errorf("Interpreted --%v=%q as a local disk path, but got error: %v", which, val, err) } c.oneIsDisk = true return disk, nil } cl := client.New(val, client.OptionInsecure(c.insecureTLS)) if httpClient != nil { cl.SetHTTPClient(httpClient) } if err := cl.SetupAuth(); err != nil { return nil, fmt.Errorf("could not setup auth for connecting to %v: %v", val, err) } cl.SetLogger(c.logger) serverKeyID, err := cl.ServerKeyID() if err != nil && err != client.ErrNoSigning { fmt.Fprintf(cmdmain.Stderr, "Failed to discover keyId for server %v: %v", val, err) } else { if which == storageSource { c.srcKeyID = serverKeyID } else if which == storageDest { c.destKeyID = serverKeyID } } return cl, nil }
func main() { client.AddFlags() flag.Parse() if *flagVersion { fmt.Fprintf(os.Stderr, "camget version: %s\n", buildinfo.Version()) return } if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } var cl *client.Client var items []*blobref.BlobRef if *flagShared != "" { if client.ExplicitServer() != "" { log.Fatal("Can't use --shared with an explicit blobserver; blobserver is implicit from the --shared URL.") } if flag.NArg() != 0 { log.Fatal("No arguments permitted when using --shared") } cl1, target, err := client.NewFromShareRoot(*flagShared, client.OptionInsecure(*flagInsecureTLS)) if err != nil { log.Fatal(err) } cl = cl1 items = append(items, target) } else { cl = client.NewOrFail() for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br := blobref.Parse(arg) if br == nil { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } items = append(items, br) } } cl.InsecureTLS = *flagInsecureTLS tr := cl.TransportForConfig(&client.TransportConfig{ Verbose: *flagHTTP, }) httpStats, _ := tr.(*httputil.StatsTransport) cl.SetHTTPClient(&http.Client{Transport: tr}) diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if *flagVerbose { log.Printf("Using temp blob cache directory %s", diskCacheFetcher.Root) } for _, br := range items { if *flagGraph { printGraph(diskCacheFetcher, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { rc, err = schema.NewFileReader(diskCacheFetcher, br) if err == nil { rc.(*schema.FileReader).LoadAllChunks() } } else { rc, err = fetch(diskCacheFetcher, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } } else { if err := smartFetch(diskCacheFetcher, *flagOutput, br); err != nil { log.Fatal(err) } } } if *flagVerbose { log.Printf("HTTP requests: %d\n", httpStats.Requests()) } }
// discoClient returns a client initialized with a server // based from --src or from the configuration file if --src // is blank. The returned client can then be used to discover // the blobRoot and syncHandlers. func (c *syncCmd) discoClient() *client.Client { cl := newClient(c.src, client.OptionInsecure(c.insecureTLS)) cl.SetLogger(c.logger) return cl }
func main() { client.AddFlags() flag.Parse() if *cmdmain.FlagHelp { flag.PrintDefaults() } if *flagVersion { fmt.Fprintf(os.Stderr, "camget version: %s\n", buildinfo.Version()) return } if *cmdmain.FlagLegal { cmdmain.PrintLicenses() return } if *flagGraph && flag.NArg() != 1 { log.Fatalf("The --graph option requires exactly one parameter.") } var cl *client.Client var items []blob.Ref optTransportConfig := client.OptionTransportConfig(&client.TransportConfig{ Verbose: *flagHTTP, }) if *flagShared != "" { if client.ExplicitServer() != "" { log.Fatal("Can't use --shared with an explicit blobserver; blobserver is implicit from the --shared URL.") } if flag.NArg() != 0 { log.Fatal("No arguments permitted when using --shared") } cl1, target, err := client.NewFromShareRoot(*flagShared, client.OptionInsecure(*flagInsecureTLS), client.OptionTrustedCert(*flagTrustedCert), optTransportConfig, ) if err != nil { log.Fatal(err) } cl = cl1 items = append(items, target) } else { if *flagTrustedCert != "" { log.Fatal("Can't use --cert without --shared.") } cl = client.NewOrFail(client.OptionInsecure(*flagInsecureTLS), optTransportConfig) for n := 0; n < flag.NArg(); n++ { arg := flag.Arg(n) br, ok := blob.Parse(arg) if !ok { log.Fatalf("Failed to parse argument %q as a blobref.", arg) } items = append(items, br) } } httpStats := cl.HTTPStats() diskCacheFetcher, err := cacher.NewDiskCache(cl) if err != nil { log.Fatalf("Error setting up local disk cache: %v", err) } defer diskCacheFetcher.Clean() if *flagVerbose { log.Printf("Using temp blob cache directory %s", diskCacheFetcher.Root) } if *flagShared != "" { diskCacheFetcher.SetCacheHitHook(func(br blob.Ref, rc io.ReadCloser) (io.ReadCloser, error) { var buf bytes.Buffer if err := cl.UpdateShareChain(br, io.TeeReader(rc, &buf)); err != nil { rc.Close() return nil, err } return struct { io.Reader io.Closer }{io.MultiReader(&buf, rc), rc}, nil }) } for _, br := range items { if *flagGraph { printGraph(diskCacheFetcher, br) return } if *flagCheck { // TODO: do HEAD requests checking if the blobs exists. log.Fatal("not implemented") return } if *flagOutput == "-" { var rc io.ReadCloser var err error if *flagContents { rc, err = schema.NewFileReader(diskCacheFetcher, br) if err == nil { rc.(*schema.FileReader).LoadAllChunks() } } else { rc, err = fetch(diskCacheFetcher, br) } if err != nil { log.Fatal(err) } defer rc.Close() if _, err := io.Copy(os.Stdout, rc); err != nil { log.Fatalf("Failed reading %q: %v", br, err) } } else { if err := smartFetch(diskCacheFetcher, *flagOutput, br); err != nil { log.Fatal(err) } } } if *flagVerbose { log.Printf("HTTP requests: %d\n", httpStats.Requests()) h1, h2 := httpStats.ProtoVersions() log.Printf(" responses: %d (h1), %d (h2)\n", h1, h2) } }