Tutorial setup

If you have not done the prior sections, you’ll need to set Spack up like this:

git clone https://github.com/spack/spack
. spack/share/spack/setup-env.sh
spack tutorial

See the Basic Installation Tutorial for full details on setup. For more help join us in the #tutorial channel on Slack – get an invitation at spackpm.herokuapp.com

Mirror Tutorial

This tutorial will guide you through the process of setting up a source mirror with a binary cache. Source mirrors and binary caches are extremely useful when using spack on a machine without internet access. Source mirrors allow you to fetch source code from a directory on your filesystem instead of accessing the outside internet, and binary caches allow you to install pre-compiled binaries to your spack installation path. Together, these two features can speed up builds when using spack within a larger development team.

We will use the filesystem for the mirrors in this tutorial, but mirrors can also be setup on web servers or s3 buckets – any URL that curl can access can be setup as a Spack mirror.

By default, Spack comes configured with a source mirror in the cloud to increase download reliability. We’ve also already set up a mirror in this tutorial for binary caches. We can see these mirrors are configured

$ spack mirror list
tutorial	file:///mirror
spack-public	https://mirror.spack.io

Setting up a source cache mirror

When you run spack install, spack goes out to the internet to grab the source code to build your packages. This works fine on most clusters, but what do you do if the cluster in question doesn’t have access to the outside internet? This could happen for a variety of reasons. Maybe you’re building on a compute node that isn’t connected to the greater internet, or maybe even the whole cluster has been isolated from the internet.

Spack has an easy answer to this – setting up a source mirror. When you use a source mirror, spack checks the mirror for the source code before going to the outside internet.

Building a source mirror is easy. Let’s start with the same simple environment. First, let’s build our software on a computer with external internet access.

