Skip to content

Commit 9d87b9e

Browse files
Give each migration its own binary (#116)
Fully isolated migrations Each migration is a separate module that includes all dependencies vendored into it. * Convert each ipfs-X-to-Y to a go module * Rename each ipfs-X-to-Y to fs-repo-X-to-Y * Move sharness tests into migration modules * Update README.md to describe how to create migration * Redesigned fs-repo-migrations binary to orchestrate, download, and execute the individual migrations * The `fs-repo-migrations version` command prints latest migration available * Added tools module for common migration code * Updated sharness tests to use newer ipfs-update and test it for migrations Co-authored-by: Adin Schmahmann <[email protected]>
1 parent 5ecf0c7 commit 9d87b9e

File tree

7,624 files changed

+429105
-750898
lines changed

Some content is hidden

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

7,624 files changed

+429105
-750898
lines changed

.gitignore

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
fs-repo-migrations
2-
ipfs-0-to-1/ipfs-0-to-1
3-
ipfs-1-to-2/ipfs-1-to-2
4-
ipfs-10-to-11/ipfs-10-to-11
5-
sharness/bin/*
61
*~
2+
cmd/fs-repo-migrations/fs-repo-migrations
3+
sharness/bin/fs-repo-migrations
4+
sharness/bin/fs-repo-*-to-*
5+
sharness/bin/go-sleep
6+
sharness/bin/ipfs-update
7+
sharness/bin/iptb
8+
sharness/bin/pollEndpoint
9+
sharness/bin/random-files
10+
sharness/BUILD-OPTIONS
11+
sharness/lib/sharness/
12+
sharness/test-results/
13+
sharness/trash directory.*.sh/

Makefile

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,43 @@
11
GO111MODULE = on
22

3-
install:
4-
go install -mod=vendor
5-
@echo "fs-repo-migrations now installed, type 'fs-repo-migrations' to run"
3+
MIG_DIRS = $(shell ls -d fs-repo-*-to-*)
64

7-
test: test_go sharness
5+
.PHONY: all build clean cmd sharness test test_go
6+
7+
all: build
8+
9+
show: $(MIG_DIRS)
10+
@echo "$(MIG_DIRS)"
11+
12+
build: $(shell ls -d fs-repo-*-to-* | sed -e 's/fs-repo/build.fs-repo/') cmd
13+
@echo OK
14+
15+
build.%: MIGRATION=$*
16+
build.%:
17+
make -C $(MIGRATION)
18+
19+
cmd: fs-repo-migrations/fs-repo-migrations
820

9-
test_go:
10-
go build -mod=vendor
11-
go test -mod=vendor $(shell go list ./... | grep -v /gx/)
21+
fs-repo-migrations/fs-repo-migrations:
22+
cd fs-repo-migrations && go build
1223

1324
sharness:
1425
make -C sharness
1526

16-
.PHONY: test test_go sharness
27+
test: test_go sharness
28+
29+
clean: $(shell ls -d fs-repo-*-to-* | sed -e 's/fs-repo/clean.fs-repo/')
30+
@make -C sharness clean
31+
@cd fs-repo-migrations && go clean
32+
@echo OK
33+
34+
clean.%: MIGRATION=$*
35+
clean.%:
36+
make -C $(MIGRATION) clean
37+
38+
test_go: $(shell ls -d fs-repo-*-to-* | sed -e 's/fs-repo/test_go.fs-repo/')
39+
@echo OK
40+
41+
test_go.%: MIGRATION=$*
42+
test_go.%:
43+
@cd $(MIGRATION) && go test -mod=vendor

README.md

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
66
[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
77

8-
> Migrations for the filesystem repository of ipfs clients
8+
> Migrations for the filesystem repository of ipfs nodes
99
10-
These are migrations for the filesystem repository of [ipfs](https://github.com/ipfs/ipfs) clients. This tool is written in Go, and developed alongside [go-ipfs](https://github.com/ipfs/go-ipfs), but it should work with any repo conforming to the [fs-repo specs](https://github.com/ipfs/specs/tree/master/repo/fs-repo).
10+
These are migrations for the filesystem repository of [ipfs](https://github.com/ipfs/ipfs) nodes. Each migration builds a separate binary that converts a repository to the next version. The `fs-repo-migrations` is a tool that downloads individual migrations from the ipfs distribution site and applies them in sequence to migrate the ipfs repository to the target version. This tool is written in Go, and developed alongside [go-ipfs](https://github.com/ipfs/go-ipfs).
1111

1212
## Table of Contents
1313

@@ -30,24 +30,23 @@ make install
3030

3131
### When should I migrate
3232

33-
When you want to upgrade go-ipfs to a new version, you may need to
34-
migrate.
35-
36-
Here is the table showing which repo version corresponds to which
37-
go-ipfs version:
38-
39-
ipfs repo version | go-ipfs versions
40-
----------------- | ----------------
41-
1 | 0.0.0 - 0.2.3
42-
2 | 0.3.0 - 0.3.11
43-
3 | 0.4.0 - 0.4.2
44-
4 | 0.4.3 - 0.4.5
45-
5 | 0.4.6 - 0.4.10
46-
6 | 0.4.11 - 0.4.15
47-
7 | 0.4.16 - 0.4.23
48-
8 | 0.5.0 - 0.6.0
49-
9 | 0.5.0 - 0.6.0
50-
10 | 0.6.0 - current
33+
When you want to upgrade go-ipfs to a new version, you may need to migrate.
34+
35+
Here is the table showing which repo version corresponds to which go-ipfs version:
36+
37+
| ipfs repo version | go-ipfs versions |
38+
| ----------------: | :--------------- |
39+
| 1 | 0.0.0 - 0.2.3. |
40+
| 2 | 0.3.0 - 0.3.11 |
41+
| 3 | 0.4.0 - 0.4.2 |
42+
| 4 | 0.4.3 - 0.4.5 |
43+
| 5 | 0.4.6 - 0.4.10 |
44+
| 6 | 0.4.11 - 0.4.15 |
45+
| 7 | 0.4.16 - 0.4.23 |
46+
| 8 | 0.5.0 - 0.6.0 |
47+
| 9 | 0.5.0 - 0.6.0 |
48+
| 10 | 0.6.0 - 0.7.0 |
49+
| 11 | 0.8.0 - current |
5150

5251
### How to Run Migrations
5352

@@ -62,9 +61,15 @@ Migrations are one of those things that can be extremely painful on users. At th
6261
- Frozen. After the tool is written, all code must be frozen and vendored.
6362
- To Spec. The tools must conform to the spec.
6463

64+
#### Build and Test
65+
66+
To create a new migration, create a go module in a directory named `fs-repo-X-to-Y`, where `X` is the repo "from" version and `Y` the repo "to" version. Vendor the module's dependencies. The build tooling will find this module and build the migration binary.
67+
68+
If the migration directory contains a subdirectory named `sharness`, tests contained in it are run using the sharness test tool. Tests must be named `tNNNN-*.sh`, where NNNN is a 4-digit sequence number.
69+
6570
### Dependencies
6671

67-
Dependencies must be vendored independently for each migration. Unfortunately, dependencies _must not_ be vendored using go modules because we need to support multiple versions of the same dependency (for different migrations).
72+
Dependencies must be vendored independently for each migration. Each migration is a separate go module with its own `vendor` directory (created with `go mod vendor` for that migration). All migrations are built using `go build -mod=vendor` to ensure dependencies come from the module's `vendor` directory.
6873

6974
## Contribute
7075

fs-repo-0-to-1/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fs-repo-0-to-1

fs-repo-0-to-1/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.PHONY: build clean
2+
3+
build:
4+
go build -mod=vendor
5+
6+
clean:
7+
go clean

fs-repo-0-to-1/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/ipfs/fs-repo-migrations/fs-repo-0-to-1
2+
3+
go 1.15
4+
5+
require github.com/ipfs/fs-repo-migrations/tools v0.0.0-20210323144402-297a63449538

fs-repo-0-to-1/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/ipfs/fs-repo-migrations/tools v0.0.0-20210323144402-297a63449538 h1:8LgAkWkawtm+fmqziG/1q/JjctLgMdaySQOfFsZYvv0=
2+
github.com/ipfs/fs-repo-migrations/tools v0.0.0-20210323144402-297a63449538/go.mod h1:fADeaHKxwS+SKhc52rsL0P1MUcnyK31a9AcaG0KcfY8=

fs-repo-0-to-1/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+
mg0 "github.com/ipfs/fs-repo-migrations/fs-repo-0-to-1/migration"
5+
migrate "github.com/ipfs/fs-repo-migrations/tools/go-migrate"
6+
)
7+
8+
func main() {
9+
m := &mg0.Migration{}
10+
migrate.Main(m)
11+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package mg0
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
lock "github.com/ipfs/fs-repo-migrations/fs-repo-0-to-1/repolock"
9+
migrate "github.com/ipfs/fs-repo-migrations/tools/go-migrate"
10+
mfsr "github.com/ipfs/fs-repo-migrations/tools/mfsr"
11+
)
12+
13+
type Migration struct {
14+
}
15+
16+
// Version is the int version number. This could be a string
17+
// in future versions
18+
func (m Migration) Versions() string {
19+
return "0-to-1"
20+
}
21+
22+
// Reversible returns whether this migration can be reverted.
23+
// Endeavor to make them all reversible. This is here only to warn users
24+
// in case this is not the case.
25+
func (m Migration) Reversible() bool {
26+
return true
27+
}
28+
29+
// Apply applies the migration in question.
30+
// This migration merely adds a version file.
31+
func (m Migration) Apply(opts migrate.Options) error {
32+
repolk, err := lock.Lock(opts.Path)
33+
if err != nil {
34+
return err
35+
}
36+
defer repolk.Close()
37+
38+
repo := mfsr.RepoPath(opts.Path)
39+
40+
// first, check if there is a version file.
41+
// if there is, bail out.
42+
if v, err := repo.Version(); err == nil {
43+
return fmt.Errorf("repo at %s is version %s (not 0)", opts.Path, v)
44+
} else if !strings.Contains(err.Error(), "no version file in repo") {
45+
return err
46+
}
47+
48+
// add the version file
49+
if err := repo.WriteVersion("1"); err != nil {
50+
return err
51+
}
52+
53+
if opts.Verbose {
54+
fmt.Println("wrote version file")
55+
}
56+
57+
fmt.Println("Migration 0 to 1 succeeded")
58+
return nil
59+
}
60+
61+
// Revert un-applies the migration in question. This should be best-effort.
62+
// Some migrations are definitively one-way. If so, return an error.
63+
func (m Migration) Revert(opts migrate.Options) error {
64+
lk, err := lock.Lock(opts.Path)
65+
if err != nil {
66+
return err
67+
}
68+
defer lk.Close()
69+
70+
repo := mfsr.RepoPath(opts.Path)
71+
72+
repolk, err := lock.Lock(opts.Path)
73+
if err != nil {
74+
return err
75+
}
76+
defer repolk.Close()
77+
78+
if err := repo.CheckVersion("1"); err != nil {
79+
return err
80+
}
81+
82+
// remove the version file
83+
if err := os.Remove(repo.VersionFile()); err != nil {
84+
return err
85+
}
86+
if opts.Verbose {
87+
fmt.Println("deleted version file")
88+
}
89+
90+
return nil
91+
}

fs-repo-0-to-1/repolock/lock.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package lock
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"path"
7+
8+
"github.com/ipfs/fs-repo-migrations/tools/lock"
9+
)
10+
11+
var errRepoLock = `failed to acquire repo lock at %s/%s
12+
Is a daemon running? please stop it before running migration`
13+
14+
// LockFile is the filename of the daemon lock, relative to config dir
15+
// TODO rename repo lock and hide name
16+
const LockFile = "daemon.lock"
17+
18+
func Lock(confdir string) (io.Closer, error) {
19+
c, err := lock.Lock(path.Join(confdir, LockFile))
20+
if err != nil {
21+
return nil, fmt.Errorf(errRepoLock, confdir, LockFile)
22+
}
23+
return c, nil
24+
}

0 commit comments

Comments
 (0)