Skip to content

Commit ea2bc1a

Browse files
authored
Add script to build migrations with datastore plugin (#126)
* Add script to build migration with plugin * Update documentation to tell about build-plugin.sh - README describes how to use the build-plugin.sh script to build a migration with plugins. - Display help with `build-plugin.sh -h` * Update test to use a distribution that is available The distribution at /ipfs/QmaaN2kipZfUpRSzwvUeG4Xi3yp1JJB294Vj8pnZ24hesF is no longer available and this is causing a sharness test to fail. Updated the test to use the current distribution.
1 parent 280b5e7 commit ea2bc1a

File tree

4 files changed

+218
-9
lines changed

4 files changed

+218
-9
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ These are migrations for the filesystem repository of [ipfs](https://github.com/
1616
- [When should I migrate](#when-should-i-migrate)
1717
- [How to Run Migrations](#how-to-run-migrations)
1818
- [Developing Migrations](#developing-migrations)
19+
- [Migration with Plugins](#migration-with-plugins)
1920
- [Contribute](#contribute)
2021
- [Want to hack on IPFS?](#want-to-hack-on-ipfs)
2122
- [License](#license)
@@ -83,6 +84,22 @@ git push origin fs-repo-99-100/v1.0.1
8384

8485
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.
8586

87+
## Migration with Plugins
88+
If IPFS plugins were used to operate your IPFS datastore, such as the [ipfs-ds-s3](https://github.com/ipfs/go-ds-s3) plugin, then migration may require building a custom migration with the plugin built into it. There is a script to assist with the process: `build-plugin.sh`.
89+
90+
### Build a Migration with a Plugin
91+
This requires that you have Go installed.
92+
93+
First clone the `fs-repo-migrations` github repo:
94+
```sh
95+
git clone https://github.com/ipfs/fs-repo-migrations.git
96+
```
97+
98+
Then run the `build-plugin.sh` script, supplying the necessary arguments (run with -h for help).
99+
100+
### Run the Custom Migration
101+
After the custom migration with plugin(s) has built successfully, change to the migration directory and run the migration binary. You can also copy the migration binary into your `PATH` if you want it to be run by `ipfs-update` or by the `fs-repo-migrations` tool.
102+
86103
## Contribute
87104

88105
Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/fs-repo-migrations/issues)!

build-plugin.sh

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/bin/bash
2+
#
3+
# Build a migration with datastore plugins
4+
#
5+
# This script builds a migration with datastore plugins. Specify the
6+
# migration, such as 10-to-11, and one or more plugin repos to build with. A
7+
# specific version of a plugin is specified by following it with
8+
# @<version_or_hash>. The migration binary is built in its module
9+
# subdirectory. Run the migration binary directly, or copy it into a directory
10+
# in PATH to be run by ipfs-update or fs-repo-migrations.
11+
#
12+
# For each plugin built, the script asks which plugin to load. Use the -y flag
13+
# to avoid the prompt and choose 'plugin *' automatically.
14+
#
15+
# Example:
16+
# ./build-plugin.sh 10-to-11 github.com/ipfs/go-ds-s3 github.com/ipfs/[email protected]
17+
#
18+
set -eou pipefail
19+
20+
function usage() {
21+
echo "usage: $0 [-y] x-to-y plugin_repo[@<version_or_hash>] ...">&2
22+
echo
23+
echo "example: $0 10-to-11 github.com/ipfs/go-ds-s3" >&2
24+
}
25+
26+
AUTO_ANSWER=no
27+
28+
if [ $# -ge 1 ]; then
29+
if [ "$1" = "-h" -o "$1" = "-?" -o "$1" = "-help" ]; then
30+
echo "Build a migration with one or more plugins"
31+
echo
32+
usage
33+
echo
34+
echo "Options and arguments"
35+
echo "-y Automatically answer 'y' to all promots"
36+
echo "First postional argument, specifies the migration to build."
37+
echo "Remaining positional arguments specify plugin repos with optional version."
38+
exit 0
39+
elif [ "$1" = "-y" ]; then
40+
AUTO_ANSWER=yes
41+
shift 1
42+
else
43+
echo "unrecognized option $1" >&2
44+
echo >&2
45+
usage
46+
exit 1
47+
fi
48+
fi
49+
50+
if [ $# -lt 2 ]; then
51+
echo "too few arguments" >&2
52+
echo >&2
53+
usage
54+
exit 1
55+
fi
56+
57+
MIGRATION="$1"
58+
BUILD_DIR="$(mktemp -d --suffix=migration_build)"
59+
BUILD_GOIPFS="${BUILD_DIR}/go-ipfs"
60+
IPFS_REPO="github.com/ipfs/go-ipfs"
61+
IPFS_REPO_URL="https://${IPFS_REPO}"
62+
63+
function cleanup {
64+
rm -rf "${BUILD_DIR}"
65+
}
66+
trap cleanup EXIT
67+
68+
function get_migration() {
69+
for i in *${1}; do
70+
if [ -d "$i" ]; then
71+
echo "$i"
72+
return 0
73+
fi
74+
done
75+
}
76+
77+
function clone_ipfs() {
78+
local mig="$1"
79+
if [ ! -d "${mig}/vendor/github.com/ipfs/go-ipfs" ]; then
80+
echo "migration $mig does not support datastore plugins" >&2
81+
return 1
82+
fi
83+
84+
pushd "$mig"
85+
local ver="$(go list -f '{{.Version}}' -m github.com/ipfs/go-ipfs)"
86+
popd
87+
if echo "$ver" | grep -E 'v.*.[0-9]{14}-[0-9a-f]{12}$'; then
88+
local commit="$(echo $ver | rev | cut -d '-' -f 1 | rev)"
89+
echo "===> Getting go-ipfs commit $commit"
90+
git clone "$IPFS_REPO_URL" "$BUILD_GOIPFS"
91+
pushd "$BUILD_GOIPFS"
92+
git checkout "$commit"
93+
popd
94+
else
95+
echo "===> Getting go-ipfs branch $ver"
96+
git clone -b "$ver" "$IPFS_REPO_URL" "$BUILD_GOIPFS"
97+
fi
98+
}
99+
100+
function ask_yes_no() {
101+
local prompt="$1"
102+
while true; do
103+
read -p "$prompt [y/n]?" yn
104+
case "$yn" in
105+
[Yy]* ) return 0;;
106+
[Nn]* ) return 1;;
107+
* ) echo "Please answer y or n";;
108+
esac
109+
done
110+
}
111+
112+
function bundle_ipfs_plugin() {
113+
local plugin_repo="$1"
114+
echo "===> Bundling plugin $plugin_repo info go-ipfs for migration"
115+
local plugin_version=latest
116+
if [[ "$plugin_repo" == *"@"* ]]; then
117+
plugin_version="$(echo $plugin_repo | cut -d '@' -f 2)"
118+
plugin_repo="$(echo $plugin_repo | cut -d '@' -f 1)"
119+
fi
120+
echo "plugin version: $plugin_version"
121+
local plugin_name="$(echo $plugin_repo | rev | cut -d '-' -f 1 | rev)"
122+
123+
pushd "$BUILD_GOIPFS"
124+
go get "${plugin_repo}@${plugin_version}"
125+
popd
126+
127+
local ds_name="${plugin_name}ds"
128+
# While there is a plugin name conflict, ask for or generate new name.
129+
# When run non-interactively, keep appending "1" until no conflict.
130+
while grep -q "^${ds_name} " "${BUILD_GOIPFS}/plugin/loader/preload_list"; do
131+
old_ds_name="$ds_name"
132+
ds_name="${ds_name}1"
133+
if [ "$AUTO_ANSWER" != "yes" ]; then
134+
echo -n "\"$old_ds_name\" already in use, "
135+
while true; do
136+
if ask_yes_no "use plugin name \"$ds_name\""; then
137+
break
138+
else
139+
read -p "Enter new value: " ds_name
140+
fi
141+
done
142+
fi
143+
done
144+
145+
# Prompt for plugin to load
146+
load_plugin='plugin *'
147+
if [ "$AUTO_ANSWER" != "yes" ]; then
148+
while true; do
149+
if ask_yes_no "For $plugin_repo, load '$load_plugin'"; then
150+
break
151+
else
152+
read -p "Enter new value: " load_plugin
153+
fi
154+
done
155+
fi
156+
echo "$ds_name ${plugin_repo}/${load_plugin}" >> "${BUILD_GOIPFS}/plugin/loader/preload_list"
157+
}
158+
159+
function build_migration() {
160+
echo "===> Building go-ipfs with datastore plugins"
161+
sed -i '/^\tgo fmt .*/a \\tgo mod tidy' "${BUILD_GOIPFS}/plugin/loader/Rules.mk"
162+
make -C "$BUILD_GOIPFS" build
163+
164+
local mig="$1"
165+
echo
166+
echo "===> Building migration $mig with plugins"
167+
pushd "$mig"
168+
go mod edit -replace "${IPFS_REPO}=${BUILD_GOIPFS}"
169+
go mod vendor
170+
go build -mod=vendor
171+
# Cleanup temporary modifications
172+
rm -rf vendor
173+
git checkout vendor go.mod
174+
if [ -e go.sum ]; then
175+
git checkout go.sum
176+
fi
177+
popd
178+
echo "===> Done building migration $mig with plugins"
179+
}
180+
181+
migration="$(get_migration ${MIGRATION})"
182+
if [ -z "$migration" ]; then
183+
echo "migration $migration does not exist" >&2
184+
exit 1
185+
fi
186+
187+
clone_ipfs "$migration"
188+
if [ $? -ne 0 ]; then
189+
continue
190+
fi
191+
192+
shift 1
193+
for repo in "$@"; do
194+
bundle_ipfs_plugin "$repo"
195+
done
196+
197+
build_migration "$migration"

fs-repo-8-to-9/sharness/t0120-migration-7-to-9.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ test_description="Test migration 7 to 9"
44

55
. lib/test-lib.sh
66

7-
# Dist specially built with a v0.5.0-dev-8to9pre1 release
8-
export IPFS_DIST_PATH="/ipfs/QmaaN2kipZfUpRSzwvUeG4Xi3yp1JJB294Vj8pnZ24hesF"
7+
export IPFS_DIST_PATH="/ipfs/QmVxxcTSuryJYdQJGcS8SyhzN7NBNLTqVPAxpu6gp2ZcrR"
98
export GOPATH="$(pwd)/gopath"
109
mkdir -p gopath/bin
1110
export PATH="$(pwd)/../bin:$GOPATH/bin:$PATH"
@@ -66,7 +65,7 @@ test_expect_success "migrated files exist" '
6665
[ -f "${IPFS_PATH}/keystore/key_nnsxsmq" ]
6766
'
6867

69-
test_install_ipfs_nd "v0.5.0-dev-8to9pre2"
68+
test_install_ipfs_nd "v0.5.0-rc2"
7069

7170
test_expect_success "ipfs key list is the same" '
7271
ipfs key list > new_key_list

run.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This document explains how to run [fs-repo](https://github.com/ipfs/specs/tree/m
44

55
Note that running migrations is a task automatically performed by the `ipfs` when starting the `ipfs` daemon after an upgrade or running the `ipfs-update` tool, so you would normally not need to run the `fs-repo-migrations` tool.
66

7-
The `fs-migrations-tool` comes into play when the internal, on-disk format `ipfs` uses to store data changes. In order to avoid losing data, this tool upgrades old versions of the repo to the new ones.
7+
The `fs-repo-migrations` tool comes into play when there is a change in the internal on-disk format `ipfs` uses to store data. In order to avoid losing data, this tool upgrades old versions of the repo to the new ones.
88

99
If you run into any trouble, please feel free to [open an issue in this repository](https://github.com/ipfs/fs-repo-migrations/issues).
1010

@@ -13,10 +13,6 @@ If you run into any trouble, please feel free to [open an issue in this reposito
1313
The migration tool is safe -- it should not delete any data. If you have important data stored _only_ in your ipfs node, and want to be extra safe, you can back up the whole repo with:
1414

1515
```sh
16-
# version 0
17-
cp -r ~/.go-ipfs ~/.go-ipfs.bak
18-
19-
# version 1+
2016
cp -r ~/.ipfs ~/.ipfs.bak
2117
```
2218

@@ -30,7 +26,7 @@ cp -r ~/.ipfs ~/.ipfs.bak
3026
Now, run the migration tool:
3127

3228
```sh
33-
# if you installed from Go, tool is in your global $PATH
29+
# if you installed from Go, the tool is in your global $PATH
3430
fs-repo-migrations
3531

3632
# otherwise, unzip the package, cd into it and run the binary:

0 commit comments

Comments
 (0)