$ cd ~
$ mkdir cache-env
$ cd cache-env
$ spack env create -d .
==> Updating view at /home/spack/cache-env/.spack-env/view
==> Created environment in /home/spack/cache-env
==> You can activate this environment with:
==>   spack env activate /home/spack/cache-env
$ spacktivate .
$ #  for now, disable fortran support in all packages
$ spack config add "packages:all:variants: ~fortran"
$ spack add macsio+scr
==> Adding macsio+scr to environment /home/spack/cache-env
$ spack install
==> Starting concretization
==> Environment concretized in 11.67 seconds.
==> Concretized macsio+scr
[+]  32fxerq  macsio@1.1%gcc@7.5.0~exodus~hdf5~ipo+mpi~pdb+scr+silo~szip~typhonio~zfp~zlib build_type=RelWithDebInfo patches=59479b946e5bbf677e814dc1cde12b38dd3b083fec8c543fc6d3abf9f73dbbfa arch=linux-ubuntu18.04-x86_64
[+]  anj6kcx	  ^cmake@3.21.4%gcc@7.5.0~doc+ncurses+openssl+ownlibs~qt build_type=Release arch=linux-ubuntu18.04-x86_64
[+]  d34lizg	      ^ncurses@6.2%gcc@7.5.0~symlinks+termlib abi=none arch=linux-ubuntu18.04-x86_64
[+]  ucp6vz7		  ^pkgconf@1.8.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  lygx3cq	      ^openssl@1.1.1l%gcc@7.5.0~docs certs=system arch=linux-ubuntu18.04-x86_64
[+]  672tzld		  ^perl@5.34.0%gcc@7.5.0+cpanm+shared+threads arch=linux-ubuntu18.04-x86_64
[+]  ue5lnfm		      ^berkeley-db@18.1.40%gcc@7.5.0+cxx~docs+stl patches=b231fcc4d5cff05e5c3a4814f6a5af0e9a966428dc2176540d2c05aff41de522 arch=linux-ubuntu18.04-x86_64
[+]  55rtzz4		      ^bzip2@1.0.8%gcc@7.5.0~debug~pic+shared arch=linux-ubuntu18.04-x86_64
[+]  kg5jymj			  ^diffutils@3.8%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  qi7dxj6			      ^libiconv@1.16%gcc@7.5.0 libs=shared,static arch=linux-ubuntu18.04-x86_64
[+]  oftaepj		      ^gdbm@1.19%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  27u6g7p			  ^readline@8.1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  3rlgy7y		      ^zlib@1.2.11%gcc@7.5.0+optimize+pic+shared arch=linux-ubuntu18.04-x86_64
[+]  2cj3pok	  ^json-cwx@0.12%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  7hurwa7	      ^autoconf@2.69%gcc@7.5.0 patches=35c449281546376449766f92d49fc121ca50e330e60fefcfc9be2af3253082c2,7793209b33013dc0f81208718c68440c5aae80e7a1c4b8d336e382525af791a7,a49dd5bac3b62daa0ff688ab4d508d71dbd2f4f8d7e2a02321926346161bf3ee arch=linux-ubuntu18.04-x86_64
[+]  ybvezwz		  ^m4@1.4.19%gcc@7.5.0+sigsegv patches=9dc5fbd0d5cb1037ab1e6d0ecc74a30df218d0a94bdd5a02759a97f62daca573,bfdffa7c2eb01021d5849b36972c069693654ad826c1a20b53534009a4ec7a89 arch=linux-ubuntu18.04-x86_64
[+]  g2vgcne		      ^libsigsegv@2.13%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  6rqxcsn	      ^automake@1.16.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  2kia6gf	      ^libtool@2.4.6%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  p5qicac	  ^openmpi@4.1.1%gcc@7.5.0~atomics~cuda~cxx~cxx_exceptions+gpfs~internal-hwloc~java~legacylaunchers~lustre~memchecker~pmi~pmix~singularity~sqlite3+static~thread_multiple+vt+wrapper-rpath fabrics=none schedulers=none arch=linux-ubuntu18.04-x86_64
[+]  gedgnpg	      ^hwloc@2.6.0%gcc@7.5.0~cairo~cuda~gl~libudev+libxml2~netloc~nvml~opencl+pci~rocm+shared arch=linux-ubuntu18.04-x86_64
[+]  ryhmw2g		  ^libpciaccess@0.16%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  h5cf2g4		      ^util-macros@1.19.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  2hw4ddh		  ^libxml2@2.9.12%gcc@7.5.0~python arch=linux-ubuntu18.04-x86_64
[+]  nplaaps		      ^xz@5.2.5%gcc@7.5.0~pic libs=shared,static arch=linux-ubuntu18.04-x86_64
[+]  xai6pyc	      ^libevent@2.1.12%gcc@7.5.0+openssl arch=linux-ubuntu18.04-x86_64
[+]  3opot4q	      ^numactl@2.0.14%gcc@7.5.0 patches=4e1d78cbbb85de625bad28705e748856033eaafab92a66dffd383a3d7e00cc94,62fc8a8bf7665a60e8f4c93ebbd535647cebf74198f7afafec4c085a8825c006,ff37630df599cfabf0740518b91ec8daaf18e8f288b19adaae5364dc1f6b2296 arch=linux-ubuntu18.04-x86_64
[+]  ux36qlb	      ^openssh@8.7p1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  3lzuqwn		  ^libedit@3.1-20210216%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  bvve4uc	  ^scr@3.0rc2%gcc@7.5.0+bbapi~bbapi_fallback~dw+examples~fortran~ipo+libyogrt+pdsh+shared+tests build_type=RelWithDebInfo cache_base=/dev/shm cntl_base=/dev/shm copy_config=none file_lock=FLOCK resource_manager=SLURM scr_config=scr.conf arch=linux-ubuntu18.04-x86_64
[+]  tioad6w	      ^axl@0.5.0%gcc@7.5.0+bbapi~bbapi_fallback~dw~ipo+shared async_api=daemon build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  6aehk3f		  ^kvtree@1.2.0%gcc@7.5.0~ipo+mpi+shared build_type=RelWithDebInfo file_lock=FLOCK arch=linux-ubuntu18.04-x86_64
[+]  jcs7klx	      ^dtcmp@1.1.3%gcc@7.5.0+shared arch=linux-ubuntu18.04-x86_64
[+]  45q636p		  ^lwgrp@1.0.4%gcc@7.5.0+shared arch=linux-ubuntu18.04-x86_64
[+]  27seins	      ^er@0.1.0%gcc@7.5.0~ipo+shared build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  no7gfol		  ^rankstr@0.1.0%gcc@7.5.0~ipo+shared build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  ymbgmh3		  ^redset@0.1.0%gcc@7.5.0~ipo+shared build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  enyf2gi		  ^shuffile@0.1.0%gcc@7.5.0~ipo+shared build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  p3d3hsx	      ^libyogrt@1.24%gcc@7.5.0~static scheduler=slurm arch=linux-ubuntu18.04-x86_64
[+]  o245qon		  ^slurm@21-08-1-1%gcc@7.5.0~gtk~hdf5~hwloc~mariadb~pmix+readline~restd sysconfdir=PREFIX/etc arch=linux-ubuntu18.04-x86_64
[+]  5qolphz		      ^curl@7.79.0%gcc@7.5.0~gssapi~ldap~libidn2~librtmp~libssh~libssh2~nghttp2 tls=openssl arch=linux-ubuntu18.04-x86_64
[+]  fp5v742		      ^glib@2.70.0%gcc@7.5.0~libmount patches=8547954e50d0a720fa9794b84c31569df6a7419319b95ac9de0ed861d8969ffd tracing=none arch=linux-ubuntu18.04-x86_64
[+]  2zkxpoq			  ^gettext@0.21%gcc@7.5.0+bzip2+curses+git~libunistring+libxml2+tar+xz arch=linux-ubuntu18.04-x86_64
[+]  otlzkgd			      ^tar@1.34%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  4bz34d3			  ^libffi@3.3%gcc@7.5.0 patches=26f26c6f29a7ce9bf370ad3ab2610f99365b4bdd7b82e7c31df41a3370d685c0 arch=linux-ubuntu18.04-x86_64
[+]  ngg44u2			  ^meson@0.60.0%gcc@7.5.0 patches=aa6c50d5a2aeb1a487d16f6712be4357fefb923aae37ab830699b07338388287 arch=linux-ubuntu18.04-x86_64
[+]  fgf6frb			      ^ninja@1.10.2%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  g2gj6mw				  ^python@3.8.12%gcc@7.5.0+bz2+ctypes+dbm~debug+libxml2+lzma~nis~optimizations+pic+pyexpat+pythoncmd+readline+shared+sqlite3+ssl~tix~tkinter~ucs4+uuid+zlib patches=0d98e93189bc278fbc37a50ed7f183bd8aaf249a8e1670a465f0db6bb4f8cf87,4c2457325f2b608b1b6a2c63087df8c26e07db3e3d493caf36a56f0ecf6fb768,f2fd060afc4b4618fe8104c4c5d771f36dc55b1db5a4623785a4ea707ec72fb4 arch=linux-ubuntu18.04-x86_64
[+]  j3i7qne				      ^expat@2.4.1%gcc@7.5.0+libbsd arch=linux-ubuntu18.04-x86_64
[+]  j5lylsy					  ^libbsd@0.11.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  aq7ydx6					      ^libmd@1.0.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  ckghzv6				      ^sqlite@3.36.0%gcc@7.5.0+column_metadata+fts~functions~rtree arch=linux-ubuntu18.04-x86_64
[+]  c23s54s				      ^util-linux-uuid@2.36.2%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  o52ww56			      ^py-setuptools@58.2.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  cgah7ko			  ^pcre@8.44%gcc@7.5.0~jit+multibyte+utf arch=linux-ubuntu18.04-x86_64
[+]  2dxobcc		      ^json-c@0.15%gcc@7.5.0~ipo build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  nuqiq66		      ^lz4@1.9.3%gcc@7.5.0 libs=shared,static arch=linux-ubuntu18.04-x86_64
[+]  h2wjv26		      ^munge@0.5.14%gcc@7.5.0 localstatedir=PREFIX/var arch=linux-ubuntu18.04-x86_64
[+]  64zlffc			  ^libgcrypt@1.9.3%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  cexzidc			      ^libgpg-error@1.42%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  km73vx2				  ^gawk@5.1.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  7kpzyzg				      ^gmp@6.2.1%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  35qmsm6				      ^mpfr@4.1.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  ievdgld					  ^autoconf-archive@2019.01.06%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
[+]  p3is4ct					  ^texinfo@6.5%gcc@7.5.0 patches=12f6edb0c6b270b8c8dba2ce17998c580db01182d871ee32b7b6e4129bd1d23a,1732115f651cff98989cb0215d8f64da5e0f7911ebf0c13b064920f088f2ffe1 arch=linux-ubuntu18.04-x86_64
[+]  6ffspsj	      ^pdsh@2.31%gcc@7.5.0+ssh+static_modules arch=linux-ubuntu18.04-x86_64
[+]  lml7squ	      ^spath@0.1.0%gcc@7.5.0~ipo+mpi+shared build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64
[+]  k6jhkin	  ^silo@4.10.2%gcc@7.5.0~fortran+fpzip+hdf5+hzip+mpi+pic+shared~silex patches=7b5a1dc2a0e358e667088d77e7caa780967fa8ea60be89c44986605df9990abe,952d3c95fbeaf32355c1c24d831b6c315c5cf29023874127b0f461855046750c arch=linux-ubuntu18.04-x86_64
[+]  vt7sza3	      ^hdf5@1.10.7%gcc@7.5.0~cxx~fortran~hl~ipo~java+mpi+shared~szip~threadsafe+tools api=default build_type=RelWithDebInfo arch=linux-ubuntu18.04-x86_64

