Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosmetic fixups in examples #8325

Merged
merged 4 commits into from
Aug 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
2 changes: 2 additions & 0 deletions docs/examples/go-ipfs-as-a-library/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ github.com/ipfs/go-ipfs-keystore v0.0.2 h1:Fa9xg9IFD1VbiZtrNLzsD0GuELVHUFXCWF64k
github.com/ipfs/go-ipfs-keystore v0.0.2/go.mod h1:H49tRmibOEs7gLMgbOsjC4dqh1u5e0R/SWuc2ScfgSo=
github.com/ipfs/go-ipfs-pinner v0.1.1 h1:iJd1gwILGQJSZhhI0jn6yFOLg34Ua7fdKcB6mXp6k/M=
github.com/ipfs/go-ipfs-pinner v0.1.1/go.mod h1:EzyyaWCWeZJ/he9cDBH6QrEkSuRqTRWMmCoyNkylTTg=
github.com/ipfs/go-ipfs-pinner v0.1.2 h1:Ve9OBhL6eg5+tVqEnIhPZOCXDtMjB+OhOohVZxPUxms=
github.com/ipfs/go-ipfs-pinner v0.1.2/go.mod h1:/u9kMe+TyQybN21O5OBicdyx3x93lVI77PCtiTnArUk=
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/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY=
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/go-ipfs-as-a-library/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func main() {

fmt.Println("\n-- Adding and getting back files & directories --")

inputBasePath := "./example-folder/"
inputBasePath := "../example-folder/"
inputPathFile := inputBasePath + "ipfs.paper.draft3.pdf"
inputPathDirectory := inputBasePath + "test-dir"

Expand Down Expand Up @@ -258,7 +258,7 @@ func main() {

/// --- Part III: Getting the file and directory you added back

outputBasePath := "./example-folder/"
outputBasePath := "../example-folder/"
outputPathFile := outputBasePath + strings.Split(cidFile.String(), "/")[2]
outputPathDirectory := outputBasePath + strings.Split(cidDirectory.String(), "/")[2]

Expand Down
15 changes: 15 additions & 0 deletions docs/examples/go-ipfs-with-experimental/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module github.com/ipfs/go-ipfs/examples/go-ipfs-with-experimental

go 1.14
petar marked this conversation as resolved.
Show resolved Hide resolved

require (
github.com/ipfs/go-ipfs v0.7.0
petar marked this conversation as resolved.
Show resolved Hide resolved
github.com/ipfs/go-ipfs-config v0.14.0
github.com/ipfs/go-ipfs-files v0.0.8
github.com/ipfs/interface-go-ipfs-core v0.4.0
github.com/libp2p/go-libp2p-core v0.8.6
github.com/libp2p/go-libp2p-peerstore v0.2.8
github.com/multiformats/go-multiaddr v0.3.3
)

replace github.com/ipfs/go-ipfs => ./../../..
1,648 changes: 1,648 additions & 0 deletions docs/examples/go-ipfs-with-experimental/go.sum

Large diffs are not rendered by default.

354 changes: 354 additions & 0 deletions docs/examples/go-ipfs-with-experimental/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,354 @@
package main
petar marked this conversation as resolved.
Show resolved Hide resolved

import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"sync"

config "github.com/ipfs/go-ipfs-config"
files "github.com/ipfs/go-ipfs-files"
icore "github.com/ipfs/interface-go-ipfs-core"
icorepath "github.com/ipfs/interface-go-ipfs-core/path"
ma "github.com/multiformats/go-multiaddr"

"github.com/ipfs/go-ipfs/core"
"github.com/ipfs/go-ipfs/core/coreapi"
"github.com/ipfs/go-ipfs/core/node/libp2p"
"github.com/ipfs/go-ipfs/plugin/loader" // This package is needed so that all the preloaded plugins are loaded automatically
"github.com/ipfs/go-ipfs/repo/fsrepo"
"github.com/libp2p/go-libp2p-core/peer"
)

/// ------ Setting up the IPFS Repo

func setupPlugins(externalPluginsPath string) error {
// Load any external plugins if available on externalPluginsPath
plugins, err := loader.NewPluginLoader(filepath.Join(externalPluginsPath, "plugins"))
if err != nil {
return fmt.Errorf("error loading plugins: %s", err)
}

// Load preloaded and external plugins
if err := plugins.Initialize(); err != nil {
return fmt.Errorf("error initializing plugins: %s", err)
}

if err := plugins.Inject(); err != nil {
return fmt.Errorf("error initializing plugins: %s", err)
}

return nil
}

func createTempRepo() (string, error) {
repoPath, err := ioutil.TempDir("", "ipfs-shell")
if err != nil {
return "", fmt.Errorf("failed to get temp dir: %s", err)
}

// Create a config with default options and a 2048 bit key
cfg, err := config.Init(ioutil.Discard, 2048)
if err != nil {
return "", err
}

// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-filestore
cfg.Experimental.FilestoreEnabled = true
// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-urlstore
cfg.Experimental.UrlstoreEnabled = true
// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#directory-sharding--hamt
cfg.Experimental.ShardingEnabled = true
// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#ipfs-p2p
cfg.Experimental.Libp2pStreamMounting = true
// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#p2p-http-proxy
cfg.Experimental.P2pHttpProxy = true
// https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#strategic-providing
cfg.Experimental.StrategicProviding = true

// Create the repo with the config
err = fsrepo.Init(repoPath, cfg)
if err != nil {
return "", fmt.Errorf("failed to init ephemeral node: %s", err)
}

return repoPath, nil
}

/// ------ Spawning the node

// Creates an IPFS node and returns its coreAPI
func createNode(ctx context.Context, repoPath string) (icore.CoreAPI, error) {
// Open the repo
repo, err := fsrepo.Open(repoPath)
if err != nil {
return nil, err
}

// Construct the node

nodeOptions := &core.BuildCfg{
Online: true,
Routing: libp2p.DHTOption, // This option sets the node to be a full DHT node (both fetching and storing DHT Records)
// Routing: libp2p.DHTClientOption, // This option sets the node to be a client DHT node (only fetching records)
Repo: repo,
}

node, err := core.NewNode(ctx, nodeOptions)
if err != nil {
return nil, err
}

// Attach the Core API to the constructed node
return coreapi.NewCoreAPI(node)
}

// Spawns a node on the default repo location, if the repo exists
func spawnDefault(ctx context.Context) (icore.CoreAPI, error) {
defaultPath, err := config.PathRoot()
if err != nil {
// shouldn't be possible
return nil, err
}

if err := setupPlugins(defaultPath); err != nil {
return nil, err

}

return createNode(ctx, defaultPath)
}

// Spawns a node to be used just for this run (i.e. creates a tmp repo)
func spawnEphemeral(ctx context.Context) (icore.CoreAPI, error) {
if err := setupPlugins(""); err != nil {
return nil, err
}

// Create a Temporary Repo
repoPath, err := createTempRepo()
if err != nil {
return nil, fmt.Errorf("failed to create temp repo: %s", err)
}

// Spawning an ephemeral IPFS node
return createNode(ctx, repoPath)
}

//

func connectToPeers(ctx context.Context, ipfs icore.CoreAPI, peers []string) error {
var wg sync.WaitGroup
peerInfos := make(map[peer.ID]*peer.AddrInfo, len(peers))
for _, addrStr := range peers {
addr, err := ma.NewMultiaddr(addrStr)
if err != nil {
return err
}
pii, err := peer.AddrInfoFromP2pAddr(addr)
if err != nil {
return err
}
pi, ok := peerInfos[pii.ID]
if !ok {
pi = &peer.AddrInfo{ID: pii.ID}
peerInfos[pi.ID] = pi
}
pi.Addrs = append(pi.Addrs, pii.Addrs...)
}

wg.Add(len(peerInfos))
for _, peerInfo := range peerInfos {
go func(peerInfo *peer.AddrInfo) {
defer wg.Done()
err := ipfs.Swarm().Connect(ctx, *peerInfo)
if err != nil {
log.Printf("failed to connect to %s: %s", peerInfo.ID, err)
}
}(peerInfo)
}
wg.Wait()
return nil
}

func getUnixfsFile(path string) (files.File, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()

st, err := file.Stat()
if err != nil {
return nil, err
}

f, err := files.NewReaderPathFile(path, file, st)
if err != nil {
return nil, err
}

return f, nil
}

func getUnixfsNode(path string) (files.Node, error) {
st, err := os.Stat(path)
if err != nil {
return nil, err
}

f, err := files.NewSerialFile(path, false, st)
if err != nil {
return nil, err
}

return f, nil
}

/// -------

func main() {
/// --- Part I: Getting a IPFS node running

fmt.Println("-- Getting an IPFS node running -- ")

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

/*
// Spawn a node using the default path (~/.ipfs), assuming that a repo exists there already
fmt.Println("Spawning node on default repo")
ipfs, err := spawnDefault(ctx)
if err != nil {
panic(fmt.Errorf("failed to spawnDefault node: %s", err))
}
*/

// Spawn a node using a temporary path, creating a temporary repo for the run
fmt.Println("Spawning node on a temporary repo")
ipfs, err := spawnEphemeral(ctx)
if err != nil {
panic(fmt.Errorf("failed to spawn ephemeral node: %s", err))
}

fmt.Println("IPFS node is running")

/// --- Part II: Adding a file and a directory to IPFS

fmt.Println("\n-- Adding and getting back files & directories --")

inputBasePath := "../example-folder/"
inputPathFile := inputBasePath + "ipfs.paper.draft3.pdf"
inputPathDirectory := inputBasePath + "test-dir"

someFile, err := getUnixfsNode(inputPathFile)
if err != nil {
panic(fmt.Errorf("Could not get File: %s", err))
}

cidFile, err := ipfs.Unixfs().Add(ctx, someFile)
if err != nil {
panic(fmt.Errorf("Could not add File: %s", err))
}

fmt.Printf("Added file to IPFS with CID %s\n", cidFile.String())

someDirectory, err := getUnixfsNode(inputPathDirectory)
if err != nil {
panic(fmt.Errorf("Could not get File: %s", err))
}

cidDirectory, err := ipfs.Unixfs().Add(ctx, someDirectory)
if err != nil {
panic(fmt.Errorf("Could not add Directory: %s", err))
}

fmt.Printf("Added directory to IPFS with CID %s\n", cidDirectory.String())

/// --- Part III: Getting the file and directory you added back

outputBasePath := "../example-folder/"
outputPathFile := outputBasePath + strings.Split(cidFile.String(), "/")[2]
outputPathDirectory := outputBasePath + strings.Split(cidDirectory.String(), "/")[2]

rootNodeFile, err := ipfs.Unixfs().Get(ctx, cidFile)
if err != nil {
panic(fmt.Errorf("Could not get file with CID: %s", err))
}

err = files.WriteTo(rootNodeFile, outputPathFile)
if err != nil {
panic(fmt.Errorf("Could not write out the fetched CID: %s", err))
}

fmt.Printf("Got file back from IPFS (IPFS path: %s) and wrote it to %s\n", cidFile.String(), outputPathFile)

rootNodeDirectory, err := ipfs.Unixfs().Get(ctx, cidDirectory)
if err != nil {
panic(fmt.Errorf("Could not get file with CID: %s", err))
}

err = files.WriteTo(rootNodeDirectory, outputPathDirectory)
if err != nil {
panic(fmt.Errorf("Could not write out the fetched CID: %s", err))
}

fmt.Printf("Got directory back from IPFS (IPFS path: %s) and wrote it to %s\n", cidDirectory.String(), outputPathDirectory)

/// --- Part IV: Getting a file from the IPFS Network

fmt.Println("\n-- Going to connect to a few nodes in the Network as bootstrappers --")

bootstrapNodes := []string{
// IPFS Bootstrapper nodes.
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",

// IPFS Cluster Pinning nodes
"/ip4/138.201.67.219/tcp/4001/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA",
"/ip4/138.201.67.219/udp/4001/quic/p2p/QmUd6zHcbkbcs7SMxwLs48qZVX3vpcM8errYS7xEczwRMA",
"/ip4/138.201.67.220/tcp/4001/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i",
"/ip4/138.201.67.220/udp/4001/quic/p2p/QmNSYxZAiJHeLdkBg38roksAR9So7Y5eojks1yjEcUtZ7i",
"/ip4/138.201.68.74/tcp/4001/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR",
"/ip4/138.201.68.74/udp/4001/quic/p2p/QmdnXwLrC8p1ueiq2Qya8joNvk3TVVDAut7PrikmZwubtR",
"/ip4/94.130.135.167/tcp/4001/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE",
"/ip4/94.130.135.167/udp/4001/quic/p2p/QmUEMvxS2e7iDrereVYc5SWPauXPyNwxcy9BXZrC1QTcHE",

// You can add more nodes here, for example, another IPFS node you might have running locally, mine was:
// "/ip4/127.0.0.1/tcp/4010/p2p/QmZp2fhDLxjYue2RiUvLwT9MWdnbDxam32qYFnGmxZDh5L",
// "/ip4/127.0.0.1/udp/4010/quic/p2p/QmZp2fhDLxjYue2RiUvLwT9MWdnbDxam32qYFnGmxZDh5L",
}

go func() {
err := connectToPeers(ctx, ipfs, bootstrapNodes)
if err != nil {
log.Printf("failed connect to peers: %s", err)
}
}()

exampleCIDStr := "QmUaoioqU7bxezBQZkUcgcSyokatMY71sxsALxQmRRrHrj"

fmt.Printf("Fetching a file from the network with CID %s\n", exampleCIDStr)
outputPath := outputBasePath + exampleCIDStr
testCID := icorepath.New(exampleCIDStr)

rootNode, err := ipfs.Unixfs().Get(ctx, testCID)
if err != nil {
panic(fmt.Errorf("Could not get file with CID: %s", err))
}

err = files.WriteTo(rootNode, outputPath)
if err != nil {
panic(fmt.Errorf("Could not write out the fetched CID: %s", err))
}

fmt.Printf("Wrote the file to %s\n", outputPath)

fmt.Println("\nAll done! You just finalized your first tutorial on how to use go-ipfs as a library")
}