Skip to content

Commit 19f7ac0

Browse files
authored
Merge pull request #72 from ipfs/feat/migrate-6-to-7
Add migration for IPNS record move
2 parents a89e976 + 2bc282a commit 19f7ac0

File tree

1,990 files changed

+614338
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,990 files changed

+614338
-4
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ os:
88
language: go
99

1010
go:
11-
- 1.8.3
11+
- 1.10.2
1212

1313
env:
1414
- TEST_VERBOSE=1

ipfs-6-to-7/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
migrate "github.com/ipfs/fs-repo-migrations/go-migrate"
5+
mg6 "github.com/ipfs/fs-repo-migrations/ipfs-6-to-7/migration"
6+
)
7+
8+
func main() {
9+
m := mg6.Migration{}
10+
migrate.Main(&m)
11+
}

ipfs-6-to-7/migration/migration.go

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package mg6
2+
3+
import (
4+
"fmt"
5+
6+
migrate "github.com/ipfs/fs-repo-migrations/go-migrate"
7+
log "github.com/ipfs/fs-repo-migrations/stump"
8+
9+
dshelp "gx/ipfs/QmTmqJGRQfuH8eKWD1FjThwPRipt1QhqJQNZ8MpzmfAAxo/go-ipfs-ds-help"
10+
record "gx/ipfs/QmUpttFinNDmNPgFwKN8sZK6BUtBmA68Y4KdSBDXa8t9sJ/go-libp2p-record"
11+
dhtpb "gx/ipfs/QmUpttFinNDmNPgFwKN8sZK6BUtBmA68Y4KdSBDXa8t9sJ/go-libp2p-record/pb"
12+
ds "gx/ipfs/QmXRKBQA4wXP7xWbFiZsR1GP4HV6wMDQ1aWFxZZ4uBcPX9/go-datastore"
13+
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
14+
peer "gx/ipfs/QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS/go-libp2p-peer"
15+
ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto"
16+
namesys "gx/ipfs/QmcKwjeebv5SX3VFUGDFa4BNMYhy14RRaCzQP7JN3UQDpB/go-ipfs/namesys"
17+
repo "gx/ipfs/QmcKwjeebv5SX3VFUGDFa4BNMYhy14RRaCzQP7JN3UQDpB/go-ipfs/repo"
18+
fsrepo "gx/ipfs/QmcKwjeebv5SX3VFUGDFa4BNMYhy14RRaCzQP7JN3UQDpB/go-ipfs/repo/fsrepo"
19+
mfsr "gx/ipfs/QmcKwjeebv5SX3VFUGDFa4BNMYhy14RRaCzQP7JN3UQDpB/go-ipfs/repo/fsrepo/migrations"
20+
base32 "gx/ipfs/QmfVj3x4D6Jkq9SEoi5n2NmoUomLwoeiwnYz2KQa15wRw6/base32"
21+
)
22+
23+
type Migration struct{}
24+
25+
func (m Migration) Versions() string {
26+
return "6-to-7"
27+
}
28+
29+
func (m Migration) Reversible() bool {
30+
return true
31+
}
32+
33+
func myKey(r repo.Repo) (ci.PrivKey, error) {
34+
cfg, err := r.Config()
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
sk, err := cfg.Identity.DecodePrivateKey("passphrase todo!")
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
pid, err := peer.IDFromPrivateKey(sk)
45+
if err != nil {
46+
return nil, err
47+
}
48+
idCfg, err := peer.IDB58Decode(cfg.Identity.PeerID)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
if pid != idCfg {
54+
return nil, fmt.Errorf(
55+
"private key in config does not match id: %s != %s",
56+
pid,
57+
idCfg,
58+
)
59+
}
60+
return sk, nil
61+
}
62+
63+
func applyForKey(dstore ds.Datastore, k ci.PrivKey) error {
64+
id, err := peer.IDFromPrivateKey(k)
65+
if err != nil {
66+
return fmt.Errorf("invalid peer ID: %s", err)
67+
}
68+
_, ipns := namesys.IpnsKeysForID(id)
69+
record, err := dstore.Get(dshelp.NewKeyFromBinary([]byte(ipns)))
70+
if err == ds.ErrNotFound {
71+
log.VLog("no IPNS record for key found")
72+
return nil
73+
}
74+
if err != nil {
75+
return fmt.Errorf("datastore error: %s", err)
76+
}
77+
78+
recordbytes, ok := record.([]byte)
79+
if !ok {
80+
return fmt.Errorf("unexpected type returned from datastore: %#v", record)
81+
}
82+
dhtrec := new(dhtpb.Record)
83+
err = proto.Unmarshal(recordbytes, dhtrec)
84+
if err != nil {
85+
return fmt.Errorf("failed to decode DHT record: %s", err)
86+
}
87+
88+
val := dhtrec.GetValue()
89+
newkey := ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id)))
90+
err = dstore.Put(newkey, val)
91+
if err != nil {
92+
return fmt.Errorf("failed to write new IPNS record: %s", err)
93+
}
94+
return nil
95+
}
96+
97+
func (m Migration) Apply(opts migrate.Options) error {
98+
log.Verbose = opts.Verbose
99+
log.Log("applying %s repo migration", m.Versions())
100+
101+
r, err := fsrepo.Open(opts.Path)
102+
if err != nil {
103+
return err
104+
}
105+
defer r.Close()
106+
107+
ks := r.Keystore()
108+
keys, err := ks.List()
109+
if err != nil {
110+
return err
111+
}
112+
113+
dstore := r.Datastore()
114+
115+
sk, err := myKey(r)
116+
if err != nil {
117+
return err
118+
}
119+
120+
log.VLog("migrating IPNS record for key: self")
121+
err = applyForKey(dstore, sk)
122+
if err != nil {
123+
return err
124+
}
125+
126+
for _, keyName := range keys {
127+
log.VLog("migrating IPNS record for key:", keyName)
128+
k, err := ks.Get(keyName)
129+
if err != nil {
130+
return err
131+
}
132+
err = applyForKey(dstore, k)
133+
if err != nil {
134+
return err
135+
}
136+
}
137+
138+
err = mfsr.RepoPath(opts.Path).WriteVersion(7)
139+
if err != nil {
140+
log.Error("failed to update version file to 7")
141+
return err
142+
}
143+
144+
log.Log("updated version file")
145+
146+
return nil
147+
}
148+
149+
func revertForKey(dstore ds.Datastore, sk ci.PrivKey, k ci.PrivKey) error {
150+
id, err := peer.IDFromPrivateKey(k)
151+
if err != nil {
152+
return fmt.Errorf("invalid peer ID: %s", err)
153+
}
154+
155+
_, ipns := namesys.IpnsKeysForID(id)
156+
157+
newkey := ds.NewKey("/ipns/" + base32.RawStdEncoding.EncodeToString([]byte(id)))
158+
val, err := dstore.Get(newkey)
159+
if err == ds.ErrNotFound {
160+
log.VLog("no IPNS record for key found")
161+
return nil
162+
}
163+
if err != nil {
164+
return fmt.Errorf("datastore error: %s", err)
165+
}
166+
value, ok := val.([]byte)
167+
if !ok {
168+
return fmt.Errorf("unexpected type returned from datastore: %#v", val)
169+
}
170+
171+
dhtrec, err := record.MakePutRecord(sk, ipns, value, true)
172+
if err != nil {
173+
return fmt.Errorf("failed to create DHT record: %s", err)
174+
}
175+
176+
data, err := proto.Marshal(dhtrec)
177+
if err != nil {
178+
return fmt.Errorf("failed to marshal DHT record: %s", err)
179+
}
180+
181+
err = dstore.Put(dshelp.NewKeyFromBinary([]byte(ipns)), data)
182+
if err != nil {
183+
return fmt.Errorf("failed to write DHT record: %s", err)
184+
}
185+
return nil
186+
}
187+
188+
func (m Migration) Revert(opts migrate.Options) error {
189+
log.Verbose = opts.Verbose
190+
log.Log("reverting migration")
191+
192+
// We're downgrading from version 7.
193+
fsrepo.RepoVersion = 7
194+
r, err := fsrepo.Open(opts.Path)
195+
fsrepo.RepoVersion = 6
196+
if err != nil {
197+
return err
198+
}
199+
defer r.Close()
200+
201+
log.VLog("decoding private key")
202+
203+
sk, err := myKey(r)
204+
if err != nil {
205+
return err
206+
}
207+
208+
ks := r.Keystore()
209+
keys, err := ks.List()
210+
if err != nil {
211+
return err
212+
}
213+
214+
dstore := r.Datastore()
215+
216+
log.VLog("migrating IPNS record for key: self")
217+
revertForKey(dstore, sk, sk)
218+
219+
for _, keyName := range keys {
220+
log.VLog("migrating IPNS record for key:", keyName)
221+
k, err := ks.Get(keyName)
222+
if err != nil {
223+
return err
224+
}
225+
revertForKey(dstore, sk, k)
226+
}
227+
228+
err = mfsr.RepoPath(opts.Path).WriteVersion(6)
229+
if err != nil {
230+
log.Error("failed to downgrade version file to 6")
231+
return err
232+
}
233+
234+
log.Log("updated version file")
235+
236+
return nil
237+
}

