master
go 143 lines 3.02 KB
Raw
1 package dagcmd
2
3 import (
4 "bytes"
5 "fmt"
6
7 blocks "github.com/ipfs/go-block-format"
8 "github.com/ipfs/go-cid"
9 ipldlegacy "github.com/ipfs/go-ipld-legacy"
10 "github.com/ipfs/kubo/config"
11 "github.com/ipfs/kubo/core/commands/cmdenv"
12 "github.com/ipfs/kubo/core/commands/cmdutils"
13 "github.com/ipld/go-ipld-prime/multicodec"
14 basicnode "github.com/ipld/go-ipld-prime/node/basic"
15
16 "github.com/ipfs/boxo/files"
17 cmds "github.com/ipfs/go-ipfs-cmds"
18 ipld "github.com/ipfs/go-ipld-format"
19 mc "github.com/multiformats/go-multicodec"
20
21 // Expected minimal set of available format/ienc codecs.
22 _ "github.com/ipld/go-codec-dagpb"
23 _ "github.com/ipld/go-ipld-prime/codec/cbor"
24 _ "github.com/ipld/go-ipld-prime/codec/dagcbor"
25 _ "github.com/ipld/go-ipld-prime/codec/dagjson"
26 _ "github.com/ipld/go-ipld-prime/codec/json"
27 _ "github.com/ipld/go-ipld-prime/codec/raw"
28 )
29
30 func dagPut(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
31 api, err := cmdenv.GetApi(env, req)
32 if err != nil {
33 return err
34 }
35
36 nd, err := cmdenv.GetNode(env)
37 if err != nil {
38 return err
39 }
40
41 cfg, err := nd.Repo.Config()
42 if err != nil {
43 return err
44 }
45
46 inputCodec, _ := req.Options["input-codec"].(string)
47 storeCodec, _ := req.Options["store-codec"].(string)
48 hash, _ := req.Options["hash"].(string)
49 dopin, _ := req.Options["pin"].(bool)
50
51 if hash == "" {
52 hash = cfg.Import.HashFunction.WithDefault(config.DefaultHashFunction)
53 }
54
55 var icodec mc.Code
56 if err := icodec.Set(inputCodec); err != nil {
57 return err
58 }
59 var scodec mc.Code
60 if err := scodec.Set(storeCodec); err != nil {
61 return err
62 }
63 var mhType mc.Code
64 if err := mhType.Set(hash); err != nil {
65 return err
66 }
67
68 cidPrefix := cid.Prefix{
69 Version: 1,
70 Codec: uint64(scodec),
71 MhType: uint64(mhType),
72 MhLength: -1,
73 }
74
75 decoder, err := multicodec.LookupDecoder(uint64(icodec))
76 if err != nil {
77 return err
78 }
79 encoder, err := multicodec.LookupEncoder(uint64(scodec))
80 if err != nil {
81 return err
82 }
83
84 var adder ipld.NodeAdder = api.Dag()
85 if dopin {
86 adder = api.Dag().Pinning()
87 }
88 b := ipld.NewBatch(req.Context, adder)
89
90 it := req.Files.Entries()
91 for it.Next() {
92 file := files.FileFromEntry(it)
93 if file == nil {
94 return fmt.Errorf("expected a regular file")
95 }
96
97 node := basicnode.Prototype.Any.NewBuilder()
98 if err := decoder(node, file); err != nil {
99 return err
100 }
101 n := node.Build()
102
103 bd := bytes.NewBuffer([]byte{})
104 if err := encoder(n, bd); err != nil {
105 return err
106 }
107
108 blockCid, err := cidPrefix.Sum(bd.Bytes())
109 if err != nil {
110 return err
111 }
112 blk, err := blocks.NewBlockWithCid(bd.Bytes(), blockCid)
113 if err != nil {
114 return err
115 }
116 ln := ipldlegacy.LegacyNode{
117 Block: blk,
118 Node: n,
119 }
120
121 if err := cmdutils.CheckBlockSize(req, uint64(bd.Len())); err != nil {
122 return err
123 }
124
125 if err := b.Add(req.Context, &ln); err != nil {
126 return err
127 }
128
129 cid := ln.Cid()
130 if err := res.Emit(&OutputObject{Cid: cid}); err != nil {
131 return err
132 }
133 }
134 if it.Err() != nil {
135 return it.Err()
136 }
137
138 if err := b.Commit(); err != nil {
139 return err
140 }
141
142 return nil
143 }