diff --git a/core/coreapi/client/client.go b/core/coreapi/client/client.go new file mode 100644 index 0000000000000000000000000000000000000000..e45ea2dd5b80a5d8ea9475b109dc14c1ef0aaba6 --- /dev/null +++ b/core/coreapi/client/client.go @@ -0,0 +1,146 @@ +package client + +import ( + "context" + "fmt" + "io" + "io/ioutil" + "os" + + config "github.com/ipfs/go-ipfs-config" + "github.com/ipfs/go-ipfs-http-client" + "github.com/ipfs/interface-go-ipfs-core" + "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" + + "github.com/ipfs/go-ipfs/core" + "github.com/ipfs/go-ipfs/core/coreapi" + "github.com/ipfs/go-ipfs/repo/fsrepo" +) + +const ( + DefaultPathName = ".ipfs" + DefaultPathRoot = "~/" + DefaultPathName + EnvDir = "IPFS_PATH" +) + +func repo() (string, error) { + baseDir := os.Getenv(EnvDir) + if baseDir == "" { + baseDir = DefaultPathRoot + } + return homedir.Expand(baseDir) +} + +////////////////////// + +type ManagedApi interface { + iface.CoreAPI + + io.Closer +} + +type ctxApi struct { + iface.CoreAPI + context.CancelFunc +} + +func (a *ctxApi) Close() error { + a.CancelFunc() + return nil +} + +var _ ManagedApi = &ctxApi{} + +////////////////////// + +func embedded(repoPath string) (ManagedApi, error) { + ctx, cancel := context.WithCancel(context.TODO()) + + r, err := fsrepo.Open(repoPath) + if err != nil { + return nil, fmt.Errorf("opening fsrepo failed: %s", err) + } + n, err := core.NewNode(ctx, &core.BuildCfg{ + Online: true, + Repo: r, + }) + if err != nil { + return nil, fmt.Errorf("ipfs NewNode() failed: %s", err) + } + + api, err := coreapi.NewCoreAPI(n) + if err != nil { + return nil, err + } + + return &ctxApi{ + CoreAPI: api, + CancelFunc: cancel, + }, nil +} + +type ApiProvider func() (ManagedApi, error) + +var localApi ApiProvider = func() (ManagedApi, error) { + api, err := httpapi.NewLocalApi() + if err != nil { + return nil, err + } + + return &ctxApi{ + CoreAPI: api, + CancelFunc: func() {}, + }, nil +} + +var tempEmbedded ApiProvider = func() (ManagedApi, error) { + dir, err := ioutil.TempDir("", "ipfs-shell") + if err != nil { + return nil, fmt.Errorf("failed to get temp dir: %s", err) + } + + cfg, err := config.Init(ioutil.Discard, 1024) + if err != nil { + return nil, err + } + + err = fsrepo.Init(dir, cfg) + if err != nil { + return nil, fmt.Errorf("failed to init ephemeral node: %s", err) + } + + return embedded(dir) +} + +var localEmbedded ApiProvider = func() (ManagedApi, error) { + repoPath, err := repo() + if err != nil { + return nil, err + } + + return embedded(repoPath) +} + +// TODO: socket activation? 'manual' daemon spawning? +// TODO: repo (config?) option to tell apps to not spawn embedded nodes + +// New creates new api client +func New() (iface.CoreAPI, error) { + api, err := localApi() + if api != nil || err != nil { + return api, err + } + + api, err = localEmbedded() + if api != nil || err != nil { + return api, err + } + + api, err = tempEmbedded() + if api != nil || err != nil { + return api, err + } + + return nil, errors.New("failed to create a node") +} diff --git a/go.mod b/go.mod index e4a786324944b525fd8a80db1c8ebb15cc6870d2..b832967a6a0a4ded75406a4438fcdd87b4aaf6d2 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/ipfs/go-ipfs-exchange-interface v0.0.1 github.com/ipfs/go-ipfs-exchange-offline v0.0.1 github.com/ipfs/go-ipfs-files v0.0.2 + github.com/ipfs/go-ipfs-http-client v0.0.1 github.com/ipfs/go-ipfs-posinfo v0.0.1 github.com/ipfs/go-ipfs-routing v0.0.1 github.com/ipfs/go-ipfs-util v0.0.1 @@ -121,3 +122,5 @@ require ( ) go 1.12 + +replace github.com/ipfs/go-ipfs-cmds => /home/magik6k/gohack/github.com/ipfs/go-ipfs-cmds diff --git a/go.sum b/go.sum index c9ddecf6d1231f8b724892765dbe1519bc56bb4b..89a8446f702463fd04c3fac42f0b15df2b2bf6b6 100644 --- a/go.sum +++ b/go.sum @@ -203,6 +203,8 @@ github.com/ipfs/go-ipfs-files v0.0.2 h1:fEEjF4H+1t8SFOHqUGp0KqcwgIRlbD2bu8CAS2sI github.com/ipfs/go-ipfs-files v0.0.2/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= github.com/ipfs/go-ipfs-flags v0.0.1 h1:OH5cEkJYL0QgA+bvD55TNG9ud8HA2Nqaav47b2c/UJk= github.com/ipfs/go-ipfs-flags v0.0.1/go.mod h1:RnXBb9WV53GSfTrSDVK61NLTFKvWc60n+K9EgCDh+rA= +github.com/ipfs/go-ipfs-http-client v0.0.1 h1:2AGO925+f7f83S5QQpKtBwDQit7hH8NDrb9tPBjseJA= +github.com/ipfs/go-ipfs-http-client v0.0.1/go.mod h1:KUugPfd9tyvRg9U4flMs4//ERbR4b5+kZA6kWmTkThs= github.com/ipfs/go-ipfs-posinfo v0.0.1 h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs= github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= github.com/ipfs/go-ipfs-pq v0.0.1 h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU= @@ -245,10 +247,13 @@ github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2 github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= github.com/ipfs/hang-fds v0.0.1 h1:KGAxiGtJPT3THVRNT6yxgpdFPeX4ZemUjENOt6NlOn4= github.com/ipfs/hang-fds v0.0.1/go.mod h1:U4JNbzwTpk/qP2Ms4VgrZ4HcgJGVosBJqMXvwe4udSY= +github.com/ipfs/interface-go-ipfs-core v0.0.1/go.mod h1:CbFOGVGV8B4NCA0fAO2VVZ1Jt/ZQYE3FzTC6nLVqiAE= +github.com/ipfs/interface-go-ipfs-core v0.0.6/go.mod h1:VceUOYu+kPEy8Ev/gAhzXFTIfc/7xILKnL4fgZg8tZM= github.com/ipfs/interface-go-ipfs-core v0.0.7 h1:KfPVykJTT2viS/NdIC7xUEmnS9jDufl3FXivatAxtZM= github.com/ipfs/interface-go-ipfs-core v0.0.7/go.mod h1:VceUOYu+kPEy8Ev/gAhzXFTIfc/7xILKnL4fgZg8tZM= github.com/ipfs/iptb v1.4.0 h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo= github.com/ipfs/iptb v1.4.0/go.mod h1:1rzHpCYtNp87/+hTxG5TfCVn/yMY3dKnLn8tBiMfdmg= +github.com/ipfs/iptb-plugins v0.0.1/go.mod h1:QUOnRv+dUB7wi+qAHha8E3nI9S3JYdsBHe/5mH0dTTI= github.com/ipfs/iptb-plugins v0.0.2 h1:JZp4h/+7f00dY4Epr8gzF+VqKITXmVGsZabvmZp7E9I= github.com/ipfs/iptb-plugins v0.0.2/go.mod h1:Vud+X6lHv5QlgVbqCPBHt91I0gPIRgmkD6/tMUsI07U= github.com/jackpal/gateway v1.0.4 h1:LS5EHkLuQ6jzaHwULi0vL+JO0mU/n4yUtK8oUjHHOlM= @@ -319,6 +324,7 @@ github.com/libp2p/go-libp2p-autonat v0.0.3 h1:PUD+pAx8Qs9hh+Bowzxq8RCkg/Vwrz5oCF github.com/libp2p/go-libp2p-autonat v0.0.3/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= github.com/libp2p/go-libp2p-autonat v0.0.4 h1:cZzdB9KW1ZkHnSjLCB6aFNw47XS4r+SecCVMuVB1xgo= github.com/libp2p/go-libp2p-autonat v0.0.4/go.mod h1:fs71q5Xk+pdnKU014o2iq1RhMs9/PMaG5zXRFNnIIT4= +github.com/libp2p/go-libp2p-autonat-svc v0.0.1/go.mod h1:S/z0LPmQ36tW6sa66pnt+JXvISOXWMucLn13Si8KAJs= github.com/libp2p/go-libp2p-autonat-svc v0.0.2 h1:beAUwqt3wHWlguz1EYdG+bVOKyf5SIQpXfTSnfGoW7k= github.com/libp2p/go-libp2p-autonat-svc v0.0.2/go.mod h1:j4iMiw0d3diRm5iB0noXumtb0mPvWrM1qAyh640cp8w= github.com/libp2p/go-libp2p-autonat-svc v0.0.5 h1:bTom7QFAkJMXiA8ibSsKQ2+LKEHsXZz2IAWYolg/YYg= @@ -333,6 +339,7 @@ github.com/libp2p/go-libp2p-connmgr v0.0.1 h1:9KP7UbP4a6fauLw954LhTGfovhkmMwvJsI github.com/libp2p/go-libp2p-connmgr v0.0.1/go.mod h1:eUBBlbuwBBTd/eim7KV5x0fOD2UHDjSwhzmBL6miIx8= github.com/libp2p/go-libp2p-crypto v0.0.1 h1:JNQd8CmoGTohO/akqrH16ewsqZpci2CbgYH/LmYl8gw= github.com/libp2p/go-libp2p-crypto v0.0.1/go.mod h1:yJkNyDmO341d5wwXxDUGO0LykUVT72ImHNUqh5D/dBE= +github.com/libp2p/go-libp2p-daemon v0.0.1/go.mod h1:xIEq+QccxuNBnViBKh4WEht8e76pVwa9rHkulsNGmaw= github.com/libp2p/go-libp2p-daemon v0.0.6/go.mod h1:nkhjsjSzkF+tg6iScsTTgq9m+VfyMtXNpycYG4CFvC8= github.com/libp2p/go-libp2p-discovery v0.0.1 h1:VkjCKmJQMwpDUwtA8Qc1z3TQAHJgQ5nGQ6cdN0wQXOw= github.com/libp2p/go-libp2p-discovery v0.0.1/go.mod h1:ZkkF9xIFRLA1xCc7bstYFkd80gBGK8Fc1JqGoU2i+zI= @@ -344,6 +351,7 @@ github.com/libp2p/go-libp2p-interface-connmgr v0.0.1 h1:Q9EkNSLAOF+u90L88qmE9z/f github.com/libp2p/go-libp2p-interface-connmgr v0.0.1/go.mod h1:GarlRLH0LdeWcLnYM/SaBykKFl9U5JFnbBGruAk/D5k= github.com/libp2p/go-libp2p-interface-pnet v0.0.1 h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8= github.com/libp2p/go-libp2p-interface-pnet v0.0.1/go.mod h1:el9jHpQAXK5dnTpKA4yfCNBZXvrzdOU75zz+C6ryp3k= +github.com/libp2p/go-libp2p-kad-dht v0.0.3/go.mod h1:RX/LjLbKnZHDt+3ecSUbk1ycOhyVpMtIUL47rSBTVW0= github.com/libp2p/go-libp2p-kad-dht v0.0.4/go.mod h1:oaBflOQcuC8H+SVV0YN26H6AS+wcUEJyjUGV66vXuSY= github.com/libp2p/go-libp2p-kad-dht v0.0.10 h1:3B8yv3QSdL4M2RRP5biK7YQEngxf2/wdNIQtVBHu6hA= github.com/libp2p/go-libp2p-kad-dht v0.0.10/go.mod h1:RVllrB76xoaayqqBkLmXT8iIkMRNfLWSBuqAggP7W00=