"bufio"
"bytes"
"context"
+ _ "embed"
"errors"
"flag"
"fmt"
"os/exec"
"os/user"
"path/filepath"
+ "runtime"
"strconv"
"strings"
"syscall"
var Command cmd.Handler = &installCommand{}
-const goversion = "1.17.7"
+const goversion = "1.20.6"
const (
- rubyversion = "2.7.5"
- singularityversion = "3.7.4"
+ rubyversion = "2.7.7"
+ bundlerversion = "2.2.19"
+ singularityversion = "3.10.4"
pjsversion = "1.9.8"
geckoversion = "0.24.0"
gradleversion = "5.3.1"
- nodejsversion = "v12.22.2"
+ nodejsversion = "v12.22.12"
devtestDatabasePassword = "insecure_arvados_test"
- workbench2version = "cfa81dfc3041cb459c8a0918a2732dfcf3a11d40"
+ workbench2version = "9a62117dbe56bdfa42489415eb6696638c2bb336" // 2.6.3
)
+//go:embed arvados.service
+var arvadosServiceFile []byte
+
type installCommand struct {
ClusterType string
SourcePath string
pkgs = append(pkgs,
"dpkg-dev",
"eatmydata", // install it for later steps, even if we're not using it now
- "rsync",
)
}
"default-jre-headless",
"gettext",
"libattr1-dev",
- "libcrypt-ssleay-perl",
"libfuse-dev",
+ "libgbm1", // cypress / workbench2 tests
+ "libglib2.0-dev", // common, used by singularity
"libgnutls28-dev",
- "libjson-perl",
"libpam-dev",
"libpcre3-dev",
"libpq-dev",
"libreadline-dev",
+ "libseccomp-dev", // singularity
"libssl-dev",
- "libwww-perl",
"libxml2-dev",
"libxslt1-dev",
"linkchecker",
"make",
"net-tools",
"pandoc",
- "perl-modules",
"pkg-config",
"postgresql",
"postgresql-contrib",
"r-cran-markdown",
"r-cran-roxygen2",
"r-cran-xml",
+ "rsync",
"sudo",
"uuid-dev",
"wget",
"xvfb",
+ "zlib1g-dev", // services/api
)
if test {
if osv.Debian && osv.Major <= 10 {
}
if dev || test {
pkgs = append(pkgs, "squashfs-tools") // for singularity
+ pkgs = append(pkgs, "gnupg") // for docker install recipe
}
switch {
+ case osv.Debian && osv.Major >= 11:
+ pkgs = append(pkgs, "g++", "libcurl4", "libcurl4-openssl-dev")
case osv.Debian && osv.Major >= 10:
- pkgs = append(pkgs, "libcurl4")
- default:
- pkgs = append(pkgs, "libcurl3")
+ pkgs = append(pkgs, "g++", "libcurl4", "libcurl4-openssl-dev")
+ case osv.Debian || osv.Ubuntu:
+ pkgs = append(pkgs, "g++", "libcurl3", "libcurl3-openssl-dev")
+ case osv.Centos:
+ pkgs = append(pkgs, "gcc", "gcc-c++", "libcurl-devel", "postgresql-devel")
}
cmd := exec.CommandContext(ctx, "apt-get")
if inst.EatMyData {
}
}
+ if dev || test {
+ if havedockerversion, err := exec.Command("docker", "--version").CombinedOutput(); err == nil {
+ logger.Printf("%s installed, assuming that version is ok", bytes.TrimSuffix(havedockerversion, []byte("\n")))
+ } else if osv.Debian {
+ var codename string
+ switch osv.Major {
+ case 10:
+ codename = "buster"
+ case 11:
+ codename = "bullseye"
+ default:
+ err = fmt.Errorf("don't know how to install docker-ce for debian %d", osv.Major)
+ return 1
+ }
+ err = inst.runBash(`
+rm -f /usr/share/keyrings/docker-archive-keyring.gpg
+curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
+echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian/ `+codename+` stable' | \
+ tee /etc/apt/sources.list.d/docker.list
+apt-get update
+DEBIAN_FRONTEND=noninteractive apt-get --yes --no-install-recommends install docker-ce
+`, stdout, stderr)
+ if err != nil {
+ return 1
+ }
+ } else {
+ err = fmt.Errorf("don't know how to install docker for osversion %v", osv)
+ return 1
+ }
+ }
+
os.Mkdir("/var/lib/arvados", 0755)
os.Mkdir("/var/lib/arvados/tmp", 0700)
if prod || pkg {
tmp=/var/lib/arvados/tmp/singularity
trap "rm -r ${tmp}" ERR EXIT
cd /var/lib/arvados/tmp
-git clone https://github.com/sylabs/singularity
+git clone --recurse-submodules https://github.com/sylabs/singularity
cd singularity
git checkout v${S}
./mconfig --prefix=/var/lib/arvados
}
}
+ err = inst.runBash(`
+install /usr/bin/nsenter /var/lib/arvados/bin/nsenter
+setcap "cap_sys_admin+pei cap_sys_chroot+pei" /var/lib/arvados/bin/nsenter
+`, stdout, stderr)
+ if err != nil {
+ return 1
+ }
+
// The entry in /etc/locale.gen is "en_US.UTF-8"; once
// it's installed, locale -a reports it as
// "en_US.utf8".
} else {
err = inst.runBash(`
NJS=`+nodejsversion+`
+rm -rf /var/lib/arvados/node-*-linux-x64
wget --progress=dot:giga -O- https://nodejs.org/dist/${NJS}/node-${NJS}-linux-x64.tar.xz | sudo tar -C /var/lib/arvados -xJf -
ln -sfv /var/lib/arvados/node-${NJS}-linux-x64/bin/{node,npm} /usr/local/bin/
`, stdout, stderr)
cd arvados-workbench2
if ! git checkout $V; then
git fetch
+ git checkout yarn.lock
git checkout $V
fi
fi
for _, srcdir := range []string{
"cmd/arvados-client",
"cmd/arvados-server",
- "services/arv-git-httpd",
- "services/crunch-dispatch-local",
- "services/crunch-dispatch-slurm",
- "services/health",
- "services/keep-balance",
- "services/keep-web",
- "services/keepproxy",
- "services/keepstore",
- "services/ws",
} {
fmt.Fprintf(stderr, "building %s...\n", srcdir)
cmd := exec.Command("go", "install", "-ldflags", "-X git.arvados.org/arvados.git/lib/cmd.version="+inst.PackageVersion+" -X main.version="+inst.PackageVersion+" -s -w")
return 1
}
+ // Install python SDK and arv-mount in
+ // /var/lib/arvados/lib/python.
+ //
+ // setup.py writes a file in the source directory in
+ // order to include the version number in the package
+ // itself. We don't want to write to the source tree
+ // (in "arvados-package" context it's mounted
+ // readonly) so we run setup.py in a temporary copy of
+ // the source dir.
+ if err = inst.runBash(`
+v=/var/lib/arvados/lib/python
+tmp=/var/lib/arvados/tmp/python
+python3 -m venv "$v"
+. "$v/bin/activate"
+pip3 install --no-cache-dir 'setuptools>=18.5' 'pip>=7'
+export ARVADOS_BUILDING_VERSION="`+inst.PackageVersion+`"
+for src in "`+inst.SourcePath+`/sdk/python" "`+inst.SourcePath+`/services/fuse"; do
+ rsync -a --delete-after "$src/" "$tmp/"
+ cd "$tmp"
+ python3 setup.py install
+ cd ..
+ rm -rf "$tmp"
+done
+`, stdout, stderr); err != nil {
+ return 1
+ }
+
// Install Rails apps to /var/lib/arvados/{railsapi,workbench1}/
for dstdir, srcdir := range map[string]string{
"railsapi": "services/api",
"-a", "--no-owner", "--no-group", "--delete-after", "--delete-excluded",
"--exclude", "/coverage",
"--exclude", "/log",
+ "--exclude", "/node_modules",
"--exclude", "/tmp",
+ "--exclude", "/public/assets",
"--exclude", "/vendor",
"--exclude", "/config/environments",
"./", "/var/lib/arvados/"+dstdir+"/")
return 1
}
for _, cmdline := range [][]string{
- {"mkdir", "-p", "log", "tmp", ".bundle", "/var/www/.gem", "/var/www/.bundle", "/var/www/.passenger"},
+ {"mkdir", "-p", "log", "public/assets", "tmp", "vendor", ".bundle", "/var/www/.bundle", "/var/www/.gem", "/var/www/.npm", "/var/www/.passenger"},
{"touch", "log/production.log"},
- {"chown", "-R", "--from=root", "www-data:www-data", "/var/www/.gem", "/var/www/.bundle", "/var/www/.passenger", "log", "tmp", ".bundle", "Gemfile.lock", "config.ru", "config/environment.rb"},
- {"sudo", "-u", "www-data", "/var/lib/arvados/bin/gem", "install", "--user", "--conservative", "--no-document", "bundler:2.2.19"},
- {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "install", "--deployment", "--jobs", "8", "--path", "/var/www/.gem"},
+ {"chown", "-R", "--from=root", "www-data:www-data", "/var/www/.bundle", "/var/www/.gem", "/var/www/.npm", "/var/www/.passenger", "log", "tmp", "vendor", ".bundle", "Gemfile.lock", "config.ru", "config/environment.rb"},
+ {"sudo", "-u", "www-data", "/var/lib/arvados/bin/gem", "install", "--user", "--conservative", "--no-document", "bundler:" + bundlerversion},
+ {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "config", "set", "--local", "deployment", "true"},
+ {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "config", "set", "--local", "path", "/var/www/.gem"},
+ {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "config", "set", "--local", "without", "development test diagnostics performance"},
+ {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "install", "--jobs", fmt.Sprintf("%d", runtime.NumCPU())},
+
+ {"chown", "www-data:www-data", ".", "public/assets"},
+ // {"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "config", "set", "--local", "system", "true"},
+ {"sudo", "-u", "www-data", "ARVADOS_CONFIG=none", "RAILS_GROUPS=assets", "RAILS_ENV=production", "PATH=/var/lib/arvados/bin:" + os.Getenv("PATH"), "/var/lib/arvados/bin/bundle", "exec", "rake", "npm:install"},
+ {"sudo", "-u", "www-data", "ARVADOS_CONFIG=none", "RAILS_GROUPS=assets", "RAILS_ENV=production", "PATH=/var/lib/arvados/bin:" + os.Getenv("PATH"), "/var/lib/arvados/bin/bundle", "exec", "rake", "assets:precompile"},
+ {"chown", "root:root", "."},
+ {"chown", "-R", "root:root", "public/assets", "vendor"},
+
{"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "exec", "passenger-config", "build-native-support"},
{"sudo", "-u", "www-data", "/var/lib/arvados/bin/bundle", "exec", "passenger-config", "install-standalone-runtime"},
} {
+ if cmdline[len(cmdline)-2] == "rake" && dstdir != "workbench1" {
+ continue
+ }
cmd = exec.Command(cmdline[0], cmdline[1:]...)
cmd.Dir = "/var/lib/arvados/" + dstdir
cmd.Stdout = stdout
`, stdout, stderr); err != nil {
return 1
}
+
+ // Install arvados-cli gem (binaries go in
+ // /var/lib/arvados/bin)
+ if err = inst.runBash(`
+/var/lib/arvados/bin/gem install --conservative --no-document arvados-cli
+`, stdout, stderr); err != nil {
+ return 1
+ }
+
+ err = os.WriteFile("/lib/systemd/system/arvados.service", arvadosServiceFile, 0777)
+ if err != nil {
+ return 1
+ }
+ if prod {
+ // (fpm will do this for us in the pkg case)
+ // This is equivalent to "systemd enable", but
+ // does not depend on the systemctl program
+ // being available:
+ symlink := "/etc/systemd/system/multi-user.target.wants/arvados.service"
+ err = os.Remove(symlink)
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
+ return 1
+ }
+ err = os.Symlink("/lib/systemd/system/arvados.service", symlink)
+ if err != nil {
+ return 1
+ }
+ }
+
+ // Add symlinks in /usr/bin for user-facing programs
+ for _, srcdst := range [][]string{
+ // go
+ {"bin/arvados-client"},
+ {"bin/arvados-client", "arv"},
+ {"bin/arvados-server"},
+ // sdk/cli
+ {"bin/arv", "arv-ruby"},
+ {"bin/arv-tag"},
+ // sdk/python
+ {"lib/python/bin/arv-copy"},
+ {"lib/python/bin/arv-federation-migrate"},
+ {"lib/python/bin/arv-get"},
+ {"lib/python/bin/arv-keepdocker"},
+ {"lib/python/bin/arv-ls"},
+ {"lib/python/bin/arv-migrate-docker19"},
+ {"lib/python/bin/arv-normalize"},
+ {"lib/python/bin/arv-put"},
+ {"lib/python/bin/arv-ws"},
+ // services/fuse
+ {"lib/python/bin/arv-mount"},
+ } {
+ src := "/var/lib/arvados/" + srcdst[0]
+ if _, err = os.Stat(src); err != nil {
+ return 1
+ }
+ dst := srcdst[len(srcdst)-1]
+ _, dst = filepath.Split(dst)
+ dst = "/usr/bin/" + dst
+ err = os.Remove(dst)
+ if err != nil && !errors.Is(err, os.ErrNotExist) {
+ return 1
+ }
+ err = os.Symlink(src, dst)
+ if err != nil {
+ return 1
+ }
+ }
}
return 0
"libcurl3-gnutls",
"libxslt1.1",
"nginx",
- "python",
+ "python3",
"sudo",
}
if osv.Debian || osv.Ubuntu {
pkgs = append(pkgs, "python3-distutils") // sdk/cwl
}
return append(pkgs,
- "g++",
- "libcurl4-openssl-dev", // services/api
- "libpq-dev",
- "libpython2.7", // services/fuse
"mime-support", // keep-web
- "zlib1g-dev", // services/api
)
} else if osv.Centos {
return append(pkgs,
"fuse-libs", // services/fuse
- "gcc",
- "gcc-c++",
- "libcurl-devel", // services/api
- "mailcap", // keep-web
- "postgresql-devel", // services/api
+ "mailcap", // keep-web
)
} else {
panic("os version not supported")