From 26770b7ebb8a9864bf656f9c220ea6dd064ff2ec Mon Sep 17 00:00:00 2001 From: Lars Gierth Date: Thu, 16 Feb 2017 15:23:58 +0100 Subject: [PATCH] fsrepo: fix musl detection for migrations The ldd command used for detection doesn't seem to have a --version flag on Alpine Linux. It would print the expected output, but instead of stdout, it would print it on stderr. The musl detection code would only scan stdout for mentions of "musl", and would thus *not* download the musl version of the fs-repo-migrations executable. This manifested in the well-known "fs-repo-migrations: not found" error, which you get when executing something that was linked against a different libc than the one present on the system. License: MIT Signed-off-by: Lars Gierth --- repo/fsrepo/migrations/migrations.go | 29 +++++++++++++++------------- test/sharness/lib/test-lib.sh | 2 +- test/sharness/t0066-migration.sh | 27 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/repo/fsrepo/migrations/migrations.go b/repo/fsrepo/migrations/migrations.go index a7f059c37..90278d3de 100644 --- a/repo/fsrepo/migrations/migrations.go +++ b/repo/fsrepo/migrations/migrations.go @@ -243,27 +243,30 @@ func GetBinaryForVersion(distname, binnom, root, vers, out string) error { return unpackArchive(distname, binnom, arcpath, out, archive) } +// osWithVariant returns the OS name with optional variant. +// Currently returns either runtime.GOOS, or "linux-musl". func osWithVariant() (string, error) { if runtime.GOOS != "linux" { return runtime.GOOS, nil } - bin, err := exec.LookPath(filepath.Base(os.Args[0])) - if err != nil { - return "", fmt.Errorf("failed to resolve go-ipfs: %s", err) - } - - // ldd outputs the system's kind of libc + // ldd outputs the system's kind of libc. // - on standard ubuntu: ldd (Ubuntu GLIBC 2.23-0ubuntu5) 2.23 // - on alpine: musl libc (x86_64) - cmd := exec.Command("ldd --version", bin) - buf := new(bytes.Buffer) - cmd.Stdout = buf - // we throw away the error, this code path must not fail because of - // a silly issue such as missing/broken ldd. we'll assume glibc in that case. - _ = cmd.Run() + // + // we use the combined stdout+stderr, + // because ldd --version prints differently on different OSes. + // - on standard ubuntu: stdout + // - on alpine: stderr (it probably doesn't know the --version flag) + // + // we supress non-zero exit codes (see last point about alpine). + out, err := exec.Command("sh", "-c", "ldd --version || true").CombinedOutput() + if err != nil { + return "", err + } - scan := bufio.NewScanner(buf) + // now just see if we can find "musl" somewhere in the output + scan := bufio.NewScanner(bytes.NewBuffer(out)) for scan.Scan() { if strings.Contains(scan.Text(), "musl") { return "linux-musl", nil diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index d24ce431b..57cf2c047 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -147,7 +147,7 @@ test_init_ipfs() { test_config_set Mounts.IPFS "$(pwd)/ipfs" && test_config_set Mounts.IPNS "$(pwd)/ipns" && test_config_set Addresses.API "/ip4/127.0.0.1/tcp/0" && - test_config_set Addresses.Gateway "/ip4/127.0.0.1/tcp/0" && + test_config_set Addresses.Gateway "/ip4/0.0.0.0/tcp/0" && test_config_set --json Addresses.Swarm "[ \"/ip4/0.0.0.0/tcp/0\" ]" && diff --git a/test/sharness/t0066-migration.sh b/test/sharness/t0066-migration.sh index 49587fe9d..d4ac46ec9 100755 --- a/test/sharness/t0066-migration.sh +++ b/test/sharness/t0066-migration.sh @@ -49,4 +49,31 @@ test_expect_success "output looks good" ' grep "Please get fs-repo-migrations from https://dist.ipfs.io" daemon_out > /dev/null ' +test_launch_ipfs_daemon + +test_expect_success "build fake dist.ipfs.io" ' + mkdir -p fakedist/fs-repo-migrations/v1.0.0/ + echo "v1.0.0" > fakedist/fs-repo-migrations/versions + + echo "#!/bin/sh" > fakedist/linux + echo "echo linux $@" >> fakedist/linux + tar -czf fakedist/fs-repo-migrations/fs-repo-migrations_v1.0.0_linux-amd64.tar.gz fakedist/linux + + echo "#!/bin/sh" > fakedist/linux-musl + echo "echo linux-musl $@" >> fakedist/linux-musl + tar -czf fakedist/fs-repo-migrations/fs-repo-migrations_v1.0.0_linux-musl-amd64.tar.gz fakedist/linux-musl + + ipfs add -q -r fakedist/ > fakedisthash +' + +test_expect_success "detect musl" ' + IPFS_DIST_PATH="http://172.17.0.1:$GWAY_PORT" echo $IPFS_DIST_PATH +' + +# make fakedist with executables that just echo "I'm $GOOS-$variant with $ARGV" +# ipfs add -r fakedist +# find out IPFS_DIST_PATH +# run daemon --migrate end-to-end +# check for correct output + test_done