==> Installing environment /home/spack/cache-env
==> All of the packages are already installed

Once we’ve created and installed this environment, we can easily upload source code needed to reproduce this build to a mirror. The following command both creates the mirror and uploads the source code for the scr package included in our environment. The -d flag (short for --directory) tells spack where to place the mirrored source code files.

$ spack mirror create -d ~/mirror scr
==> Adding package scr@3.0rc2 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/4b/4b2a718af56b3683e428d25a2269c038e9452db734221d370e3023a491477fad.tar.gz
==> Successfully created mirror in file:///home/spack/mirror
  Archive stats:
    0	 already present
    1	 added
    0	 failed to fetch.

We can configure spack to use this source mirror by adding a few lines to your spack.yaml file.

$ spack mirror add mymirror ~/mirror

Manually uploading every package in an environment can be tedious. Luckily, when run within an environment, spack mirror create with the --all flag will upload every source used to build the current environment to the specified directory.

$ spack mirror create -d ~/mirror --all
==> Adding package autoconf@2.69 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/95/954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/ea/eaa3f69d927a853313a0b06e2117c51adab6377a2278549b05abc5df93643e16
==> Fetching https://mirror.spack.io/_source-cache/archive/77/7793209b33013dc0f81208718c68440c5aae80e7a1c4b8d336e382525af791a7
==> Fetching https://mirror.spack.io/_source-cache/archive/35/35c449281546376449766f92d49fc121ca50e330e60fefcfc9be2af3253082c2
==> Fetching https://mirror.spack.io/_source-cache/archive/a4/a49dd5bac3b62daa0ff688ab4d508d71dbd2f4f8d7e2a02321926346161bf3ee
==> Adding package autoconf-archive@2019.01.06 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/17/17195c833098da79de5778ee90948f4c5d90ed1a0cf8391b4ab348e2ec511e3f.tar.xz
==> Adding package automake@1.16.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ce/ce010788b51f64511a1e9bb2a1ec626037c6d0e7ede32c1c103611b9d3cba65f.tar.gz
==> Adding package axl@0.5.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/9f/9f3bbb4de563896551bdb68e889ba93ea1984586961ad8c627ed766bff020acf.tar.gz
==> Adding package berkeley-db@18.1.40 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/0c/0cecb2ef0c67b166de93732769abdeba0555086d51de1090df325e18ee8da9c8.tar.gz
==> Adding package bzip2@1.0.8 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ab/ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269.tar.gz
==> Adding package cmake@3.21.4 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/d9/d9570a95c215f4c9886dd0f0564ca4ef8d18c30750f157238ea12669c2985978.tar.gz
==> Adding package curl@7.79.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/d6/d607a677f473f79f96c964100327125a6204a39d835dc00dab7fc0129b959f42.tar.bz2
==> Adding package diffutils@3.8 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/a6/a6bdd7d1b31266d11c4f4de6c1b748d4607ab0231af5188fc2533d0ae2438fec.tar.xz
==> Adding package dtcmp@1.1.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/90/90b32cadd0ff2f4fa7fc916f8dcfdbe6918e3e285e0292a2470772478ca0aab5.tar.gz
==> Adding package er@0.1.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/54/543afc1c48bb2c67f48c32f6c9efcbf7bb27f2e622ff76f2c2ce5618c77aacfc.tar.gz
==> Adding package expat@2.4.1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/2f/2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40.tar.bz2
==> Adding package gawk@5.1.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/cf/cf5fea4ac5665fd5171af4716baab2effc76306a9572988d5ba1078f196382bd.tar.xz
==> Adding package gdbm@1.19 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/37/37ed12214122b972e18a0d94995039e57748191939ef74115b1d41d8811364bc.tar.gz
==> Adding package gettext@0.21 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/d2/d20fcbb537e02dcf1383197ba05bd0734ef7bf5db06bdb241eb69b7d16b73192.tar.xz
==> Adding package glib@2.70.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/20/200d7df811c5ba634afbf109f14bb40ba7fde670e89389885da14e27c0840742.tar.xz
==> Adding package gmp@6.2.1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ea/eae9326beb4158c386e39a356818031bd28f3124cf915f8c5b1dc4c7a36b4d7c.tar.bz2
==> Adding package hdf5@1.10.7 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/7a/7a1a0a54371275ce2dfc5cd093775bb025c365846512961e7e5ceaecb437ef15.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/57/57cee5ff1992b4098eda079815c36fc2da9b10e00a9056df054f2384c4fc7523
==> Adding package hwloc@2.6.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/9a/9aa7e768ed4fd429f488466a311ef2191054ea96ea1a68657bc06ffbb745e59f.tar.gz
==> Adding package json-c@0.15 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/b8/b8d80a1ddb718b3ba7492916237bbf86609e9709fb007e7f7d4322f02341a4c6.tar.gz
==> Adding package json-cwx@0.12 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/3b/3bfae1f23eacba53ee130dbd1a6acf617af4627a9b4e4581d64b20a99b4e2b60.tar.gz
==> Adding package kvtree@1.2.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/ec/ecd4b8bc479c33ab4f23fc764445a3bb353a1d15c208d011f5577a32c182477f.tar.gz
==> Adding package libbsd@0.11.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ff/ff95cf8184151dacae4247832f8d4ea8800fa127dbd15033ecfe839f285b42a1.tar.xz
==> Adding package libedit@3.1-20210216 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/22/2283f741d2aab935c8c52c04b57bf952d02c2c02e651172f8ac811f77b1fc77a.tar.gz
==> Adding package libevent@2.1.12 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/92/92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb.tar.gz
==> Adding package libffi@3.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/72/72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056.tar.gz
==> Adding package libgcrypt@1.9.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/97/97ebe4f94e2f7e35b752194ce15a0f3c66324e0ff6af26659bbfb5ff2ec328fd.tar.bz2
==> Adding package libgpg-error@1.42 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/fc/fc07e70f6c615f8c4f590a8e37a9b8dd2e2ca1e9408f8e60459c67452b925e23.tar.bz2
==> Adding package libiconv@1.16 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/e6/e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04.tar.gz
==> Adding package libmd@1.0.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/5a/5a02097f95cc250a3f1001865e4dbba5f1d15554120f95693c0541923c52af4a.tar.xz
==> Adding package libpciaccess@0.16 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/84/84413553994aef0070cf420050aa5c0a51b1956b404920e21b81e96db6a61a27.tar.gz
==> Adding package libsigsegv@2.13 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/be/be78ee4176b05f7c75ff03298d84874db90f4b6c9d5503f0da1226b3a3c48119.tar.gz
==> Adding package libtool@2.4.6 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/e3/e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3.tar.gz
==> Adding package libxml2@2.9.12 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/c8/c8d6681e38c56f172892c85ddc0852e1fd4b53b4209e7f4ebf17f7e2eae71d92.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/96/96151685cec997e1f9f3387e3626d61e6284d4d6e66e0e440c209286c03e9cc7.tar.gz
==> Adding package libyogrt@1.24 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/36/36695030e72b24b1f22bfcfe42bfd1d3c87f9c0eea5e94ce0120782581ea522f.tar.gz
==> Adding package lwgrp@1.0.4 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/0c/0c933df7658660a0225f8e3a940eb2621efa4421397859417c8d90d906d4e90a.tar.gz
==> Adding package lz4@1.9.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/03/030644df4611007ff7dc962d981f390361e6c97a34e5cbc393ddfbe019ffe2c1.tar.gz
==> Adding package m4@1.4.19 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/3b/3be4a26d825ffdfda52a56fc43246456989a3630093cced3fbddf4771ee58a70.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/fc/fc9b61654a3ba1a8d6cd78ce087e7c96366c290bc8d2c299f09828d793b853c8
==> Fetching https://mirror.spack.io/_source-cache/archive/bf/bfdffa7c2eb01021d5849b36972c069693654ad826c1a20b53534009a4ec7a89
==> Fetching https://mirror.spack.io/_source-cache/archive/9d/9dc5fbd0d5cb1037ab1e6d0ecc74a30df218d0a94bdd5a02759a97f62daca573
==> Adding package macsio@1.1 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/a8/a86249b0f10647c0b631773db69568388094605ec1a0af149d9e61e95e6961ec.tar.gz
==> Adding package meson@0.60.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/56/5672a560fc4094c88ca5b8be0487e099fe84357e5045f5aecf1113084800e6fd.tar.gz
==> Adding package mpfr@4.1.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/fe/feced2d430dd5a97805fa289fed3fc8ff2b094c02d05287fd6133e7f1f0ec926.tar.bz2
==> Fetching https://mirror.spack.io/_source-cache/archive/3f/3f80b836948aa96f8d1cb9cc7f3f55973f19285482a96f9a4e1623d460bcccf0
==> Fetching https://mirror.spack.io/_source-cache/archive/52/5230aab653fa8675fc05b5bdd3890e071e8df49a92a9d58c4284024affd27739
==> Fetching https://mirror.spack.io/_source-cache/archive/7a/7a6dd71bcda4803d6b89612706a17b8816e1acd5dd9bf1bec29cf748f3b60008
==> Fetching https://mirror.spack.io/_source-cache/archive/1a/1ae14fb3a54ae8e0faed20801970255b279eee9e5ac624891ab5d29727f0bc04
==> Fetching https://mirror.spack.io/_source-cache/archive/11/113705d5333ef0d0ad3eb136a85404ba6bd1cc524dece5ce902c536aa2e29903
==> Fetching https://mirror.spack.io/_source-cache/archive/41/4152a780b3cc6e9643283e59093b43460196d0fea9302d8c93b2496f6679f4e4
==> Fetching https://mirror.spack.io/_source-cache/archive/1b/1b9fdb515efb09a506a01e1eb307b1464455f5ca63d6c193db3a3da371ab3220
==> Adding package munge@0.5.14 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/66/6606a218f18090fa1f702e3f6fb608073eb6aafed534cf7dd81b67b2e0d30640.tar.xz
==> Adding package ncurses@6.2 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/30/30306e0c76e0f9f1f0de987cf1c82a5c21e1ce6568b9227f7da5b71cbea86c9d.tar.gz
==> Adding package ninja@1.10.2 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ce/ce35865411f0490368a8fc383f29071de6690cbadc27704734978221f25e2bed.tar.gz
==> Adding package numactl@2.0.14 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/1e/1ee27abd07ff6ba140aaf9bc6379b37825e54496e01d6f7343330cf1a4487035.tar.gz
==> Adding package openmpi@4.1.1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/e2/e24f7a778bd11a71ad0c14587a7f5b00e68a71aa5623e2157bafee3d44c07cda.tar.bz2
==> Adding package openssh@8.7p1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/7c/7ca34b8bb24ae9e50f33792b7091b3841d7e1b440ff57bc9fabddf01e2ed1e24.tar.gz
==> Adding package openssl@1.1.1l to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/0b/0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1.tar.gz
==> Adding package pcre@8.44 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/19/19108658b23b3ec5058edc9f66ac545ea19f9537234be1ec62b714c84399366d.tar.bz2
==> Adding package pdsh@2.31 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/0e/0ee066ce395703285cf4f6cf00b54b7097d12457a4b1c146bc6f33d8ba73caa7.tar.gz
==> Adding package perl@5.34.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/55/551efc818b968b05216024fb0b727ef2ad4c100f8cb6b43fab615fa78ae5be9a.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/9d/9da50e155df72bce55cb69f51f1dbb4b62d23740fb99f6178bb27f22ebdf8a46.tar.gz
==> Fetching https://mirror.spack.io/_source-cache/archive/8c/8cf4302ca8b480c60ccdcaa29ec53d9d50a71d4baf469ac8c6fca00ca31e58a2
==> Fetching https://mirror.spack.io/_source-cache/archive/3b/3bbd7d6f9933d80b9571533867b444c6f8f5a1ba0575bfba1fba4db9d885a71a
==> Fetching https://mirror.spack.io/_source-cache/archive/0e/0eac10ed90aeb0459ad8851f88081d439a4e41978e586ec743069e8b059370ac
==> Adding package pkgconf@1.8.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/ef/ef9c7e61822b7cb8356e6e9e1dca58d9556f3200d78acab35e4347e9d4c2bbaf.tar.xz
==> Adding package py-setuptools@58.2.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/2c/2c55bdb85d5bb460bd2e3b12052b677879cffcf46c0c688f2e5bf51d36001145.tar.gz
==> Adding package python@3.8.12 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/31/316aa33f3b7707d041e73f246efedb297a70898c4b91f127f66dc8d80c596f1a.tgz
==> Adding package rankstr@0.1.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/b6/b68239d67b2359ecc067cc354f86ccfbc8f02071e60d28ae0a2449f2e7f88001.tar.gz
==> Adding package readline@8.1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/f8/f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02.tar.gz
==> Adding package redset@0.1.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/ba/baa75de0d0d6de64ade50cff3d38ee89fd136ce69869182bdaefccf5be5d286d.tar.gz
==> Adding package scr@3.0rc2 to mirror
==> Adding package shuffile@0.1.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/9e/9e730cc8b7937517a9cffb08c031d9f5772306341c49d17b87b7f349d55a6d5e.tar.gz
==> Adding package silo@4.10.2 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/3a/3af87e5f0608a69849c00eb7c73b11f8422fa36903dd14610584506e7f68e638.tgz
==> Adding package slurm@21-08-1-1 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/23/23321719101762b055a6b1da6ff4261f5e6c469bce038c6c23549840453862e7.tar.gz
==> Adding package spath@0.1.0 to mirror
==> Using cached archive: /home/spack/spack/var/spack/cache/_source-cache/archive/2c/2cfc635b2384d3f92973c7aea173dabe47da112d308f5098e6636e4b2f4a704c.tar.gz
==> Adding package sqlite@3.36.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/bd/bd90c3eb96bee996206b83be7065c9ce19aef38c3f4fb53073ada0d0b69bbce3.tar.gz
==> Adding package tar@1.34 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/03/03d908cf5768cfe6b7ad588c921c6ed21acabfb2b79b788d1330453507647aed.tar.gz
==> Adding package texinfo@6.5 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/d3/d34272e4042c46186ddcd66bd5d980c0ca14ff734444686ccf8131f6ec8b1427.tar.gz
==> Adding package util-linux-uuid@2.36.2 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/f5/f5dbe79057e7d68e1a46fc04083fc558b26a49499b1b3f50e4f4893150970463.tar.gz
==> Adding package util-macros@1.19.3 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/0f/0f812e6e9d2786ba8f54b960ee563c0663ddbe2434bf24ff193f5feab1f31971.tar.bz2
==> Adding package xz@5.2.5 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/51/5117f930900b341493827d63aa910ff5e011e0b994197c3b71c08a20228a42df.tar.bz2
==> Adding package zlib@1.2.11 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/c3/c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1.tar.gz
==> Successfully updated mirror in file:///home/spack/mirror
  Archive stats:
    1	 already present
    68	 added
    0	 failed to fetch.

