Skip to content

Commit

Permalink
Attempt to read Bootstrap and Peering from config
Browse files Browse the repository at this point in the history
- Peer info is not provided by Migration condif
- Do not fail, but use defaults, if Bootstrap or Peering config is not readable
  • Loading branch information
gammazero committed May 4, 2021
1 parent c4c2097 commit 38d3c36
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 182 deletions.
46 changes: 15 additions & 31 deletions cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,27 +297,16 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
return err
}

keep := migrationCfg.Keep
if keep == "" {
keep = config.DefaultMigrationKeep
fetcher, err = getMigrationFetcher(migrationCfg, &cctx.ConfigRoot)
if err != nil {
return err
}
switch keep {
case "discard":
case "cache":
defer fetcher.Close()

if migrationCfg.Keep == "cache" {
cacheMigrations = true
case "pin":
} else if migrationCfg.Keep == "pin" {
pinMigrations = true
default:
return errors.New("unrecognized value for %s, must be 'cache', 'pin', or 'discard'")
}

dlSources := migrationCfg.DownloadSources
if len(dlSources) == 0 {
dlSources = config.DefaultMigrationDownloadSources
}
fetcher, err = getMigrationFetcher(dlSources, migrationCfg.Peers)
if err != nil {
return err
}

if cacheMigrations || pinMigrations {
Expand All @@ -339,21 +328,9 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
fmt.Printf(" %s\n", err)
fmt.Println("If you think this is a bug, please file an issue and include this whole log output.")
fmt.Println(" https://github.com/ipfs/fs-repo-migrations")
fetcher.Close()
return err
}

if cacheMigrations || pinMigrations {
defer fetcher.Close()
} else {
// If there is an error closing the IpfsFetcher, then print error, but
// do not fail because of it.
err = fetcher.Close()
if err != nil {
log.Errorf("error closing IPFS fetcher: %s", err)
}
}

repo, err = fsrepo.Open(cctx.ConfigRoot)
if err != nil {
return err
Expand Down Expand Up @@ -481,10 +458,17 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
if err != nil {
fmt.Fprintln(os.Stderr, "Could not add migragion to IPFS:", err)
}
fetcher.Close()
os.RemoveAll(migrations.DownloadDirectory)
migrations.DownloadDirectory = ""
}
if fetcher != nil {
// If there is an error closing the IpfsFetcher, then print error, but
// do not fail because of it.
err = fetcher.Close()
if err != nil {
log.Errorf("error closing IPFS fetcher: %s", err)
}
}

// construct http gateway
gwErrc, err := serveHTTPGateway(req, cctx)
Expand Down
88 changes: 72 additions & 16 deletions cmd/ipfs/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,54 +24,110 @@ import (
"github.com/libp2p/go-libp2p-core/peer"
)

// readMigrationConfig reads the migration config out of the config, avoiding reading anything other
// than the migration section. That way, we're free to make arbitrary changes to all _other_
// sections in migrations.
// readMigrationConfig reads the migration config out of the config, avoiding
// reading anything other than the migration section. That way, we're free to
// make arbitrary changes to all _other_ sections in migrations.
func readMigrationConfig(repoRoot string) (*config.Migration, error) {
var cfg struct {
Migration config.Migration
}

cfgPath, err := config.Filename(repoRoot)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, err
}

cfgFile, err := os.Open(cfgPath)
if err != nil {
return nil, err
}

defer cfgFile.Close()

err = json.NewDecoder(cfgFile).Decode(&cfg)
if err != nil {
return nil, err
}

switch cfg.Migration.Keep {
case "":
cfg.Migration.Keep = config.DefaultMigrationKeep
case "discard", "cache", "keep":
default:
return nil, errors.New("unknown config value, Migrations.Keep must be 'cache', 'pin', or 'discard'")
}

if len(cfg.Migration.DownloadSources) == 0 {
cfg.Migration.DownloadSources = config.DefaultMigrationDownloadSources
}

return &cfg.Migration, nil
}

func readIpfsConfig(repoRoot *string) (bootstrap []string, peers []peer.AddrInfo) {
if repoRoot == nil {
return nil, nil
}

cfgPath, err := config.Filename(*repoRoot)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}

cfgFile, err := os.Open(cfgPath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
defer cfgFile.Close()

// Attempt to read bootstrap addresses
var bootstrapCfg struct {
Bootstrap []string
}
err = json.NewDecoder(cfgFile).Decode(&bootstrapCfg)
if err != nil {
fmt.Fprintln(os.Stderr, "cannot read bootstrap peers from config")
} else {
bootstrap = bootstrapCfg.Bootstrap
}

if _, err = cfgFile.Seek(0, 0); err != nil {
fmt.Fprintln(os.Stderr, err)
}

// Attempt to read peers
var peeringCfg struct {
Peering config.Peering
}
err = json.NewDecoder(cfgFile).Decode(&peeringCfg)
if err != nil {
fmt.Fprintln(os.Stderr, "cannot read peering from config")
} else {
peers = peeringCfg.Peering.Peers
}

return
}

// getMigrationFetcher creates one or more fetchers according to
// downloadPolicy.
//
// The downloadPolicy parameter is a comma-separated string. It may contain
// "ipfs" to indicate using the IpfsFetcher and "http" to indicate using the
// HttpFetcher. Any other string is treated as a gateway URL to use with
// another HttpFetcher. If downloadPolicy is is an empty string, then the
// default policy ("http,ipfs")is used.
func getMigrationFetcher(downloadSources []string, peers []peer.AddrInfo) (migrations.Fetcher, error) {
// config.Migration.DownloadSources. If an IpfsFetcher is required, then
// bootstrap and peer information in read from the config file in repoRoot,
// unless repoRoot is nil.
func getMigrationFetcher(cfg *config.Migration, repoRoot *string) (migrations.Fetcher, error) {
const httpUserAgent = "go-ipfs"

// Fetch migrations from current distribution, or location from environ
fetchDistPath := migrations.GetDistPathEnv(migrations.CurrentIpfsDist)

var fetchers []migrations.Fetcher
for _, src := range downloadSources {
for _, src := range cfg.DownloadSources {
src := strings.TrimSpace(src)
switch src {
case "IPFS", "ipfs":
fetchers = append(fetchers, ipfsfetcher.NewIpfsFetcher(fetchDistPath, 0, peers))
bootstrap, peers := readIpfsConfig(repoRoot)
fetchers = append(fetchers, ipfsfetcher.NewIpfsFetcher(fetchDistPath, 0, bootstrap, peers))
case "HTTPS", "https", "HTTP", "http":
fetchers = append(fetchers, migrations.NewHttpFetcher(fetchDistPath, "", httpUserAgent, 0))
default:
Expand All @@ -92,7 +148,7 @@ func getMigrationFetcher(downloadSources []string, peers []peer.AddrInfo) (migra
}
}
if len(fetchers) == 0 {
return nil, errors.New("no fetchers specified")
return nil, errors.New("no sources specified")
}

if len(fetchers) == 1 {
Expand Down Expand Up @@ -230,7 +286,7 @@ func ipfsGet(ctx context.Context, ufs coreiface.UnixfsAPI, ipfsPath ipath.Path)
}
_, err = io.Copy(ioutil.Discard, fnd)
if err != nil {
return fmt.Errorf("could not read migration: %w", err)
return fmt.Errorf("cannot read migration: %w", err)
}
fmt.Printf("Added migration file: %q\n", ipfsPath)
return nil
Expand Down
Loading

0 comments on commit 38d3c36

Please sign in to comment.