config.go 3.87 KB
Newer Older
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
1 2 3
package config

import (
4 5 6 7
	"crypto"
	"crypto/x509"
	"encoding/base64"
	"errors"
8
	"os"
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
9
	"path/filepath"
10 11

	u "github.com/jbenet/go-ipfs/util"
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
12 13
)

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
14
// Identity tracks the configuration of the local node's identity.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
15
type Identity struct {
16
	PeerID  string
17
	PrivKey string
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
18 19
}

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
20
// Datastore tracks the configuration of the datastore.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
21
type Datastore struct {
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
22 23
	Type string
	Path string
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
24 25
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
26 27 28 29 30 31
// Addresses stores the (string) multiaddr addresses for the node.
type Addresses struct {
	Swarm string // address for the swarm network
	API   string // address for the local API (RPC)
}

32 33 34 35 36 37
// Mounts stores the (string) mount points
type Mounts struct {
	IPFS string
	IPNS string
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
38 39
// BootstrapPeer is a peer used to bootstrap the network.
type BootstrapPeer struct {
40
	Address string
41
	PeerID  string // until multiaddr supports ipfs, use another field.
42 43
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
44 45 46 47
func (bp *BootstrapPeer) String() string {
	return bp.Address + "/" + bp.PeerID
}

Juan Batiz-Benet's avatar
go lint  
Juan Batiz-Benet committed
48
// Config is used to load IPFS config files.
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
49
type Config struct {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
50 51 52
	Identity  Identity         // local node's peer identity
	Datastore Datastore        // local node's storage
	Addresses Addresses        // local node's addresses
53
	Mounts    Mounts           // local node's mount points
54
	Version   Version          // local node's version management
55
	Bootstrap []*BootstrapPeer // local nodes's bootstrap peers
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
56 57
}

Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
58
// DefaultPathRoot is the path to the default config dir location.
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
59
const DefaultPathRoot = "~/.go-ipfs"
Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
60 61

// DefaultConfigFile is the filename of the configuration file
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
62
const DefaultConfigFile = "config"
Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
63 64

// DefaultDataStoreDirectory is the directory to store all the local IPFS data.
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
65
const DefaultDataStoreDirectory = "datastore"
Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
66 67

// EnvDir is the environment variable used to change the path root.
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
68 69 70 71 72
const EnvDir = "IPFS_DIR"

// PathRoot returns the default configuration root directory
func PathRoot() (string, error) {
	dir := os.Getenv(EnvDir)
73 74
	var err error
	if len(dir) == 0 {
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
75
		dir, err = u.TildeExpansion(DefaultPathRoot)
76 77 78
	}
	return dir, err
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
79

Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
80 81 82
// 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) {
83
	if len(configroot) == 0 {
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
84
		dir, err := PathRoot()
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
85 86 87
		if err != nil {
			return "", err
		}
Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
88
		return filepath.Join(dir, extension), nil
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
89

90
	}
Juan Batiz-Benet's avatar
lint  
Juan Batiz-Benet committed
91
	return filepath.Join(configroot, extension), nil
92
}
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
93

Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
94 95 96
// 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) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
97
	return Path(configroot, DefaultDataStoreDirectory)
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
98 99 100 101 102
}

// 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) {
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
103
	return Path(configroot, DefaultConfigFile)
Shanti Bouchez-Mongardé's avatar
Shanti Bouchez-Mongardé committed
104 105
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
106
// DecodePrivateKey is a helper to decode the users PrivateKey
107 108 109 110 111 112
func (i *Identity) DecodePrivateKey(passphrase string) (crypto.PrivateKey, error) {
	pkb, err := base64.StdEncoding.DecodeString(i.PrivKey)
	if err != nil {
		return nil, err
	}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
113 114
	// currently storing key unencrypted. in the future we need to encrypt it.
	// TODO(security)
115 116 117
	return x509.ParsePKCS1PrivateKey(pkb)
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
118 119
// Load reads given file and returns the read config, or error.
func Load(filename string) (*Config, error) {
120
	// if nothing is there, fail. User must run 'ipfs init'
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
121
	if _, err := os.Stat(filename); os.IsNotExist(err) {
122
		return nil, errors.New("ipfs not initialized, please run 'ipfs init'")
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
123 124 125
	}

	var cfg Config
126
	err := ReadConfigFile(filename, &cfg)
127 128 129 130 131 132
	if err != nil {
		return nil, err
	}

	// tilde expansion on datastore path
	cfg.Datastore.Path, err = u.TildeExpansion(cfg.Datastore.Path)
Juan Batiz-Benet's avatar
gofmt  
Juan Batiz-Benet committed
133 134 135 136 137
	if err != nil {
		return nil, err
	}

	return &cfg, err
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
138
}
139 140 141

// Set sets the value of a particular config key
func Set(filename, key, value string) error {
142
	return WriteConfigKey(filename, key, value)
143
}