ipfs-6-to-7/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"author": "stebalien",
3+
"bugs": {},
4+
"gx": {
5+
"dvcsimport": "github.com/ipfs/fs-repo-migrations/ipfs-6-to-7"
6+
},
7+
"gxDependencies": [
8+
{
9+
"hash": "QmcKwjeebv5SX3VFUGDFa4BNMYhy14RRaCzQP7JN3UQDpB",
10+
"name": "go-ipfs",
11+
"version": "0.4.15"
12+
},
13+
{
14+
"hash": "QmY1y2M1aCcVhy8UuTbZJBvuFbegZm47f9cDAdgxiehQfx",
15+
"name": "go-libp2p-kad-dht",
16+
"version": "3.0.18"
17+
},
18+
{
19+
"author": "whyrusleeping",
20+
"hash": "QmZoWKhxUmZ2seW4BzX6fJkNR8hh9PsGModr7q171yq2SS",
21+
"name": "go-libp2p-peer",
22+
"version": "2.2.3"
23+
},
24+
{
25+
"author": "jbenet",
26+
"hash": "QmXRKBQA4wXP7xWbFiZsR1GP4HV6wMDQ1aWFxZZ4uBcPX9",
27+
"name": "go-datastore",
28+
"version": "2.4.0"
29+
},
30+
{
31+
"author": "whyrusleeping",
32+
"hash": "QmfVj3x4D6Jkq9SEoi5n2NmoUomLwoeiwnYz2KQa15wRw6",
33+
"name": "base32",
34+
"version": "0.0.2"
35+
},
36+
{
37+
"hash": "QmUpttFinNDmNPgFwKN8sZK6BUtBmA68Y4KdSBDXa8t9sJ",
38+
"name": "go-libp2p-record",
39+
"version": "3.0.2"
40+
}
41+
],
42+
"gxVersion": "0.12.1",
43+
"language": "go",
44+
"license": "MIT",
45+
"name": "ipfs-6-to-7",
46+
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
47+
"version": "0.0.0"
48+
}
49+

0 commit comments

Comments
 (0)