This directory can be shared between users on a shared filesystem and protected with typical unix file permissions. If you’re making a spack mirror on a shared filesystem, remember to fix the file permissions every time you update the mirror, or update your umask settings so any new files you create have the appropriate permissions. Here you would replace the word spack to the appropriate unix group.

$ umask 750
$ chmod -R g+rs ~/mirror
$ chgrp -R spack ~/mirror

As long as spack can read from the mirror directory, spack will attempt to read source packages from the mirror instead of accessing the internet. This can be a huge boon for computers that can’t access the external internet but can access a shared filesystem. If you need to use spack on a system that is isolated from the external internet, you must bundle the whole spack mirror directory and unbundle it on the isolated system. From there, you follow the same steps to use the spack mirror as you would on any computer that can’t access the external internet.

If you need to add more sources to the mirror, you can re-run the command you used to create the mirror. For example, assume we want to add unzip to our environment.

$ spack add unzip
==> Adding unzip to environment /home/spack/cache-env
$ spack install
==> Starting concretization
==> Environment concretized in 0.51 seconds.
==> Concretized unzip
 -   a23m5gl  unzip@6.0%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64

==> Installing environment /home/spack/cache-env
==> Installing unzip-6.0-a23m5gldaggzi5saqfp47g2yw42wr7gi
==> Fetching file:///mirror/build_cache/linux-ubuntu18.04-x86_64/gcc-7.5.0/unzip-6.0/linux-ubuntu18.04-x86_64-gcc-7.5.0-unzip-6.0-a23m5gldaggzi5saqfp47g2yw42wr7gi.spack
==> Extracting unzip-6.0-a23m5gldaggzi5saqfp47g2yw42wr7gi from binary cache
[+] /home/spack/spack/opt/spack/linux-ubuntu18.04-x86_64/gcc-7.5.0/unzip-6.0-a23m5gldaggzi5saqfp47g2yw42wr7gi
==> Updating view at /home/spack/cache-env/.spack-env/view

