// updateApply applies an update of the ipfs binary and shuts down the node if successful func updateApply(n *core.IpfsNode) (*UpdateOutput, error) { // TODO: 'force bool' param that stops the daemon (if running) before update output := &UpdateOutput{ OldVersion: updates.Version, } u, err := updates.CheckForUpdate() if err != nil { return nil, err } if u == nil { output.NewVersion = updates.Version return output, nil } output.NewVersion = u.Version if n.OnlineMode() { return nil, errors.New(`You must stop the IPFS daemon before updating.`) } if err = updates.Apply(u); err != nil { return nil, err } return output, nil }
func AddMetadataTo(n *core.IpfsNode, skey string, m *ft.Metadata) (string, error) { ukey := key.B58KeyDecode(skey) nd, err := n.DAG.Get(n.Context(), ukey) if err != nil { return "", err } mdnode := new(dag.Node) mdata, err := ft.BytesForMetadata(m) if err != nil { return "", err } mdnode.Data = mdata if err := mdnode.AddNodeLinkClean("file", nd); err != nil { return "", err } nk, err := n.DAG.Add(mdnode) if err != nil { return "", err } return nk.B58String(), nil }
// printing self is special cased as we get values differently. func printSelf(node *core.IpfsNode) (interface{}, error) { info := new(IdOutput) info.ID = node.Identity.Pretty() if node.PrivateKey == nil { if err := node.LoadPrivateKey(); err != nil { return nil, err } } pk := node.PrivateKey.GetPublic() pkb, err := ic.MarshalPublicKey(pk) if err != nil { return nil, err } info.PublicKey = base64.StdEncoding.EncodeToString(pkb) if node.PeerHost != nil { for _, a := range node.PeerHost.Addrs() { s := a.String() + "/ipfs/" + info.ID info.Addresses = append(info.Addresses, s) } } info.ProtocolVersion = identify.IpfsVersion info.AgentVersion = identify.ClientVersion return info, nil }
func Cat(n *core.IpfsNode, pstr string) (*uio.DagReader, error) { p := path.FromString(pstr) dagNode, err := n.Resolver.ResolvePath(n.Context(), p) if err != nil { return nil, err } return uio.NewDagReader(n.Context(), dagNode, n.DAG) }
func addNode(n *core.IpfsNode, node *merkledag.Node) error { if err := n.DAG.AddRecursive(node); err != nil { // add the file to the graph + local storage return err } ctx, cancel := context.WithCancel(n.Context()) defer cancel() err := n.Pinning.Pin(ctx, node, true) // ensure we keep it return err }
func Dial(nd *core.IpfsNode, p peer.ID, protocol string) (net.Stream, error) { ctx, cancel := context.WithTimeout(nd.Context(), time.Second*30) defer cancel() err := nd.PeerHost.Connect(ctx, peer.PeerInfo{ID: p}) if err != nil { return nil, err } return nd.PeerHost.NewStream(pro.ID(protocol), p) }
func Metadata(n *core.IpfsNode, skey string) (*ft.Metadata, error) { ukey := key.B58KeyDecode(skey) nd, err := n.DAG.Get(n.Context(), ukey) if err != nil { return nil, err } return ft.MetadataFromBytes(nd.Data) }
func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error { handler, err := makeHandler(node, lis, options...) if err != nil { return err } addr, err := manet.FromNetAddr(lis.Addr()) if err != nil { return err } // if the server exits beforehand var serverError error serverExited := make(chan struct{}) node.Process().Go(func(p goprocess.Process) { serverError = http.Serve(lis, handler) close(serverExited) }) // wait for server to exit. select { case <-serverExited: // if node being closed before server exits, close server case <-node.Process().Closing(): log.Infof("server at %s terminating...", addr) lis.Close() outer: for { // wait until server exits select { case <-serverExited: // if the server exited as we are closing, we really dont care about errors serverError = nil break outer case <-time.After(5 * time.Second): log.Infof("waiting for server at %s to terminate...", addr) } } } log.Infof("server at %s terminated", addr) return serverError }
func Listen(nd *core.IpfsNode, protocol string) (*ipfsListener, error) { ctx, cancel := context.WithCancel(nd.Context()) list := &ipfsListener{ proto: pro.ID(protocol), conCh: make(chan net.Stream), ctx: ctx, cancel: cancel, } nd.PeerHost.SetStreamHandler(list.proto, func(s net.Stream) { select { case list.conCh <- s: case <-ctx.Done(): s.Close() } }) return list, nil }