Skip to content

Commit 964ea3a

Browse files
Merge pull request #49 from ipfs/kevina/4-to-5
4-to-5 migration improvments
2 parents 4d03c6f + 986d5e2 commit 964ea3a

File tree

4 files changed

+137
-12
lines changed

4 files changed

+137
-12
lines changed

go-migrate/cli.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
)
88

99
type Flags struct {
10-
Force bool
11-
Revert bool
12-
Path string // file path to migrate for fs based migrations
13-
Verbose bool
14-
Help bool
10+
Force bool
11+
Revert bool
12+
Path string // file path to migrate for fs based migrations
13+
Verbose bool
14+
Help bool
15+
NoRevert bool
1516
}
1617

1718
func (f *Flags) Setup() {
@@ -20,6 +21,11 @@ func (f *Flags) Setup() {
2021
flag.BoolVar(&f.Verbose, "verbose", false, "enable verbose logging")
2122
flag.BoolVar(&f.Help, "help", false, "display help message")
2223
flag.StringVar(&f.Path, "path", "", "file path to migrate for fs based migrations (required)")
24+
flag.BoolVar(&f.NoRevert, "no-revert", false, "do not attempt to automatically revert on failure")
25+
}
26+
27+
var SupportNoRevert = map[string]bool{
28+
"4-to-5": true,
2329
}
2430

2531
func (f *Flags) Parse() {
@@ -43,13 +49,17 @@ func Run(m Migration) error {
4349

4450
if !m.Reversible() {
4551
if f.Revert {
46-
return fmt.Errorf("migration %d is irreversible", m.Versions())
52+
return fmt.Errorf("migration %s is irreversible", m.Versions())
4753
}
4854
if !f.Force {
49-
return fmt.Errorf("migration %d is irreversible (use -f to proceed)", m.Versions())
55+
return fmt.Errorf("migration %s is irreversible (use -f to proceed)", m.Versions())
5056
}
5157
}
5258

59+
if f.NoRevert && !SupportNoRevert[m.Versions()] {
60+
return fmt.Errorf("migration %s does not support the '-no-revert' option", m.Versions())
61+
}
62+
5363
if f.Revert {
5464
return m.Revert(Options{
5565
Flags: f,

ipfs-4-to-5/migration/migration.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,22 @@ func (m Migration) Apply(opts migrate.Options) error {
5353
basepath := filepath.Join(opts.Path, "blocks")
5454
ffspath := filepath.Join(opts.Path, "blocks-v4")
5555
if err := os.Rename(basepath, ffspath); err != nil {
56-
return err
56+
if os.IsNotExist(err) {
57+
fi, err2 := os.Stat(ffspath)
58+
if err2 == nil && fi.IsDir() {
59+
log.Log("... blocks already renamed to blocks-v4, continuing")
60+
err = nil
61+
}
62+
}
63+
if err != nil {
64+
return err
65+
}
5766
}
5867

5968
revert1 := func(e error) error {
69+
if opts.NoRevert {
70+
return e
71+
}
6072
err := os.Rename(ffspath, basepath)
6173
if err != nil {
6274
log.Error(err)
@@ -66,20 +78,38 @@ func (m Migration) Apply(opts migrate.Options) error {
6678

6779
log.Log("> Upgrading datastore format to have sharding specification file")
6880
if err := flatfs.UpgradeV0toV1(ffspath, 5); err != nil {
69-
return revert1(err)
81+
if os.IsExist(err) {
82+
id, err2 := flatfs.ReadShardFunc(ffspath)
83+
if err2 == nil && id.String() == flatfs.Prefix(5).String() {
84+
log.Log("... datastore already has sharding specification file, continuing")
85+
err = nil
86+
}
87+
}
88+
if err != nil {
89+
return revert1(err)
90+
}
7091
}
7192

7293
tempffs := filepath.Join(opts.Path, "blocks-v5")
7394
log.Log("> creating a new flatfs datastore with new format")
7495
if err := flatfs.Create(tempffs, flatfs.NextToLast(2)); err != nil {
75-
if err2 := revertStep2(ffspath); err2 != nil {
76-
log.Error(err2)
96+
if err == flatfs.ErrDatastoreExists {
97+
log.Log("... new flatfs datastore already exists continuing")
98+
err = nil
99+
}
100+
if err != nil {
101+
if err2 := revertStep2(ffspath); err2 != nil {
102+
log.Error(err2)
103+
}
104+
return revert1(err)
77105
}
78-
return revert1(err)
79106
}
80107

81108
revert3 := func(mainerr error) error {
82109
log.Error("failed to convert flatfs datastore: %s", mainerr)
110+
if opts.NoRevert {
111+
return mainerr
112+
}
83113
log.Log("attempting to revert...")
84114

85115
if _, err := os.Stat(filepath.Join(ffspath, "SHARDING")); os.IsNotExist(err) {
@@ -114,6 +144,9 @@ func (m Migration) Apply(opts migrate.Options) error {
114144
}
115145

116146
revert4 := func(mainerr error) error {
147+
if opts.NoRevert {
148+
return mainerr
149+
}
117150
if err := os.Mkdir(ffspath, 0755); err != nil {
118151
log.Error("recreating flatfs directory: %s", err)
119152
return err

sharness/t0080-migration-3-to-4.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ test_expect_success "get pin lists" '
105105

106106
test_kill_ipfs_daemon
107107

108+
test_expect_success "'ipfs-3-to-4 -no-revert' fails" '
109+
test_must_fail ipfs-3-to-4 -no-revert -path="$IPFS_PATH"
110+
'
111+
108112
test_install_ipfs_nd "v0.4.3-dev"
109113

110114
test_launch_ipfs_daemon
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/sh
2+
3+
test_description="Test migration 4 to 5 woth -no-revert"
4+
5+
. lib/test-lib.sh
6+
7+
# setup vars for tests
8+
9+
export IPFS_DIST_PATH="/ipfs/QmRgeXaMTu426NcVvTNywAR7HyFBFGhvRc9FuTtKx3Hfno"
10+
11+
DEPTH=3
12+
NBDIR=3
13+
NBFILE=6
14+
PINTOTAL=20
15+
16+
PINEACH=$(expr $PINTOTAL / 2)
17+
18+
echo "DEPTH: $DEPTH"
19+
echo "NBDIR: $NBDIR"
20+
echo "NBFILE: $NBFILE"
21+
echo "PINTOTAL: $PINTOTAL"
22+
echo "PINEACH: $PINEACH"
23+
24+
export GOPATH="$(pwd)/gopath"
25+
mkdir -p gopath/bin
26+
export PATH="../bin:$GOPATH/bin:$PATH"
27+
28+
test_install_ipfs_nd "v0.4.4"
29+
30+
test_init_ipfs_nd
31+
32+
test_expect_success "make a couple files" '
33+
rm -rf manyfiles &&
34+
random-files -depth=$DEPTH -dirs=$NBDIR -files=$NBFILE manyfiles > filenames
35+
'
36+
37+
test_expect_success "add a few files" '
38+
ipfs add -r -q manyfiles | tee hashes
39+
'
40+
41+
test_expect_success "get full ref list" '
42+
ipfs refs local | sort > start_refs
43+
'
44+
test_expect_success "create a permission problem" '
45+
RANDOM_DIR="`(cd "$IPFS_PATH"/blocks/ && ls -d CI??? | sort | head -3 | tail -1)`" &&
46+
chmod 000 "$IPFS_PATH/blocks/$RANDOM_DIR"
47+
'
48+
49+
test_expect_success "ipfs-4-to-5 -no-revert should fail" '
50+
test_must_fail ipfs-4-to-5 -no-revert -path "$IPFS_PATH"
51+
'
52+
53+
test_expect_success "ipfs-4-to-5 -no-revert leaves repo in inconsistent state" '
54+
test -d "$IPFS_PATH"/blocks-v4 &&
55+
test -d "$IPFS_PATH"/blocks-v5
56+
'
57+
58+
test_expect_success "fix permission problem" '
59+
chmod 700 "$IPFS_PATH/blocks-v4/$RANDOM_DIR"
60+
'
61+
62+
test_expect_success "ipfs-4-to-5 -no-revert should be okay now" '
63+
ipfs-4-to-5 -no-revert -path "$IPFS_PATH"
64+
'
65+
66+
test_install_ipfs_nd "v0.4.5-pre2"
67+
68+
test_expect_success "list all refs after migration" '
69+
ipfs refs local | sort > after_refs
70+
'
71+
72+
test_expect_success "refs look right" '
73+
comm -23 start_refs after_refs > missing_refs &&
74+
touch empty_refs_file &&
75+
test_cmp missing_refs empty_refs_file
76+
'
77+
78+
test_done

0 commit comments

Comments
 (0)