Now that we’ve added unzip, we need to update the mirror.

$ spack mirror create -d ~/mirror --all
==> Adding package autoconf@2.69 to mirror
==> Adding package autoconf-archive@2019.01.06 to mirror
==> Adding package automake@1.16.3 to mirror
==> Adding package axl@0.5.0 to mirror
==> Adding package berkeley-db@18.1.40 to mirror
==> Adding package bzip2@1.0.8 to mirror
==> Adding package cmake@3.21.4 to mirror
==> Adding package curl@7.79.0 to mirror
==> Adding package diffutils@3.8 to mirror
==> Adding package dtcmp@1.1.3 to mirror
==> Adding package er@0.1.0 to mirror
==> Adding package expat@2.4.1 to mirror
==> Adding package gawk@5.1.0 to mirror
==> Adding package gdbm@1.19 to mirror
==> Adding package gettext@0.21 to mirror
==> Adding package glib@2.70.0 to mirror
==> Adding package gmp@6.2.1 to mirror
==> Adding package hdf5@1.10.7 to mirror
==> Adding package hwloc@2.6.0 to mirror
==> Adding package json-c@0.15 to mirror
==> Adding package json-cwx@0.12 to mirror
==> Adding package kvtree@1.2.0 to mirror
==> Adding package libbsd@0.11.3 to mirror
==> Adding package libedit@3.1-20210216 to mirror
==> Adding package libevent@2.1.12 to mirror
==> Adding package libffi@3.3 to mirror
==> Adding package libgcrypt@1.9.3 to mirror
==> Adding package libgpg-error@1.42 to mirror
==> Adding package libiconv@1.16 to mirror
==> Adding package libmd@1.0.3 to mirror
==> Adding package libpciaccess@0.16 to mirror
==> Adding package libsigsegv@2.13 to mirror
==> Adding package libtool@2.4.6 to mirror
==> Adding package libxml2@2.9.12 to mirror
==> Adding package libyogrt@1.24 to mirror
==> Adding package lwgrp@1.0.4 to mirror
==> Adding package lz4@1.9.3 to mirror
==> Adding package m4@1.4.19 to mirror
==> Adding package macsio@1.1 to mirror
==> Adding package meson@0.60.0 to mirror
==> Adding package mpfr@4.1.0 to mirror
==> Adding package munge@0.5.14 to mirror
==> Adding package ncurses@6.2 to mirror
==> Adding package ninja@1.10.2 to mirror
==> Adding package numactl@2.0.14 to mirror
==> Adding package openmpi@4.1.1 to mirror
==> Adding package openssh@8.7p1 to mirror
==> Adding package openssl@1.1.1l to mirror
==> Adding package pcre@8.44 to mirror
==> Adding package pdsh@2.31 to mirror
==> Adding package perl@5.34.0 to mirror
==> Adding package pkgconf@1.8.0 to mirror
==> Adding package py-setuptools@58.2.0 to mirror
==> Adding package python@3.8.12 to mirror
==> Adding package rankstr@0.1.0 to mirror
==> Adding package readline@8.1 to mirror
==> Adding package redset@0.1.0 to mirror
==> Adding package scr@3.0rc2 to mirror
==> Adding package shuffile@0.1.0 to mirror
==> Adding package silo@4.10.2 to mirror
==> Adding package slurm@21-08-1-1 to mirror
==> Adding package spath@0.1.0 to mirror
==> Adding package sqlite@3.36.0 to mirror
==> Adding package tar@1.34 to mirror
==> Adding package texinfo@6.5 to mirror
==> Adding package unzip@6.0 to mirror
==> Fetching https://mirror.spack.io/_source-cache/archive/03/036d96991646d0449ed0aa952e4fbe21b476ce994abc276e49d30e686708bd37.tar.gz
==> Adding package util-linux-uuid@2.36.2 to mirror
==> Adding package util-macros@1.19.3 to mirror
==> Adding package xz@5.2.5 to mirror
==> Adding package zlib@1.2.11 to mirror
==> Successfully updated mirror in file:///home/spack/mirror
  Archive stats:
    69	 already present
    1	 added
    0	 failed to fetch.

