mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 23:42:20 +08:00
220 lines
6.0 KiB
Go
220 lines
6.0 KiB
Go
// package config implements the ipfs config file datastructures and utilities.
|
|
package config
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
|
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
|
|
|
ic "github.com/jbenet/go-ipfs/p2p/crypto"
|
|
u "github.com/jbenet/go-ipfs/util"
|
|
"github.com/jbenet/go-ipfs/util/debugerror"
|
|
)
|
|
|
|
var log = u.Logger("config")
|
|
|
|
// Identity tracks the configuration of the local node's identity.
|
|
type Identity struct {
|
|
PeerID string
|
|
PrivKey string
|
|
}
|
|
|
|
// Logs tracks the configuration of the event logger
|
|
type Logs struct {
|
|
Filename string
|
|
MaxSizeMB uint64
|
|
MaxBackups uint64
|
|
MaxAgeDays uint64
|
|
}
|
|
|
|
// Datastore tracks the configuration of the datastore.
|
|
type Datastore struct {
|
|
Type string
|
|
Path string
|
|
}
|
|
|
|
// Addresses stores the (string) multiaddr addresses for the node.
|
|
type Addresses struct {
|
|
Swarm []string // addresses for the swarm network
|
|
API string // address for the local API (RPC)
|
|
Gateway string // address to listen on for IPFS HTTP object gateway
|
|
}
|
|
|
|
// Mounts stores the (string) mount points
|
|
type Mounts struct {
|
|
IPFS string
|
|
IPNS string
|
|
}
|
|
|
|
// BootstrapPeer is a peer used to bootstrap the network.
|
|
type BootstrapPeer struct {
|
|
Address string
|
|
PeerID string // until multiaddr supports ipfs, use another field.
|
|
}
|
|
|
|
func (bp *BootstrapPeer) String() string {
|
|
return bp.Address + "/" + bp.PeerID
|
|
}
|
|
|
|
func ParseBootstrapPeer(addr string) (BootstrapPeer, error) {
|
|
// to be replaced with just multiaddr parsing, once ptp is a multiaddr protocol
|
|
idx := strings.LastIndex(addr, "/")
|
|
if idx == -1 {
|
|
return BootstrapPeer{}, errors.New("invalid address")
|
|
}
|
|
addrS := addr[:idx]
|
|
peeridS := addr[idx+1:]
|
|
|
|
// make sure addrS parses as a multiaddr.
|
|
if len(addrS) > 0 {
|
|
maddr, err := ma.NewMultiaddr(addrS)
|
|
if err != nil {
|
|
return BootstrapPeer{}, err
|
|
}
|
|
|
|
addrS = maddr.String()
|
|
}
|
|
|
|
// make sure idS parses as a peer.ID
|
|
_, err := mh.FromB58String(peeridS)
|
|
if err != nil {
|
|
return BootstrapPeer{}, err
|
|
}
|
|
|
|
return BootstrapPeer{
|
|
Address: addrS,
|
|
PeerID: peeridS,
|
|
}, nil
|
|
}
|
|
|
|
func ParseBootstrapPeers(addrs []string) ([]BootstrapPeer, error) {
|
|
peers := make([]BootstrapPeer, len(addrs))
|
|
var err error
|
|
for i, addr := range addrs {
|
|
peers[i], err = ParseBootstrapPeer(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return peers, nil
|
|
}
|
|
|
|
// Tour stores the ipfs tour read-list and resume point
|
|
type Tour struct {
|
|
Last string // last tour topic read
|
|
// Done []string // all topics done so far
|
|
}
|
|
|
|
// Config is used to load IPFS config files.
|
|
type Config struct {
|
|
Identity Identity // local node's peer identity
|
|
Datastore Datastore // local node's storage
|
|
Addresses Addresses // local node's addresses
|
|
Mounts Mounts // local node's mount points
|
|
Version Version // local node's version management
|
|
Bootstrap []BootstrapPeer // local nodes's bootstrap peers
|
|
Tour Tour // local node's tour position
|
|
Logs Logs // local node's event log configuration
|
|
}
|
|
|
|
// DefaultPathRoot is the path to the default config dir location.
|
|
const DefaultPathRoot = "~/.go-ipfs"
|
|
|
|
// DefaultConfigFile is the filename of the configuration file
|
|
const DefaultConfigFile = "config"
|
|
|
|
// DefaultDataStoreDirectory is the directory to store all the local IPFS data.
|
|
const DefaultDataStoreDirectory = "datastore"
|
|
|
|
// EnvDir is the environment variable used to change the path root.
|
|
const EnvDir = "IPFS_DIR"
|
|
|
|
// LogsDefaultDirectory is the directory to store all IPFS event logs.
|
|
var LogsDefaultDirectory = "logs"
|
|
|
|
// PathRoot returns the default configuration root directory
|
|
func PathRoot() (string, error) {
|
|
dir := os.Getenv(EnvDir)
|
|
var err error
|
|
if len(dir) == 0 {
|
|
dir, err = u.TildeExpansion(DefaultPathRoot)
|
|
}
|
|
return dir, err
|
|
}
|
|
|
|
// Path returns the path `extension` relative to the configuration root. If an
|
|
// empty string is provided for `configroot`, the default root is used.
|
|
func Path(configroot, extension string) (string, error) {
|
|
if len(configroot) == 0 {
|
|
dir, err := PathRoot()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return filepath.Join(dir, extension), nil
|
|
|
|
}
|
|
return filepath.Join(configroot, extension), nil
|
|
}
|
|
|
|
// DataStorePath returns the default data store path given a configuration root
|
|
// (set an empty string to have the default configuration root)
|
|
func DataStorePath(configroot string) (string, error) {
|
|
return Path(configroot, DefaultDataStoreDirectory)
|
|
}
|
|
|
|
// LogsPath returns the default path for event logs given a configuration root
|
|
// (set an empty string to have the default configuration root)
|
|
func LogsPath(configroot string) (string, error) {
|
|
return Path(configroot, LogsDefaultDirectory)
|
|
}
|
|
|
|
// Filename returns the configuration file path given a configuration root
|
|
// directory. If the configuration root directory is empty, use the default one
|
|
func Filename(configroot string) (string, error) {
|
|
return Path(configroot, DefaultConfigFile)
|
|
}
|
|
|
|
// DecodePrivateKey is a helper to decode the users PrivateKey
|
|
func (i *Identity) DecodePrivateKey(passphrase string) (ic.PrivKey, error) {
|
|
pkb, err := base64.StdEncoding.DecodeString(i.PrivKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// currently storing key unencrypted. in the future we need to encrypt it.
|
|
// TODO(security)
|
|
return ic.UnmarshalPrivateKey(pkb)
|
|
}
|
|
|
|
// Load reads given file and returns the read config, or error.
|
|
func Load(filename string) (*Config, error) {
|
|
// if nothing is there, fail. User must run 'ipfs init'
|
|
if !u.FileExists(filename) {
|
|
return nil, debugerror.New("ipfs not initialized, please run 'ipfs init'")
|
|
}
|
|
|
|
var cfg Config
|
|
err := ReadConfigFile(filename, &cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// tilde expansion on datastore path
|
|
cfg.Datastore.Path, err = u.TildeExpansion(cfg.Datastore.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &cfg, err
|
|
}
|
|
|
|
// Set sets the value of a particular config key
|
|
func Set(filename, key, value string) error {
|
|
return WriteConfigKey(filename, key, value)
|
|
}
|