Spack will skip uploading source code packages that are already included in the spack mirror. Mirrors can be shared across different environments, meaning one mirror can house all the source code needed to build your team’s dependencies.

Setting up a binary cache mirror

If you’re going to be setting up a team to use spack as part of their development practice, you’ll run up against the biggest disadvantage to using spack: building all your packages from scratch is slow. Recompiling the software dependencies for a large project can take hours to complete. If every developer is rebuilding their own software stack, that leads to a massive waste of computational resources and a loss of developer productivity.

Spack has two ways to help alleviate this problem: chained spack instances and spack binary caches. For now, we’re going to discuss spack binary caches as a way of solving this issue.

A spack binary cache is made up of spack binary packages. Each spack binary package, ending with a *.spack extension, is a tarball of an installed spack package signed with a gpg signature. When you install a package from a mirror with a binary cache, spack

  • Checks to see if there is a spack binary package that exactly matches the hash of the spec you want to build.
  • If a binary package is found, spack checks to see if the signature on the spack binary package is trusted. If the signature isn’t trusted or no package was found, spack builds the package from source.
  • If the signature is trusted, then spack unzips and relocates the spack package.

For the user, spack binary caches are transparent to use. This is a clear departure from systems like conda, where you need to chose separate workflows for binary and source packages. We’ve already demonstrated using spack binary caches earlier in the tutorial when we set up spack to use a binary mirror. As a reminder, we ran:

$ spack mirror add tutorial /mirror
$ spack buildcache keys --install --trust
==> Fetching file:///mirror/build_cache/_pgp/8990E06AC18B52C31C9914C79328D01DE7FB5587.pub
gpg: key 9328D01DE7FB5587: public key "Spack Build Pipeline (Demo Key) <key@spack.demo>" imported
gpg: Total number processed: 1
gpg:		   imported: 1
gpg: inserting ownertrust of 6

Building a spack binary cache has some gotchas, but is almost as easy as building a source mirror. We’ll start by making a new environment for ourselves. Since we’re intending to publish to a binary cache, we’ll need to compile all these packages ourselves. This can take some time, so we’ll make a new environment with some packages that compile quickly.

$ cd ~
$ mkdir cache-binary
$ cd cache-binary
$ spack env create -d .
==> Updating view at /home/spack/cache-binary/.spack-env/view
==> Created environment in /home/spack/cache-binary
==> You can activate this environment with:
==>   spack env activate /home/spack/cache-binary
$ spacktivate .
$ spack add bzip2
==> Adding bzip2 to environment /home/spack/cache-binary
$ spack add zlib
==> Adding zlib to environment /home/spack/cache-binary

Before we build anything, we need to modify the following line in our spack configuration file. Then, just to be sure, we’ll initiate a build of this environment and force ourselves to not use any cache.

$ spack config add "config:install_tree:padded_length:128"
$ spack install --no-cache
==> Starting concretization pool with 2 processes
==> Environment concretized in 0.51 seconds.
==> Concretized bzip2
 -   55rtzz4  bzip2@1.0.8%gcc@7.5.0~debug~pic+shared arch=linux-ubuntu18.04-x86_64
 -   kg5jymj	  ^diffutils@3.8%gcc@7.5.0 arch=linux-ubuntu18.04-x86_64
 -   qi7dxj6	      ^libiconv@1.16%gcc@7.5.0 libs=shared,static arch=linux-ubuntu18.04-x86_64

==> Concretized zlib
 -   3rlgy7y  zlib@1.2.11%gcc@7.5.0+optimize+pic+shared arch=linux-ubuntu18.04-x86_64

==> Installing environment /home/spack/cache-binary
==> Installing libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig
==> Fetching https://mirror.spack.io/_source-cache/archive/e6/e6a1b1b589654277ee790cce3734f07876ac4ccfaecbee8afa0b649cf529cc04.tar.gz
==> No patches needed for libiconv
==> libiconv: Executing phase: 'autoreconf'
==> libiconv: Executing phase: 'configure'
==> libiconv: Executing phase: 'build'
==> libiconv: Executing phase: 'install'
==> libiconv: Successfully installed libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig
  Fetch: 0.75s.  Build: 25.54s.  Total: 26.30s.
[+] /home/spack/spack/opt/spack/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeh/linux-ubuntu18.04-x86_64/gcc-7.5.0/libiconv-1.16-qi7dxj6rgdydno5mdjzyolz6applztig
==> Installing zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
==> Fetching https://mirror.spack.io/_source-cache/archive/c3/c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1.tar.gz
==> No patches needed for zlib
==> zlib: Executing phase: 'install'
==> zlib: Successfully installed zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
  Fetch: 0.25s.  Build: 1.62s.	Total: 1.87s.
[+] /home/spack/spack/opt/spack/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeh/linux-ubuntu18.04-x86_64/gcc-7.5.0/zlib-1.2.11-3rlgy7ycxtoho44una6o3itgfjltkmpd
==> Installing diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy
==> Fetching https://mirror.spack.io/_source-cache/archive/a6/a6bdd7d1b31266d11c4f4de6c1b748d4607ab0231af5188fc2533d0ae2438fec.tar.xz
==> No patches needed for diffutils
==> diffutils: Executing phase: 'autoreconf'
==> diffutils: Executing phase: 'configure'
==> diffutils: Executing phase: 'build'
==> diffutils: Executing phase: 'install'
==> diffutils: Successfully installed diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy
  Fetch: 0.38s.  Build: 38.64s.  Total: 39.02s.
[+] /home/spack/spack/opt/spack/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeh/linux-ubuntu18.04-x86_64/gcc-7.5.0/diffutils-3.8-kg5jymjbqjurpq52nvycbddt5ia5uypy
==> Installing bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3
==> Fetching https://mirror.spack.io/_source-cache/archive/ab/ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269.tar.gz
==> Ran patch() for bzip2
==> bzip2: Executing phase: 'install'
==> bzip2: Successfully installed bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3
  Fetch: 0.26s.  Build: 1.81s.	Total: 2.07s.
[+] /home/spack/spack/opt/spack/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeh/linux-ubuntu18.04-x86_64/gcc-7.5.0/bzip2-1.0.8-55rtzz4s6m4swr6x7exse22ucbmluwl3
==> Updating view at /home/spack/cache-binary/.spack-env/view

This configuration change ensures that spack installs all our packages to a path that is at least 128 characters. We need this change because of how spack relocates packages. Relocation consists of the following steps:

  • Search all text files to replace the package builder’s path with your specific local installation path.
  • Use patchelf to replace all the RPATHs in your binaries to point to your specific local installation path.
  • Search all binaries to replace hard-coded C strings of the package builder’s path with your specific local installation path.

Adding padding ensures that any paths hard-coded as C strings in our binaries will be large enough to hold our user’s eventual install path. We advise picking 128 because longer strings occasionally cause compilation problems with some software packages. If the user’s install path is too long, spack will give you a warning. All scripts and and RPATHs will still be properly relocated, but C strings within any binaries will not be modified. Depending on the package, this may cause problems when you try and use the software.

We also need to create a gpg key to sign all our packages. You should back up the secret and public keys to a secure place so they can be re-used in the future.

$ spack gpg create "My Name" "<my.email@my.domain.com>"
gpg: key 95DED62473FE0770 marked as ultimately trusted
gpg: directory '/home/spack/spack/opt/spack/gpg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/spack/spack/opt/spack/gpg/openpgp-revocs.d/C0A952C3A72452C00128783995DED62473FE0770.rev'
$ mkdir ~/private_gpg_backup
$ cp ~/spack/opt/spack/gpg/*.gpg ~/private_gpg_backup
$ cp ~/spack/opt/spack/gpg/pubring.* ~/mirror

With this setup done, we’re ready to fill a binary cache with binary packages. Binary packages are attached to an existing source mirror. We follow the same steps we used for the source mirror – making an environment, creating the source mirror, and building the packages to a spack installation with our padded path. To upload a spec to a binary cache, simply use the command spack buildcache create --only=package spec. We use this here in a for loop to create binary packages for every non-external package in our environment. We do this by writing a find command that will return a hash of each spec in this environment and filtering out the external packages.

$
for ii in $(spack find --format "yyy {version} /{hash}" |
	    grep -v -E "^(develop^master)" |
	    grep "yyy" |
	    cut -f3 -d" ")
do
  spack buildcache create --allow-root --force -d ~/mirror --only=package $ii
done
==> Buildcache files will be output to file:///home/spack/mirror/build_cache
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:	2  signed:   0	trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: using "C0A952C3A72452C00128783995DED62473FE0770" as default secret key for signing
==> Buildcache files will be output to file:///home/spack/mirror/build_cache
gpg: using "C0A952C3A72452C00128783995DED62473FE0770" as default secret key for signing
==> Buildcache files will be output to file:///home/spack/mirror/build_cache
gpg: using "C0A952C3A72452C00128783995DED62473FE0770" as default secret key for signing
==> Buildcache files will be output to file:///home/spack/mirror/build_cache
gpg: using "C0A952C3A72452C00128783995DED62473FE0770" as default secret key for signing

Voila, done! Our spack mirror has now been augmented with a binary cache. This cache can be used on systems without external internet access, just like with a spack source mirror. As always, remember to update the file permissions after updating the mirror.

$ umask 750
$ chmod -R g+rs ~/mirror
$ chgrp -R spack ~/mirror

Though it’s outside the scope of this tutorial, spack mirrors and build caches can also be hosted over https:// and s3:// as well. Consult the spack documentation for more information on how to do this.

Before a user can use this binary cache, they will need to make sure that they trust all the packages listed in the binary cache. If you’re sharing files between trusted users on a filesystem, you can do this with the following command:

$ spack buildcache keys --install --trust --force
==> Fetching file:///mirror/build_cache/_pgp/8990E06AC18B52C31C9914C79328D01DE7FB5587.pub
gpg: key 9328D01DE7FB5587: "Spack Build Pipeline (Demo Key) <key@spack.demo>" not changed
gpg: Total number processed: 1
gpg:		  unchanged: 1

Together, this means download all the keys on the binary cache and trust them. Have your users run the above command on a new spack instance before they initiate a build.

Cache Summary

If you’re using spack within a development team, consider setting up source mirrors with binary caches. Source mirrors will let you replicate a spack environment on a machine without external internet access, and binary mirrors free you from the burden of recompiling everything from scratch and save you development time.