├── wlm_integration ├── slurm │ ├── test │ │ ├── .gitignore │ │ ├── test_udiRoot.conf.in │ │ ├── test_shifterSpank_prolog.cpp │ │ ├── test_shifterSpank_util.cpp │ │ ├── test_shifterSpank_config.cpp │ │ ├── test_shifterSpank_cgroup.cpp │ │ └── Makefile.am │ ├── Makefile.am │ ├── wrapper.h │ └── udiRoot-epilogue.in ├── torque │ ├── README │ ├── Makefile │ ├── qsetenv.man8 │ └── qsetenv.8 └── cray │ ├── udiRoot-nhc-plugin.in │ └── Makefile ├── imagegw ├── test │ ├── cleanup.sh │ ├── postmount.sh │ ├── premount.sh │ ├── sha256sum │ ├── test.squashfs │ ├── fasthash │ ├── oci-image-tool │ ├── exam.sh │ ├── mkfs.cramfs │ ├── umoci │ ├── mksquashfs │ ├── munge │ ├── scp │ ├── tar │ ├── __init__.py │ ├── init.sh │ ├── ssh │ ├── config │ │ ├── imagemanager.json │ │ └── nersc.pem │ ├── unmunge │ ├── entrypoint.sh │ ├── munge_test.py │ ├── auth_test.py │ └── skopeo ├── requirements.txt ├── sitecustomize.py ├── .dockerignore ├── scanner_install.sh ├── Makefile.am ├── shifter_imagegw │ ├── Makefile.am │ ├── fasthash.py │ ├── __init__.py.in │ ├── tarfilemp.py │ └── util.py ├── docker-compose.yml ├── imagemanager.json.example ├── Makefile.test ├── entrypoint.sh ├── imagegwapi.py ├── imagemanager.schema.json ├── Dockerfile ├── test.json.example ├── README.md └── imagecli.py ├── src ├── test │ ├── .gitignore │ ├── data_config1.conf │ ├── shifter_sleep_test │ ├── data_config2.conf │ ├── data_config3.conf │ ├── data_config4.conf │ ├── etc_small │ │ └── group │ ├── setup_test_chroot.sh │ ├── valgrind.suppressions │ ├── chroot3 │ │ └── etc │ │ │ ├── group │ │ │ ├── nsswitch.conf │ │ │ └── passwd │ ├── etc │ │ ├── group │ │ ├── nsswitch.conf │ │ └── passwd │ ├── chroot1 │ │ └── etc │ │ │ ├── group │ │ │ ├── nsswitch.conf │ │ │ └── passwd │ ├── chroot2 │ │ └── etc │ │ │ ├── group │ │ │ ├── nsswitch.conf │ │ │ └── passwd │ ├── test_udiRoot.conf.in │ └── test_shifterimg.cpp ├── TODO ├── shiftrun.in ├── shifter_mem.h ├── Makefile.am ├── shifterimg.h ├── shifter_mem.c ├── unsetupRoot.c └── MountList.h ├── .coveragerc ├── .dockerignore ├── extra ├── CI │ ├── integration │ │ ├── libdummy32bit.so │ │ ├── libdummy64bit.so │ │ ├── test_etcmtab.py │ │ ├── test_capabilities.py │ │ ├── test_shifterConfig_format.py │ │ └── test_etcpasswd.py │ ├── base_udiRoot.conf │ ├── imagemanager.json │ ├── test_script.sh │ └── integration_test.sh ├── python │ ├── README.md │ └── shifter-python.spec ├── cle6 │ └── ansible │ │ ├── roles │ │ └── shifter │ │ │ ├── files │ │ │ ├── postmount.sh │ │ │ └── premount.sh │ │ │ ├── vars │ │ │ └── cluster.yaml │ │ │ └── tasks │ │ │ └── main.yaml │ │ └── shifter.yaml ├── systemd │ ├── shifter_imagegw_36.service │ ├── shifter_imagegw.service │ └── shifter_imagegw-2.7.service ├── Makefile.am ├── shifter_cray_mpich.spec.in ├── shifter_cle6_kmod_deps.spec.cray ├── build_cray_kernel_modules.sh ├── shifter_slurm_dws_support.c ├── setup_udiRoot_etc_files.sh └── oscap-scan.py ├── etc_files ├── Makefile.am └── nsswitch.conf ├── Makefile.am ├── contrib ├── README.md ├── shifter-imagegw ├── shifter-imagegw_init_d └── shifter-imagegw_build_env ├── auxdir ├── ac_define_dir.m4 ├── x_ac_munge.m4 ├── x_ac_jsonc.m4 └── x_ac_slurm.m4 ├── AUTHORS ├── dep ├── build_mount.sh ├── cpputest.sh └── Makefile.am ├── doc ├── skopeo.rst ├── index.rst ├── command │ └── shifter.rst ├── install │ └── centos7.rst ├── PrivateImagesAndACLS.md ├── import.md ├── modules.rst ├── api │ └── authentication.rst ├── faq.rst └── sshd.rst ├── .gitignore ├── README.md ├── LICENSE ├── .travis.yml ├── Dockerfile └── autogen.sh /wlm_integration/slurm/test/.gitignore: -------------------------------------------------------------------------------- 1 | *.trs 2 | -------------------------------------------------------------------------------- /imagegw/test/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exit 0 4 | -------------------------------------------------------------------------------- /imagegw/test/postmount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exit 0 4 | -------------------------------------------------------------------------------- /imagegw/test/premount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exit 0 4 | -------------------------------------------------------------------------------- /src/test/.gitignore: -------------------------------------------------------------------------------- 1 | chroot*/lib* 2 | chroot*/nss 3 | *.trs 4 | -------------------------------------------------------------------------------- /imagegw/test/sha256sum: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec shasum -a 256 $* 4 | -------------------------------------------------------------------------------- /imagegw/requirements.txt: -------------------------------------------------------------------------------- 1 | pymongo==3.12.1 2 | sanic==20.9.1 3 | pylint 4 | -------------------------------------------------------------------------------- /imagegw/sitecustomize.py: -------------------------------------------------------------------------------- 1 | """ 2 | Site customize to fix unicode issue 3 | """ 4 | -------------------------------------------------------------------------------- /src/test/data_config1.conf: -------------------------------------------------------------------------------- 1 | first: abcdefg 2 | second : 10 3 | third: 3.14159 4 | -------------------------------------------------------------------------------- /src/test/shifter_sleep_test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | title=$1 3 | exec -a "$title" sleep 100 4 | 5 | -------------------------------------------------------------------------------- /imagegw/test/test.squashfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NERSC/shifter/HEAD/imagegw/test/test.squashfs -------------------------------------------------------------------------------- /src/test/data_config2.conf: -------------------------------------------------------------------------------- 1 | first: abcdefg 2 | second : 10 3 | third: 3.14159 4 | forth: qwerty 5 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | omit = 3 | */python?.?/* 4 | */site-packages/nose/* 5 | */test/* 6 | -------------------------------------------------------------------------------- /imagegw/test/fasthash: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | D=$(dirname $0) 4 | python $D/../shifter_imagegw/fasthash.py $@ 5 | -------------------------------------------------------------------------------- /src/test/data_config3.conf: -------------------------------------------------------------------------------- 1 | first: abcdefg \ 2 | qed \ 3 | feg 4 | second : 10 5 | third: 3.14159 6 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | test.json 2 | docker-compose.yml 3 | imagegw/test/config 4 | *.pyc 5 | rpms 6 | autom4te.cache 7 | -------------------------------------------------------------------------------- /imagegw/.dockerignore: -------------------------------------------------------------------------------- 1 | test.json 2 | docker-compose.yml 3 | test/config 4 | *.pyc 5 | private 6 | *__pycache__* 7 | -------------------------------------------------------------------------------- /imagegw/test/oci-image-tool: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Mock oci image tool (just exit without an error) 4 | exit 0 5 | -------------------------------------------------------------------------------- /extra/CI/integration/libdummy32bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NERSC/shifter/HEAD/extra/CI/integration/libdummy32bit.so -------------------------------------------------------------------------------- /extra/CI/integration/libdummy64bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NERSC/shifter/HEAD/extra/CI/integration/libdummy64bit.so -------------------------------------------------------------------------------- /src/test/data_config4.conf: -------------------------------------------------------------------------------- 1 | first: abcdefg \ 2 | qed \ 3 | feg 4 | second : 10 5 | third: 3.14159 6 | : invalid field 7 | -------------------------------------------------------------------------------- /src/test/etc_small/group: -------------------------------------------------------------------------------- 1 | grp1:x:100: 2 | grp2:x:200:user1,user3 3 | grp3:x:300:user2,user3 4 | grp4:x:400:user1,user2,user3 5 | -------------------------------------------------------------------------------- /extra/python/README.md: -------------------------------------------------------------------------------- 1 | # Shifter-Python 2 | 3 | This is a spec file to create an RPM with dependencies needed to 4 | run the image gateway. 5 | -------------------------------------------------------------------------------- /imagegw/test/exam.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | path=$1 3 | id=$2 4 | 5 | if [ "$2" = "bogus" ] ; then 6 | exit 0 7 | else 8 | exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /imagegw/test/mkfs.cramfs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Mock for mkfs.cramfs for testing purposes 3 | # 4 | (echo "mock mkfs.cramfs called with $@";date) > $2 5 | -------------------------------------------------------------------------------- /imagegw/test/umoci: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Mock umoci 4 | 5 | [ -z "$UMOCI_FAIL" ] || exit 1 6 | 7 | DDIR=$(echo $5) 8 | mkdir -p $DDIR/rootfs 9 | mkdir -p $DDIR/rootfs/bin 10 | 11 | -------------------------------------------------------------------------------- /extra/cle6/ansible/roles/shifter/files/postmount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # customize this file to perform any post-sitefs-mount operations 3 | # e.g., at NERSC, we symlink some paths 4 | 5 | exit 0 6 | -------------------------------------------------------------------------------- /imagegw/test/mksquashfs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # For test purposes on a mac 4 | (echo "mock mksquahfs called with $@";date) > $2 5 | # ret = subprocess.call(["mksquashfs", expandedPath, imageTempPath, "-all-root"]) 6 | -------------------------------------------------------------------------------- /imagegw/scanner_install.sh: -------------------------------------------------------------------------------- 1 | yum -y install cmake openscap-utils openscap-python python-lxml git 2 | git clone https://github.com/OpenSCAP/scap-security-guide.git 3 | cd scap-security-guide/build 4 | cmake .. 5 | make -j4 6 | make install 7 | -------------------------------------------------------------------------------- /imagegw/test/munge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Mock munge - For test purposes only 4 | # 5 | T=$(dirname $0) 6 | 7 | if [ ! -z "$IP" ] ; then 8 | ssh -i test/ssh.key $IP -p $PORT -l root munge $@ 9 | else 10 | cat $T/munge.test 11 | fi 12 | -------------------------------------------------------------------------------- /extra/cle6/ansible/roles/shifter/files/premount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p lus 4 | ## recommended cray paths 5 | #mkdir -p var/opt/cray/alps 6 | #mkdir -p var/run 7 | #mkdir -p var/spool 8 | #mkdir -p etc/opt/cray 9 | 10 | exit 0 11 | -------------------------------------------------------------------------------- /etc_files/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | shifter_etc_filesdir = $(shifter_etc_files) 4 | dist_shifter_etc_files_DATA = nsswitch.conf passwd group 5 | 6 | passwd: 7 | getent passwd > ./passwd 8 | 9 | group: 10 | getent group > ./group 11 | -------------------------------------------------------------------------------- /extra/CI/integration/test_etcmtab.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pexpect 4 | import subprocess 5 | import sys 6 | 7 | image_name = sys.argv[1] 8 | 9 | pex = pexpect.spawnu("shifter --image=%s ls -ld /etc/mtab" % image_name) 10 | pex.expect('/proc/mounts') 11 | -------------------------------------------------------------------------------- /imagegw/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = shifter_imagegw 2 | 3 | dist_pkglibexec_SCRIPTS = imagecli.py \ 4 | imagegwapi.py \ 5 | sitecustomize.py 6 | 7 | dist_sysconf_DATA = imagemanager.json.example 8 | 9 | shifterdatadir=$(datadir)/$(PACKAGE_NAME) 10 | dist_shifterdata_DATA = requirements.txt 11 | -------------------------------------------------------------------------------- /src/test/setup_test_chroot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | chrootdir=$1 4 | 5 | if [[ -z "$chrootdir" ]]; then 6 | exit 1 7 | fi 8 | 9 | while read -r path; do 10 | directory=$(dirname "$path") 11 | 12 | mkdir -p "$chrootdir/$directory" 13 | cp -p "$path" "$chrootdir/$directory" 14 | 15 | 16 | done < <(find /lib/ /lib64/ -name libnss_files\*) 17 | -------------------------------------------------------------------------------- /etc_files/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/nsswitch.conf 3 | # 4 | passwd: files 5 | group: files 6 | 7 | hosts: files dns 8 | networks: files dns 9 | 10 | services: files 11 | protocols: files 12 | rpc: files 13 | ethers: files 14 | netmasks: files 15 | netgroup: files 16 | publickey: files 17 | 18 | bootparams: files 19 | automount: files 20 | aliases: files 21 | -------------------------------------------------------------------------------- /extra/CI/integration/test_capabilities.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pexpect 4 | import subprocess 5 | import sys 6 | 7 | image_name = sys.argv[1] 8 | 9 | pex = pexpect.spawnu("shifter --image=%s cat /proc/self/status | grep Cap" % image_name) 10 | pex.expect('CapInh:\s+0+') 11 | pex.expect('CapPrm:\s+0+') 12 | pex.expect('CapEff:\s+0+') 13 | pex.expect('CapBnd:\s+0+') 14 | -------------------------------------------------------------------------------- /wlm_integration/torque/README: -------------------------------------------------------------------------------- 1 | qsetenv 2 | Douglas Jacobsen 3 | 4 | Simple tool to append an environment variable to the list of 5 | variables of a pending job. Clearly, if the job is already 6 | running it will have no effect unless the job is rescheduled. 7 | 8 | See qsetenv(8) for more information. 9 | 10 | Source is stored in scm:/data/svn-nsg/common/cmd/qsetenv 11 | -------------------------------------------------------------------------------- /imagegw/shifter_imagegw/Makefile.am: -------------------------------------------------------------------------------- 1 | shifter_imagegw_PYTHON = auth.py \ 2 | api.py \ 3 | converters.py \ 4 | dockerv2.py \ 5 | dockerv2_ext.py \ 6 | tarfilemp.py \ 7 | imagemngr.py \ 8 | imageworker.py \ 9 | __init__.py \ 10 | munge.py \ 11 | transfer.py \ 12 | fasthash.py \ 13 | util.py 14 | 15 | shifter_imagegwdir = $(pyexecdir)/shifter_imagegw 16 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = foreign 2 | ACLOCAL_AMFLAGS = -I auxdir 3 | SUBDIRS = dep src extra imagegw etc_files 4 | DISTCHECK_CONFIGURE_FLAGS = --disable-staticsshd 5 | 6 | if WITH_SLURM 7 | SUBDIRS += wlm_integration/slurm 8 | endif WITH_SLURM 9 | 10 | sysconf_DATA=udiRoot.conf.example 11 | EXTRA_DIST = AUTHORS Dockerfile LICENSE NEWS README.md autogen.sh config.h contrib doc shifter.spec 12 | -------------------------------------------------------------------------------- /imagegw/test/scp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Mock scp 3 | # if the target host is localhost, then just cp 4 | # 5 | 6 | let last=$#-1 7 | array=( "$@" ) 8 | 9 | src=${array[$last-1]} 10 | target=$(echo ${array[$last]}|sed 's|.*:/|/|') 11 | host=$(echo ${array[$last]}|sed 's|.*@||'|sed 's|:.*||') 12 | if [ $host = "localhost" ] ; then 13 | exec cp $src $target 14 | else 15 | exec /usr/bin/scp $@ 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /contrib/README.md: -------------------------------------------------------------------------------- 1 | # Contributed scripts 2 | 3 | * ```shifter-imagegw_build_env``` is an example of how to build a self-contained Python environment to run ```shifter-imagegw```. This is required to run ```shifter-imagegw``` script. 4 | * ```shifter-imagegw``` is an example of how to launch shifter-imagegw with one queue 5 | * ```shifter-imagegw_init_d``` is an example of how to make shifter-imagegw startup as a system V service. 6 | -------------------------------------------------------------------------------- /extra/systemd/shifter_imagegw_36.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Shifter image manager 3 | After=munge.service 4 | 5 | [Service] 6 | Type=simple 7 | User=shifter 8 | Group=shifter 9 | PrivateTmp=true 10 | Environment=PYTHONPATH=/opt/shifter-python-21.12/ 11 | PermissionsStartOnly=true 12 | ExecStart=/usr/bin/python3.6 -m shifter_imagegw.api 13 | Restart=on-failure 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | 18 | -------------------------------------------------------------------------------- /imagegw/test/tar: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Mock tar 4 | # This is just to hide errors that seem to only happen in a docker container. 5 | # So, let's just ignore tar errors for now. 6 | # 7 | 8 | if [ -e /bin/tar ] ; then 9 | TAR=/bin/tar 10 | elif [ -e /usr/bin/tar ] ; then 11 | TAR=/usr/bin/tar 12 | else 13 | echo "tar not found" 1>&2 14 | exit 1 15 | fi 16 | 17 | $TAR $(echo "$@"|sed 's/--force-local//') 18 | exit 0 19 | -------------------------------------------------------------------------------- /auxdir/ac_define_dir.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AC_DEFINE_DIR], [ 2 | prefix_NONE= 3 | exec_prefix_NONE= 4 | test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix 5 | test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix 6 | eval ac_define_dir="\"[$]$2\"" 7 | AC_SUBST($1, "$ac_define_dir") 8 | AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3]) 9 | test "$prefix_NONE" && prefix=NONE 10 | test "$exec_prefix_NONE" && exec_prefix=NONE 11 | ]) 12 | -------------------------------------------------------------------------------- /imagegw/test/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | 4 | 5 | def setup(): 6 | print("Module setup") 7 | os.environ['GWCONFIG'] = 'test.json' 8 | os.environ['CONFIG'] = 'test.json' 9 | os.environ['ENABLE_LABELS'] = '1' 10 | test_dir = os.path.dirname(os.path.abspath(__file__)) 11 | os.environ['PATH'] = '%s:%s' % (test_dir, os.environ['PATH']) 12 | # Create __init__ 13 | 14 | 15 | def teardown(): 16 | subprocess.check_call("cleanup.sh") 17 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Shifter was authored at the Lawrence Berkeley National Laboratory by the National Energy Research Scientific Computing Center (NERSC) 2 | 3 | This work has accepted contributions from: 4 | Shane Canon (NERSC) 5 | Douglas M. Jacobsen (NERSC) 6 | Miguel Gila (CSCS) 7 | Carles Fenoy (Barcelona Supercomputing Center) 8 | Kean Mariotti (CSCS) 9 | Alberto Madonna (CSCS) 10 | Felipe Cruz (CSCS) 11 | 12 | Please review the LICENSE file for more information about the terms of Shifter software distribution. 13 | -------------------------------------------------------------------------------- /contrib/shifter-imagegw: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author: 4 | # Miguel Gila 5 | # 6 | # 7 | if [ -z ${ROOT_TREE} ]; then 8 | ROOT_TREE='/opt/shifter/15.12.0' 9 | fi 10 | 11 | if [ -z ${PYTHON_VENV} ]; then 12 | PYTHON_VENV='imagegw_venv' 13 | fi 14 | 15 | if [ -z ${SHIFTER_SYSTEM_NAME} ]; then 16 | SHIFTER_SYSTEM_NAME='system_name' 17 | fi 18 | QA="${SHIFTER_SYSTEM_NAME}" 19 | 20 | cd ${ROOT_TREE} 21 | source ${PYTHON_VENV}/bin/activate 22 | echo "Starting imagegw API" 23 | python ./imagegwapi.py 24 | -------------------------------------------------------------------------------- /src/TODO: -------------------------------------------------------------------------------- 1 | Douglas Jacobsen 2 | 2015/06/11 3 | 4 | * Need to finish adding config validation support to ensure setupRoot isn't 5 | getting tricked into handing out privilege (i.e. check for safe file 6 | ownership, write perms etc). Would be nice to have a better way. 7 | 8 | * Add sshd configuration to shifter_core/prepareSiteModifications() 9 | 10 | * Rely on recent versions of mount understanding autoclear functionality for 11 | loop device management. OK in CLE 5.2, may need to add more explicit loop 12 | device management for other systems. 13 | 14 | * Add unittest 15 | -------------------------------------------------------------------------------- /imagegw/test/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export PATH=$PATH:$(pwd)/test/ 4 | 5 | function refreshmunge { 6 | export MUNGE=$(grep auth ~/.dockercfg |sed 's/",//'|sed 's/.*"//'|systema munge ) 7 | } 8 | 9 | function update { 10 | IP=$(docker-machine ip $(docker-machine active)) 11 | PORT=$(docker-compose ps systema|grep systema|sed 's/.*://'|sed 's/-.*//') 12 | alias systemaroot="ssh -i test/config/ssh.key $IP -p $PORT -l root" 13 | alias systema="ssh -i test/config/ssh.key $IP -p $PORT" 14 | echo y|ssh -i test/config/ssh.key $IP -p $PORT -l root date 15 | export IMAGEGW="$IP:5555" 16 | } 17 | -------------------------------------------------------------------------------- /src/test/valgrind.suppressions: -------------------------------------------------------------------------------- 1 | { 2 | ShifterCopyEnvTESTwithExplicitLeak 3 | Memcheck:Leak 4 | fun:malloc 5 | fun:strdup 6 | fun:_Z7copyenvv 7 | fun:_ZN40TEST_ShifterTestGroup_CopyEnv_basic_Test8testBodyEv 8 | fun:PlatformSpecificSetJmp 9 | fun:_ZN5Utest3runEv 10 | fun:_ZN10UtestShell26runOneTestInCurrentProcessEP10TestPluginR10TestResult 11 | fun:PlatformSpecificSetJmp 12 | fun:_ZN10UtestShell10runOneTestEP10TestPluginR10TestResult 13 | fun:_ZN12TestRegistry11runAllTestsER10TestResult 14 | fun:_ZN21CommandLineTestRunner11runAllTestsEv 15 | fun:_ZN21CommandLineTestRunner15runAllTestsMainEv 16 | } 17 | -------------------------------------------------------------------------------- /extra/CI/integration/test_shifterConfig_format.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pexpect 4 | import subprocess 5 | import sys 6 | 7 | image_name = sys.argv[1] 8 | 9 | pex = pexpect.spawnu("whoami") 10 | pex.expect('(\S+)') 11 | username = pex.match.groups()[0] 12 | 13 | pex = pexpect.spawnu("shifterimg lookup %s" % image_name) 14 | pex.expect('([0-9a-f]+)') 15 | image_id = pex.match.groups()[0] 16 | 17 | expected_config = '{"identifier":"%s","user":"%s","volMap":"","modules":""}' \ 18 | % (image_id, username) 19 | 20 | pex = pexpect.spawnu("shifter --image=%s cat /var/shifterConfig.json" % image_name) 21 | pex.expect(expected_config) 22 | -------------------------------------------------------------------------------- /extra/cle6/ansible/shifter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: shifter 4 | hosts: localhost 5 | 6 | vars: 7 | run_after: 8 | - early 9 | - persistent_data 10 | - service_node 11 | - ssh 12 | 13 | run_before: 14 | - slurm 15 | 16 | tasks: 17 | - set_fact: 18 | shifterConfigure: True 19 | when: ((ansible_local.cray_system_elogin is defined) or 20 | (ansible_local.cray_system.platform == "compute") or 21 | ('mom' in ansible_local.cray_system.node_groups)) and 22 | (not ansible_local.cray_system.in_init) 23 | 24 | roles: 25 | - role: shifter 26 | when: shifterConfigure is defined and shifterConfigure 27 | -------------------------------------------------------------------------------- /extra/systemd/shifter_imagegw.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Shifter image manager 3 | After=munge.service 4 | 5 | [Service] 6 | Type=simple 7 | User=shifter 8 | Group=shifter 9 | PrivateTmp=true 10 | PermissionsStartOnly=true 11 | ExecStartPre=/usr/bin/mkdir -p /var/log/shifter_imagegw 12 | ExecStartPre=/usr/bin/chown shifter:shifter /var/log/shifter_imagegw 13 | ExecStart=/usr/bin/gunicorn \ 14 | -b 0.0.0.0:5000 --backlog 2048 \ 15 | --access-logfile=/var/log/shifter_imagegw/access.log \ 16 | --log-file=/var/log/shifter_imagegw/error.log \ 17 | -t 3600 \ 18 | shifter_imagegw.api:app 19 | Restart=on-failure 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | 24 | -------------------------------------------------------------------------------- /extra/systemd/shifter_imagegw-2.7.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Shifter image manager 3 | After=munge.service 4 | 5 | [Service] 6 | Type=simple 7 | User=shifter 8 | Group=shifter 9 | PrivateTmp=true 10 | PermissionsStartOnly=true 11 | ExecStartPre=/usr/bin/mkdir -p /var/log/shifter_imagegw 12 | ExecStartPre=/usr/bin/chown shifter:shifter /var/log/shifter_imagegw 13 | ExecStart=/usr/bin/gunicorn-2.7 \ 14 | -b 0.0.0.0:5000 --backlog 2048 \ 15 | --access-logfile=/var/log/shifter_imagegw/access.log \ 16 | --log-file=/var/log/shifter_imagegw/error.log \ 17 | -t 3600 \ 18 | shifter_imagegw.api:app 19 | Restart=on-failure 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | 24 | -------------------------------------------------------------------------------- /extra/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | AM_CPPFLAGS = -DCONFIG_FILE=\"${sysconfdir}/udiRoot.conf\" -DLIBEXECDIR=\"${libexecdir}/shifter\" -I$(top_srcdir)/src -Wall 4 | 5 | pkglibexec_PROGRAMS = shifter_slurm_dws_support 6 | 7 | SHIFTER_SLURM_DWS_SUPPORT_SOURCES = \ 8 | shifter_slurm_dws_support.c \ 9 | $(top_srcdir)/src/UdiRootConfig.c \ 10 | $(top_srcdir)/src/utility.c \ 11 | $(top_srcdir)/src/VolumeMap.c \ 12 | $(top_srcdir)/src/MountList.c \ 13 | $(top_srcdir)/src/PathList.c \ 14 | $(top_srcdir)/src/shifter_core.c \ 15 | $(top_srcdir)/src/shifter_mem.c 16 | 17 | 18 | shifter_slurm_dws_support_SOURCES = $(SHIFTER_SLURM_DWS_SUPPORT_SOURCES) 19 | 20 | EXTRA_DIST = cle6 systemd 21 | -------------------------------------------------------------------------------- /imagegw/test/ssh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Mock ssh 3 | # if the target host is localhost, then just exec the command 4 | # 5 | 6 | function getCmd { 7 | host= 8 | while [[ -n $1 ]]; do 9 | if [[ "$1" == *@* ]]; then 10 | host=$(echo $1 | sed 's|.*@||') 11 | shift 12 | break 13 | fi 14 | shift 15 | done 16 | if [[ "$host" != "localhost" ]]; then 17 | return 1 18 | fi 19 | while [[ -n $1 ]]; do 20 | echo -n "$1 " 21 | shift 22 | done 23 | return 0 24 | } 25 | 26 | localCmd=$(getCmd "$@") 27 | retStatus=$? 28 | if [[ -z "$localCmd" ]]; then 29 | exec /usr/bin/ssh "$@" 30 | else 31 | exec $localCmd 32 | fi 33 | -------------------------------------------------------------------------------- /extra/CI/base_udiRoot.conf: -------------------------------------------------------------------------------- 1 | udiMount=/var/udiMount 2 | loopMount=/var/udiLoopMount 3 | 4 | imagePath=/images 5 | udiRootPath=/usr 6 | optUdiImage=/usr/libexec/shifter/opt/udiImage 7 | etcPath=/etc/shifter/shifter_etc_files 8 | mountUdiRootWritable=1 9 | maxGroupCount=31 10 | modprobePath=/sbin/modprobe 11 | insmodPath=/sbin/insmod 12 | cpPath=/usr/bin/cp 13 | mvPath=/usr/bin/mv 14 | chmodPath=/usr/bin/chmod 15 | ddPath=/usr/bin/dd 16 | mkfsXfsPath=/sbin/mkfs.xfs 17 | rootfsType=tmpfs 18 | siteFs=/home:/home 19 | siteEnv=SHIFTER_RUNTIME=1 20 | siteEnvAppend=PATH=/opt/udiImage/bin 21 | imageGateway=http://localhost:8000 22 | system=mycluster 23 | defaultImageType=docker 24 | populateEtcDynamically = 1 25 | allowLibcPwdCalls = 1 26 | -------------------------------------------------------------------------------- /extra/CI/integration/test_etcpasswd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import subprocess 4 | import sys 5 | 6 | image_name = sys.argv[1] 7 | 8 | proc = subprocess.Popen(['whoami'], stdout=subprocess.PIPE) 9 | stdout, _ = proc.communicate() 10 | username = stdout.strip() 11 | 12 | proc = subprocess.Popen(['getent','passwd',username], stdout=subprocess.PIPE) 13 | passwd = proc.communicate()[0].decode("utf-8").rstrip() 14 | 15 | cmd = ['shifter', '--image=%s' % (image_name), 'cat', '/etc/passwd'] 16 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) 17 | out = proc.communicate()[0].decode("utf-8") 18 | 19 | for line in out.split('\n'): 20 | if line.startswith(passwd): 21 | sys.exit(0) 22 | 23 | sys.exit(1) 24 | 25 | -------------------------------------------------------------------------------- /dep/build_mount.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | unset CFLAGS 5 | unset CPPFLAGS 6 | 7 | origdir=$( pwd ) 8 | mkdir -p build_mount 9 | cd build_mount 10 | builddir=$( pwd ) 11 | 12 | if [[ -n "$DEPTAR_DIR" && -e "$DEPTAR_DIR/util-linux-2.34.tar.gz" ]]; then 13 | cp "$DEPTAR_DIR/util-linux-2.34.tar.gz" . 14 | fi 15 | 16 | if [[ ! -e "util-linux-2.34.tar.gz" ]]; then 17 | curl -L -k -o "util-linux-2.34.tar.gz" "https://www.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.gz" 18 | fi 19 | 20 | cd "${builddir}" 21 | mkdir -p util-linux 22 | tar xf "util-linux-2.34.tar.gz" -C util-linux --strip-components=1 23 | cd util-linux 24 | CC=gcc ./configure --enable-static --disable-shared 25 | CC=gcc make mount 26 | cp -p mount "${origdir}/" 27 | -------------------------------------------------------------------------------- /imagegw/shifter_imagegw/fasthash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import hashlib 4 | import argparse 5 | 6 | 7 | def fast_hash(infile): 8 | """ 9 | Calculate a sha256 hash of the first MB of a file and every 512MB offset 10 | """ 11 | 12 | m = hashlib.sha256() 13 | with open(infile, 'rb', 1024 * 1024) as f: 14 | l = f.read(1024 * 1024) 15 | while (len(l) > 0): 16 | m.update(l) 17 | f.seek(1024 * 1024 * (512 - 1), 1) 18 | l = f.read(1024 * 1024) 19 | return m.hexdigest() 20 | 21 | 22 | if __name__ == '__main__': 23 | parser = argparse.ArgumentParser(description='Calculate file hash') 24 | parser.add_argument('infile', nargs=1, type=str) 25 | 26 | args = parser.parse_args() 27 | infile = args.infile[0] 28 | 29 | print(fast_hash(infile)) 30 | -------------------------------------------------------------------------------- /imagegw/docker-compose.yml: -------------------------------------------------------------------------------- 1 | api: 2 | image: imagegwapi 3 | ports: 4 | - 5555:8000 5 | links: 6 | - mongo 7 | volumes: 8 | - imagegw:/images 9 | - munge:/var/run/munge/ 10 | - ./test/config:/config 11 | command: api 12 | munge: 13 | image: munge 14 | volumes: 15 | - munge:/var/run/munge/ 16 | mongo: 17 | image: mongo:3 18 | volumes: 19 | - /data/db 20 | command: --smallfiles 21 | systema: 22 | container_name: systema 23 | image: shifter-test 24 | extra_hosts: 25 | - "api:172.17.0.1" 26 | - "registry:172.17.0.1" 27 | ports: 28 | - "2222:22" 29 | volumes: 30 | - /images 31 | - ./test/config/:/config 32 | privileged: true 33 | environment: 34 | - ADDUSER=canon 35 | registry: 36 | image: registry 37 | ports: 38 | - "5000:5000" 39 | volumes: 40 | - registry:/var/lib/registry 41 | -------------------------------------------------------------------------------- /extra/python/shifter-python.spec: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package shifter-skopeo 3 | # 4 | 5 | 6 | Name: shifter-python 7 | Version: 21.12 8 | Release: 1 9 | Summary: Python packages 10 | License: Apache License 2.0 11 | Group: System Environment/Base 12 | #Url: 13 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 14 | Requires: skopeo 15 | BuildRequires: python3-pip 16 | %description 17 | This provides python tools to handle the image convesion for Shifter. 18 | 19 | %prep 20 | 21 | %build 22 | 23 | %install 24 | pip3 install -t $RPM_BUILD_ROOT/opt/shifter-python-%{version} pymongo==3.6 25 | pip3 install -t $RPM_BUILD_ROOT/opt/shifter-python-%{version} sanic==20.12.3 26 | 27 | %post 28 | %postun 29 | 30 | %files 31 | %defattr(-,root,root) 32 | /opt/shifter-python-%{version} 33 | 34 | %changelog 35 | * Fri Dec 3 2021 Shane Canon - 21.12-1 36 | - Initial version 37 | 38 | -------------------------------------------------------------------------------- /wlm_integration/slurm/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | SUBDIRS=test 4 | 5 | AM_CPPFLAGS = -DCONFIG_FILE=\"${sysconfdir}/udiRoot.conf\" -DLIBEXECDIR=\"${libexecdir}/shifter\" $(SLURM_CPPFLAGS) -I$(top_srcdir)/wlm_integration/slurm -I$(top_srcdir)/src -DIS_NATIVE_SLURM=$(SLURM_NATIVE_SLURM) -Wall 6 | 7 | pkglib_LTLIBRARIES = shifter_slurm.la 8 | 9 | PLUGIN_FLAGS = -module -avoid-version --export-dynamic 10 | 11 | SHIFTER_SO_SOURCES = \ 12 | shifterSpank.c \ 13 | shifterSpank.h \ 14 | wrapper.c \ 15 | wrapper.h \ 16 | $(top_srcdir)/src/UdiRootConfig.c \ 17 | $(top_srcdir)/src/utility.c \ 18 | $(top_srcdir)/src/shifter_core.c \ 19 | $(top_srcdir)/src/shifter_mem.c \ 20 | $(top_srcdir)/src/PathList.c \ 21 | $(top_srcdir)/src/ImageData.c \ 22 | $(top_srcdir)/src/VolumeMap.c 23 | 24 | shifter_slurm_la_SOURCES = $(SHIFTER_SO_SOURCES) 25 | shifter_slurm_la_LDFLAGS = $(SO_LDFLAGS) $(PLUGIN_FLAGS) 26 | -------------------------------------------------------------------------------- /extra/CI/imagemanager.json: -------------------------------------------------------------------------------- 1 | { 2 | "WorkerThreads":8, 3 | "DefaultLustreReplication": 1, 4 | "DefaultOstCount": 16, 5 | "DefaultImageLocation": "registry-1.docker.io", 6 | "DefaultImageFormat": "squashfs", 7 | "PullUpdateTimeout": 300, 8 | "ImageExpirationTimeout": "90:00:00:00", 9 | "MongoDBURI":"mongodb://localhost/", 10 | "MongoDB":"Shifter", 11 | "CacheDirectory": "/images/cache/", 12 | "ExpandDirectory": "/images/expand/", 13 | "Locations": { 14 | "registry-1.docker.io": { 15 | "remotetype": "dockerv2", 16 | "authentication": "http" 17 | } 18 | }, 19 | 20 | "Platforms": { 21 | "mycluster": { 22 | "mungeSocketPath": "/var/run/munge/munge.socket.2", 23 | "accesstype": "local", 24 | "usergroupService": "local", 25 | "local": { 26 | "imageDir": "/images" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /extra/cle6/ansible/roles/shifter/vars/cluster.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | shifterImagePath: /lus/peel/shifter/images 3 | shifterRuntimePrefix: /usr 4 | shifterEtcPathByType: 5 | compute: /local/shifter/etcFiles 6 | elogin: /opt/shifter/etcFiles 7 | mom: /non_volatile/local/shifter/etcFiles 8 | default: /invalid 9 | shifterRootfsTypeByType: 10 | compute: ramfs 11 | default: tmpfs 12 | shifterOptUdiImagePathByType: 13 | compute: /lus/peel/shifter/udiImage 14 | default: /invalid 15 | shifterSystem: cluster 16 | shifterPerNodeCachePath: /lus/peel/shifter/backingStore 17 | 18 | shifterBaseSiteFs: 19 | - "/homes:/homes" 20 | - "/lus/peel:/lus/peel" 21 | 22 | shifterSiteFsByType: 23 | compute: 24 | - "/var/opt/cray/dws:/var/opt/cray/dws:rec:slave" 25 | - "/var/opt/cray/alps:/var/opt/cray/alps:rec:slave" 26 | - "/var/run/munge:/var/run/munge" 27 | - "/etc/opt/cray/wlm_detect:/etc/opt/cray/wlm_detect" 28 | # - "/var/spool/slurmd:/var/spool/slurmd" 29 | default: [] 30 | -------------------------------------------------------------------------------- /imagegw/imagemanager.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "WorkerThreads":8, 3 | "DefaultLustreReplication": 1, 4 | "DefaultOstCount": 16, 5 | "DefaultImageLocation": "registry-1.docker.io", 6 | "DefaultImageFormat": "squashfs", 7 | "PullUpdateTimeout": 300, 8 | "ImageExpirationTimeout": "90:00:00:00", 9 | "MongoDBURI":"mongodb://localhost/", 10 | "MongoDB":"Shifter", 11 | "CacheDirectory": "/images/cache/", 12 | "ExpandDirectory": "/images/expand/", 13 | "Locations": { 14 | "registry-1.docker.io": { 15 | "remotetype": "dockerv2", 16 | "authentication": "http" 17 | } 18 | }, 19 | 20 | "Platforms": { 21 | "mycluster": { 22 | "mungeSocketPath": "/var/run/munge/munge.socket.2", 23 | "accesstype": "local", 24 | "admins": ["root"], 25 | "usergroupService": "local", 26 | "local": { 27 | "imageDir": "/images" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dep/cpputest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | CPPUTEST_VERSION=3.8 5 | 6 | baseDir=$(pwd) 7 | mkdir -p cpputest 8 | cd cpputest 9 | 10 | if [[ ! -e "cpputest-${CPPUTEST_VERSION}.tar.gz" && -n "$DEPTAR_DIR" && -e "$DEPTAR_DIR/cpputest-${CPPUTEST_VERSION}.tar.gz" ]]; then 11 | cp "$DEPTAR_DIR/cpputest-${CPPUTEST_VERSION}.tar.gz" . 12 | fi 13 | if [[ ! -e "cpputest-${CPPUTEST_VERSION}.tar.gz" ]]; then 14 | curl -L -k -o "cpputest-${CPPUTEST_VERSION}.tar.gz" "https://github.com/cpputest/cpputest/releases/download/v${CPPUTEST_VERSION}/cpputest-${CPPUTEST_VERSION}.tar.gz" 15 | fi 16 | 17 | mkdir -p cpputest_src 18 | tar xf "cpputest-${CPPUTEST_VERSION}.tar.gz" -C cpputest_src --strip-components=1 19 | cd cpputest_src 20 | # make sure we have the last config.guess available, this helps when building on openpower 21 | curl 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess 22 | ./configure --prefix="${baseDir}/cpputest" 23 | make 24 | make install 25 | cd .. 26 | rm -rf cpputest_src 27 | -------------------------------------------------------------------------------- /dep/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | if BUILD_STATICSSHD 4 | OPT = udiRoot_dep.tar 5 | else 6 | OPT = 7 | endif 8 | 9 | pkglibexec_SCRIPTS = mount 10 | dist_noinst_SCRIPTS = build_mount.sh build_ssh.sh cpputest.sh 11 | check_DATA = cpputest/include/CppUTest/CppUTestConfig.h 12 | noinst_DATA = $(OPT) 13 | 14 | mount: 15 | +$(srcdir)/build_mount.sh > build_mount.log 16 | 17 | cpputest/include/CppUTest/CppUTestConfig.h: 18 | +$(srcdir)/cpputest.sh > build_cpputest.log 19 | 20 | udiRoot_dep.tar: 21 | +$(srcdir)/build_ssh.sh > build_ssh.log 22 | 23 | .PHONY: clean-local-check 24 | 25 | install-data-hook: 26 | mkdir -p $(DESTDIR)/$(libexecdir)/shifter/opt 27 | if [[ -e udiRoot_dep.tar ]]; then tar xf udiRoot_dep.tar -C $(DESTDIR)$(libexecdir)/shifter/opt --strip-components=2 -p --no-same-owner; fi 28 | 29 | clean-local: clean-local-check 30 | clean-local-check: 31 | -rm -rf build build_ssh.log 32 | -rm -rf build_mount build_mount.log 33 | -rm -rf cpputest build_cpputest.log 34 | -rm udiRoot_dep.tar 35 | -rm mount 36 | 37 | -------------------------------------------------------------------------------- /imagegw/Makefile.test: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | 4 | test/config/ssh.key: 5 | ssh-keygen -t rsa -f test/config/ssh -N '' -C 'Test key' 6 | mv test/config/ssh test/config/ssh.key 7 | 8 | 9 | test/config/munge.key: 10 | dd if=/dev/urandom bs=1 count=1024 > test/config/munge.key 11 | 12 | testprep: test/config/ssh.key test/config/munge.key 13 | docker volume inspect imagegw || docker volume create --name imagegw 14 | 15 | startdeps: 16 | docker run -d --name mongot -p 27017:27017 mongo 17 | 18 | starttest: testprep 19 | docker build -t imagegwapi . 20 | docker build -t shifter-test .. 21 | docker-compose up -d 22 | 23 | restartgw: 24 | docker build -t imagegwapi . 25 | docker-compose up -d 26 | 27 | getssh: 28 | $(eval IP=$(shell docker-machine ip $(shell docker-machine active))) 29 | $(eval PORT=$(shell docker-compose ps systema|grep systema|sed 's/.*://'|sed 's/-.*//')) 30 | @echo "To connect, do:" 31 | @echo "ssh -i test/config/ssh.key $(IP) -p $(PORT)" 32 | 33 | cleanup: 34 | docker-compose stop 35 | docker images -f dangling=true -q|xargs docker rmi 36 | -------------------------------------------------------------------------------- /imagegw/test/config/imagemanager.json: -------------------------------------------------------------------------------- 1 | { 2 | "WorkerThreads":8, 3 | "LogLevel":"debug", 4 | "DefaultLustreReplication": 1, 5 | "DefaultOstCount": 16, 6 | "DefaultImageLocation": "index.docker.io", 7 | "DefaultImageFormat": "squashfs", 8 | "PullUpdateTimeout": 300, 9 | "ImageExpirationTimeout": "90:00:00:00", 10 | "MongoDBURI":"mongodb://mongo/", 11 | "MongoDB":"Shifter", 12 | "CacheDirectory": "/images/cache/", 13 | "ExpandDirectory": "/images/expand/", 14 | "Locations": { 15 | "index.docker.io": { 16 | "remotetype": "dockerv2", 17 | "authentication": "http" 18 | } 19 | }, 20 | "Platforms": { 21 | "mycluster": { 22 | "mungeSocketPath": "/var/run/munge/munge.socket.2", 23 | "accesstype": "local", 24 | "admins": ["root"], 25 | "use_external": true, 26 | "usergroupService": "local", 27 | "local": { 28 | "imageDir": "/images" 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/test_udiRoot.conf.in: -------------------------------------------------------------------------------- 1 | nodeContextPrefix= 2 | udiMount=/var/udiMount 3 | loopMount=/var/loopUdiMount 4 | imagePath=/usr/syscom/shifter 5 | modprobePath=/sbin/modprobe 6 | insmodPath=/sbin/insmod 7 | cpPath=/bin/cp 8 | mvPath=/bin/mv 9 | chmodPath=/bin/chmod 10 | ddPath=/bin/dd 11 | rootfsType=@@@ROOTFSTYPE@@@ 12 | allowLocalChroot=1 13 | autoLoadKernelModule=1 14 | udiRootPath=@@@PREFIX@@@ 15 | sitePreMountHook=@@@CONFIG_DIR@@@/premount.sh 16 | sitePostMountHook=@@@CONFIG_DIR@@@/postmount.sh 17 | siteFs=/home;/mnt 18 | optUdiImage=@@@PREFIX@@@/deps/udiImage 19 | etcPath=@@@PREFIX@@@/etc_files 20 | kmodBasePath=@@@PREFIX@@@/kmod 21 | kmodCacheFile=/tmp/udiRootLoadedModules.txt 22 | batchType=slurm 23 | imageGateway=http://localhost:5000 24 | system=testSystem 25 | perNodeCachePath=/tmp 26 | perNodeCacheAllowedFsType=xfs 27 | perNodeCacheSizeLimit=100G 28 | mkfsXfsPath=/sbin/mkfs.xfs 29 | siteEnv=SHIFTER_RUNTIME=1 \ 30 | TEST_ENV=yes 31 | siteEnvAppend=PATH=/opt/udiImage/bin\ 32 | MANPATH=/opt/udiImage/share/man 33 | siteEnvPrepend=PKG_CONFIG_PATH=/this/is/fake 34 | -------------------------------------------------------------------------------- /src/test/chroot3/etc/group: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | bin:x:1: 3 | daemon:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mem:x:8: 10 | kmem:x:9: 11 | wheel:x:10: 12 | cdrom:x:11: 13 | mail:x:12:postfix 14 | man:x:15: 15 | dialout:x:18: 16 | floppy:x:19: 17 | games:x:20: 18 | tape:x:30: 19 | video:x:39: 20 | ftp:x:50: 21 | lock:x:54: 22 | audio:x:63: 23 | nobody:x:99: 24 | users:x:100: 25 | ssh_keys:x:999: 26 | systemd-journal:x:190: 27 | dbus:x:81: 28 | polkitd:x:998: 29 | unbound:x:997: 30 | utmp:x:22: 31 | colord:x:996: 32 | usbmuxd:x:113: 33 | cgred:x:995: 34 | avahi:x:70: 35 | avahi-autoipd:x:170: 36 | saslauth:x:76: 37 | libstoragemgmt:x:994: 38 | kvm:x:36:qemu 39 | qemu:x:107: 40 | rpc:x:32: 41 | rtkit:x:172: 42 | radvd:x:75: 43 | ntp:x:38: 44 | dip:x:40: 45 | chrony:x:993: 46 | abrt:x:173: 47 | pulse-access:x:992: 48 | pulse:x:171: 49 | rpcuser:x:29: 50 | nfsnobody:x:65534: 51 | gdm:x:42: 52 | gnome-initial-setup:x:991: 53 | stapusr:x:156: 54 | stapsys:x:157: 55 | stapdev:x:158: 56 | slocate:x:21: 57 | postdrop:x:90: 58 | postfix:x:89: 59 | sshd:x:74: 60 | tcpdump:x:72: 61 | docker:x:990: 62 | tss:x:59: 63 | dockerroot:x:989: 64 | vboxsf:x:988: 65 | -------------------------------------------------------------------------------- /src/test/etc/group: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | bin:x:1: 3 | daemon:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mem:x:8: 10 | kmem:x:9: 11 | wheel:x:10:dmj 12 | cdrom:x:11: 13 | mail:x:12:postfix 14 | man:x:15: 15 | dialout:x:18: 16 | floppy:x:19: 17 | games:x:20: 18 | tape:x:30: 19 | video:x:39: 20 | ftp:x:50: 21 | lock:x:54: 22 | audio:x:63: 23 | nobody:x:99: 24 | users:x:100: 25 | ssh_keys:x:999: 26 | systemd-journal:x:190: 27 | dbus:x:81: 28 | polkitd:x:998: 29 | unbound:x:997: 30 | utmp:x:22: 31 | colord:x:996: 32 | usbmuxd:x:113: 33 | cgred:x:995: 34 | avahi:x:70: 35 | avahi-autoipd:x:170: 36 | saslauth:x:76: 37 | libstoragemgmt:x:994: 38 | kvm:x:36:qemu 39 | qemu:x:107: 40 | rpc:x:32: 41 | rtkit:x:172: 42 | radvd:x:75: 43 | ntp:x:38: 44 | dip:x:40: 45 | chrony:x:993: 46 | abrt:x:173: 47 | pulse-access:x:992: 48 | pulse:x:171: 49 | rpcuser:x:29: 50 | nfsnobody:x:65534: 51 | gdm:x:42: 52 | gnome-initial-setup:x:991: 53 | stapusr:x:156: 54 | stapsys:x:157: 55 | stapdev:x:158: 56 | slocate:x:21: 57 | postdrop:x:90: 58 | postfix:x:89: 59 | sshd:x:74: 60 | tcpdump:x:72: 61 | dmj:x:1000:dmj 62 | docker:x:990:dmj 63 | tss:x:59: 64 | dockerroot:x:989: 65 | vboxsf:x:988: 66 | -------------------------------------------------------------------------------- /src/test/chroot1/etc/group: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | bin:x:1: 3 | daemon:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mem:x:8: 10 | kmem:x:9: 11 | wheel:x:10:dmj 12 | cdrom:x:11: 13 | mail:x:12:postfix 14 | man:x:15: 15 | dialout:x:18: 16 | floppy:x:19: 17 | games:x:20: 18 | tape:x:30: 19 | video:x:39: 20 | ftp:x:50: 21 | lock:x:54: 22 | audio:x:63: 23 | nobody:x:99: 24 | users:x:100: 25 | ssh_keys:x:999: 26 | systemd-journal:x:190: 27 | dbus:x:81: 28 | polkitd:x:998: 29 | unbound:x:997: 30 | utmp:x:22: 31 | colord:x:996: 32 | usbmuxd:x:113: 33 | cgred:x:995: 34 | avahi:x:70: 35 | avahi-autoipd:x:170: 36 | saslauth:x:76: 37 | libstoragemgmt:x:994: 38 | kvm:x:36:qemu 39 | qemu:x:107: 40 | rpc:x:32: 41 | rtkit:x:172: 42 | radvd:x:75: 43 | ntp:x:38: 44 | dip:x:40: 45 | chrony:x:993: 46 | abrt:x:173: 47 | pulse-access:x:992: 48 | pulse:x:171: 49 | rpcuser:x:29: 50 | nfsnobody:x:65534: 51 | gdm:x:42: 52 | gnome-initial-setup:x:991: 53 | stapusr:x:156: 54 | stapsys:x:157: 55 | stapdev:x:158: 56 | slocate:x:21: 57 | postdrop:x:90: 58 | postfix:x:89: 59 | sshd:x:74: 60 | tcpdump:x:72: 61 | dmj:x:1000:dmj 62 | docker:x:990:dmj 63 | tss:x:59: 64 | dockerroot:x:989: 65 | vboxsf:x:988: 66 | -------------------------------------------------------------------------------- /src/test/chroot2/etc/group: -------------------------------------------------------------------------------- 1 | root:x:0:dmj 2 | bin:x:1: 3 | daemon:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mem:x:8: 10 | kmem:x:9: 11 | wheel:x:10:dmj 12 | cdrom:x:11: 13 | mail:x:12:postfix 14 | man:x:15: 15 | dialout:x:18: 16 | floppy:x:19: 17 | games:x:20: 18 | tape:x:30: 19 | video:x:39: 20 | ftp:x:50: 21 | lock:x:54: 22 | audio:x:63: 23 | nobody:x:99: 24 | users:x:100: 25 | ssh_keys:x:999: 26 | systemd-journal:x:190: 27 | dbus:x:81: 28 | polkitd:x:998: 29 | unbound:x:997: 30 | utmp:x:22: 31 | colord:x:996: 32 | usbmuxd:x:113: 33 | cgred:x:995: 34 | avahi:x:70: 35 | avahi-autoipd:x:170: 36 | saslauth:x:76: 37 | libstoragemgmt:x:994: 38 | kvm:x:36:qemu 39 | qemu:x:107: 40 | rpc:x:32: 41 | rtkit:x:172: 42 | radvd:x:75: 43 | ntp:x:38: 44 | dip:x:40: 45 | chrony:x:993: 46 | abrt:x:173: 47 | pulse-access:x:992: 48 | pulse:x:171: 49 | rpcuser:x:29: 50 | nfsnobody:x:65534: 51 | gdm:x:42: 52 | gnome-initial-setup:x:991: 53 | stapusr:x:156: 54 | stapsys:x:157: 55 | stapdev:x:158: 56 | slocate:x:21: 57 | postdrop:x:90: 58 | postfix:x:89: 59 | sshd:x:74: 60 | tcpdump:x:72: 61 | dmj:x:1000:dmj 62 | docker:x:990:dmj 63 | tss:x:59: 64 | dockerroot:x:989: 65 | vboxsf:x:988: 66 | -------------------------------------------------------------------------------- /imagegw/test/unmunge: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Mock unmunge command - For testing purposes only 4 | # 5 | T=$(dirname $0) 6 | 7 | IN=$(cat) 8 | MT=$(cat $T/munge.test) 9 | EX=$(cat $T/munge.expired 2>/dev/null) 10 | REP=$(cat $T/munge.replay 2>/dev/null) 11 | 12 | if [ "$IN" == "$MT" ] ;then 13 | ST="Success (0)" 14 | RT=0 15 | # Mimic unmunging the same thing twice 16 | cat $T/munge.test > $T/munge.replay 17 | echo "" > $T/munge.test 18 | elif [ "$IN" == "$EX" ] ;then 19 | ST="Expired credential (15))" 20 | RT=15 21 | elif [ "$IN" == "$REP" ] ;then 22 | ST="Replayed credential (17)" 23 | RT=17 24 | else 25 | echo "unmunge: Error: Failed to match armor prefix" 26 | exit 8 27 | fi 28 | 29 | DS=$(TZ=GMT date +"%Y-%m-%d %H:%M:%S %z (%s)") 30 | 31 | cat << EOF 32 | STATUS: $ST 33 | ENCODE_HOST: 4175821389c5 (172.17.1.59) 34 | ENCODE_TIME: 2015-10-15 14:56:43 +0000 (1444921003) 35 | DECODE_TIME: $DS 36 | TTL: 300 37 | CIPHER: aes128 (4) 38 | MAC: sha1 (3) 39 | ZIP: none (0) 40 | UID: root (0) 41 | GID: root (0) 42 | LENGTH: 0 43 | 44 | test 45 | EOF 46 | 47 | exit $RT 48 | -------------------------------------------------------------------------------- /doc/skopeo.rst: -------------------------------------------------------------------------------- 1 | External Mode 2 | ============= 3 | 4 | Since the beginning Shifter has used a native python code to pull and unpack 5 | Docker images. This has some drawbacks such as keeping up to date with changes 6 | in the specs and performance issues unpacking certain large images. External 7 | mode allows Shifter to use standard external tools from the Open Container community 8 | to perform these actions. 9 | 10 | Dependencies 11 | ------------ 12 | 13 | To use external mode you need three external tools: Skopeo, Umoci, and oci-image-tool. 14 | 15 | These can be obtained from: 16 | 17 | - https://github.com/containers/skopeo 18 | - https://github.com/openSUSE/umoci 19 | - https://github.com/opencontainers/image-tools 20 | 21 | Some distributions have packages for some of these tools. The tools 22 | should be installed and available on the PATH when the Image Gateway 23 | is started. 24 | 25 | 26 | Configuration 27 | ------------- 28 | 29 | To configure the gateway to use external mode, simply set `use_external` 30 | to true in the appropriate platform section of the imagemanager.json 31 | file. 32 | 33 | For example: 34 | 35 | ~~~~ 36 | ... 37 | "Platforms": { 38 | "mycluster": { 39 | "admins": ["root"], 40 | "use_external": true 41 | } 42 | } 43 | ... 44 | ~~~~ 45 | 46 | -------------------------------------------------------------------------------- /imagegw/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -z $LOG_LEVEL ] ; then 3 | LOG_LEVEL=INFO 4 | fi 5 | if [ -e "/config/imagemanager.json" ] ; then 6 | echo "Copying configuration from /config" 7 | cp /config/imagemanager.json . 8 | else 9 | echo "Use the volume mount to pass a configuration" 10 | echo "into the container (e.g. -v `pwd`/myconfig:/config)" 11 | fi 12 | 13 | for service in $@ ; do 14 | echo "service: $service" 15 | if [ "$service" == "api" ] ; then 16 | python ./shifter_imagegw/api.py 17 | elif [ $(echo $service|grep -c "munge:") -gt 0 ] ; then 18 | socket=$(echo $service|awk -F: '{print $2}') 19 | key=$(echo $service|awk -F: '{print $3}') 20 | cp /config/$key.key /etc/munge/$socket.key 21 | chown munge /etc/munge/$socket.key 22 | chmod 600 /etc/munge/$socket.key 23 | runuser -u munge -- /usr/sbin/munged -S /var/run/munge/${socket}.socket --key-file=/etc/munge/$socket.key --force -F & 24 | elif [ "$service" == "munge" ] ; then 25 | cp /config/munge.key /etc/munge/munge.key 26 | chown munge /etc/munge/munge.key 27 | chmod 600 /etc/munge/munge.key 28 | runuser -u munge -- /usr/sbin/munged --key-file=/etc/munge/munge.key --force -F 29 | else 30 | echo "$service not recognized" 31 | fi 32 | done 33 | 34 | wait 35 | 36 | if [ $# -eq 0 ] ; then 37 | bash 38 | fi 39 | -------------------------------------------------------------------------------- /src/shiftrun.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | @@@INCLUDE shifterLibCore.sh@@@ 4 | @@@INCLUDE shifterLibFancyShell.sh@@@ 5 | 6 | parseConfiguration 7 | [[ -z "$batchType" ]] && die "Unknown batch system type" 8 | if [[ "$batchType" == "nativeSlurm" ]]; then 9 | SRUN=`which srun 2>/dev/null` 10 | else 11 | APRUN=`which aprun 2>/dev/null` 12 | fi 13 | 14 | declare -a args=("$@") 15 | job=0 16 | [[ -n "$PBS_JOBID" ]] && job="$PBS_JOBID" 17 | [[ -n "$SLURM_JOBID" ]] && job="$SLURM_JOBID" 18 | datadir="/var/run/udiRoot_run/$USER/$job" 19 | 20 | [[ "$job" == "0" ]] && die "Couldn't identify job" 21 | 22 | prepareEnvironment "$datadir/env" 23 | if [[ "$batchType" == "nativeSlurm" ]]; then 24 | srunCmd=("$SRUN") 25 | srunCmd=("${srunCmd[@]}" "${args[@]}") 26 | exec "${srunCmd[@]}" 27 | else 28 | export CRAY_ROOTFS="UDI" ## temporary 29 | 30 | aprunCmd=("$APRUN" "-b") 31 | while IFS= read -r -d '' item; do 32 | IFS="=" 33 | set -- $item 34 | unset IFS 35 | varName="$1" 36 | [[ "$varName" = "BASH_FUNC"* ]] && continue 37 | value=$( echo $item | awk -F= '{ $1=""; print $0; }' | sed 's/^ //g' ) 38 | aprunCmd=("${aprunCmd[@]}" "-e" "$varName=\"$value\"") 39 | done < <(env -0) 40 | 41 | aprunCmd=("${aprunCmd[@]}" "${args[@]}") 42 | exec "${aprunCmd[@]}" 43 | fi 44 | -------------------------------------------------------------------------------- /imagegw/imagegwapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Shifter, Copyright (c) 2015, The Regents of the University of California, 5 | through Lawrence Berkeley National Laboratory (subject to receipt of any 6 | required approvals from the U.S. Dept. of Energy). All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 1. Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 3. Neither the name of the University of California, Lawrence Berkeley 16 | National Laboratory, U.S. Dept. of Energy nor the names of its 17 | contributors may be used to endorse or promote products derived from this 18 | software without specific prior written permission.` 19 | 20 | See LICENSE for full text. 21 | """ 22 | 23 | from shifter_imagegw import api 24 | 25 | LISTEN_PORT = 5000 26 | DEBUG_FLAG = False 27 | 28 | if __name__ == "__main__": 29 | api.app.run(debug=DEBUG_FLAG, host='0.0.0.0', port=LISTEN_PORT, threaded=True) 30 | -------------------------------------------------------------------------------- /wlm_integration/cray/udiRoot-nhc-plugin.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ksh 2 | 3 | if [[ -e /opt/cray/nodehealth/default/bin/libplugin.sh ]]; then 4 | . /opt/cray/nodehealth/default/bin/libplugin.sh 5 | fi 6 | 7 | context=/dsl 8 | 9 | ### parse config file 10 | #while read line; do 11 | # if [[ "$line" == "*=" ]]; then continue; fi 12 | # IFS="=" 13 | # set - $line 14 | # key=$1 15 | # value=$2 16 | # if [[ -z $2 ]]; then 17 | # continue; 18 | # fi 19 | # unset IFS 20 | # expr="export $key=\"$value\"" 21 | # eval $expr 22 | # IFS="=" 23 | #done < "$CONFIG_FILE" 24 | #unset IFS 25 | 26 | foundVFSMounts=1 27 | (cat /proc/mounts | awk '{print $2}' | egrep "^/var/udiMount" > /dev/null 2>&1) || foundVFSMounts=0 28 | 29 | foundLoopMount=1 30 | (cat /proc/mounts | awk '{print $2}' | egrep "^/var/loopUdiMount" > /dev/null 2>&1) || foundLoopMount=0 31 | 32 | errMessage="" 33 | if [[ $foundVFSMounts -eq 1 ]]; then 34 | errMessage="$errMessage,UDI/VFS mounts remain" 35 | fi 36 | if [[ $foundLoopMount -eq 1 ]]; then 37 | errMessage="$errMessage,loopback mount remains" 38 | fi 39 | if [[ $kmodCacheExists -eq 1 ]]; then 40 | errMessage="$errMessage,temporary loaded kernel module cache file exists ($kmodCache)" 41 | fi 42 | 43 | if [[ -n "$errMessage" ]]; then 44 | errMessage="${errMessage:1}" 45 | log_output "$errMessage" 46 | exit 1 47 | fi 48 | exit 0 49 | -------------------------------------------------------------------------------- /wlm_integration/cray/Makefile: -------------------------------------------------------------------------------- 1 | ######## 2 | ## udiRoot: Makefile 3 | ## 4 | ## Author: Douglas Jacobsen 5 | ## Date : 2015/03/23 6 | ## 7 | ######## 8 | 9 | include ../../config.mk 10 | -include ../../config.inc 11 | SED_UPDATE=sed 's|@@@SYSTEM@@@|$(SYSTEM)|g' |\ 12 | sed 's|@@@PREFIX@@@|$(PREFIX)|g' |\ 13 | sed 's|@@@CONFIG_FILE@@@|$(CONFIG_FILE)|g' 14 | 15 | 16 | ALL=udiRoot-nhc-plugin 17 | ifneq ($(IS_NATIVE_SLURM),1) 18 | ALL += udiRoot-epilogue udiRoot-prologue 19 | endif 20 | 21 | all: $(ALL) 22 | 23 | udiRoot-epilogue: udiRoot-epilogue.in 24 | cat $< | $(SED_UPDATE) > $@ 25 | 26 | udiRoot-prologue: udiRoot-prologue.in 27 | cat $< | $(SED_UPDATE) > $@ 28 | 29 | udiRoot-nhc-plugin:udiRoot-nhc-plugin.in 30 | cat $< | $(SED_UPDATE) > $@ 31 | 32 | 33 | install: all 34 | mkdir -p $(DESTDIR)/libexec 35 | $(INSTALL) --owner=root --group=root --mode=555 udiRoot-nhc-plugin $(DESTDIR)/libexec/udiRoot-nhc-plugin 36 | if [ -a udiRoot-prologue ]; then $(INSTALL) --owner=root --group=root --mode=555 udiRoot-prologue $(DESTDIR)/libexec/udiRoot-prologue; fi 37 | if [ -a udiRoot-epilogue ]; then $(INSTALL) --owner=root --group=root --mode=555 udiRoot-epilogue $(DESTDIR)/libexec/udiRoot-epilogue; fi 38 | 39 | clean: 40 | if [ -a udiRoot-prologue ]; then $(RM) udiRoot-prologue; fi 41 | if [ -a udiRoot-epilogue ]; then $(RM) udiRoot-epilogue; fi 42 | if [ -a udiRoot-nhc-plugin ]; then $(RM) udiRoot-nhc-plugin; fi 43 | -------------------------------------------------------------------------------- /imagegw/test/config/nersc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID5zCCAs+gAwIBAgIJALnc0pazOSKPMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD 3 | VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx 4 | DjAMBgNVBAoMBU5FUlNDMQwwCgYDVQQLDANVREkxETAPBgNVBAMMCHJlZ2lzdHJ5 5 | MSEwHwYJKoZIhvcNAQkBFhJkbWphY29ic2VuQGxibC5nb3YwHhcNMTUwNjAxMjI0 6 | NzI1WhcNMTgwMzIxMjI0NzI1WjCBiTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh 7 | bGlmb3JuaWExETAPBgNVBAcMCEJlcmtlbGV5MQ4wDAYDVQQKDAVORVJTQzEMMAoG 8 | A1UECwwDVURJMREwDwYDVQQDDAhyZWdpc3RyeTEhMB8GCSqGSIb3DQEJARYSZG1q 9 | YWNvYnNlbkBsYmwuZ292MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA 10 | uILlAvG00KkA0b1jYcs3Lc5BPEBQY25uIYoLYJVnZ44g6BEAlS8+bGDs/hXPV6Q3 11 | mnePLMBt9O7QRJPDiCvMKrVbQCRZ2WjsrJC+iRv8kGSNY/eQ/A38XhcwLFFazA9h 12 | Yb12w9kTwPCxbg+AE+ct1ry4e/R/IcdFgYYwxyVikUerEl9B7K3GbMOyINgZH3xp 13 | Q3sbva2t/TqpI3+ADq8dh0idbjW3xYbqrSuqI7k4JmR5KtGuyfhMleooLB8crII/ 14 | MoZ7XhQI+4OrFX59q16Rlh0ZXpr1D1eWsC+gfixKe39Z7MU9cwFHtD1HzZQnFKon 15 | Q+mdY23Epj8iAqf3IZZRLQIDAQABo1AwTjAdBgNVHQ4EFgQUzPit2E9DM/SYNHpW 16 | gsiBCGFStMcwHwYDVR0jBBgwFoAUzPit2E9DM/SYNHpWgsiBCGFStMcwDAYDVR0T 17 | BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAFavA+g+5iVxaR7OGESnTCxgKunm0 18 | Fumg7uhfFEISKPOZG/HSi/3ZIHTLITiOBjxhFqtexjBiopIGQDY4ADSrjuMa85tG 19 | S6MB2th6htXlmN88lIyd8jPeZ0SNexRVXBCMjD5HiJxlNjNrmccL09ZyMR0UeIkr 20 | mfGdeH7KXJ2eDvpXqYDmlii+znOPt439JLBvKASwhYTSsZYMxNU/TY3CpnFv92q7 21 | zcmTacv6e9ZCKI2nPl7IQODg18dxpSaztSuQ4lpB97J5Pu4rBmzVDmLySTPTxnuH 22 | dUH66KzlEL5tiFgxi9aQ92SH+aA9SO169KOlz2veRY1bKjv8OK2C6fs0HQ== 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /imagegw/imagemanager.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "imagemanager Configuration Schema", 3 | "type": "object", 4 | "properties": { 5 | "WorkerThreads": { 6 | "description": "Number of worker threads to instantiate", 7 | "type": "integer", 8 | "minimum": 1 9 | }, 10 | "DefaultLustreReplication": { 11 | "description": "number of copies of an image to generate", 12 | "type": "integer", 13 | "minimum": 1 14 | }, 15 | "DefaultOstCount": { 16 | "description": "number of OSTs to strip images across (if lustre)", 17 | "type": "integer", 18 | "minimum": 1 19 | }, 20 | "DefaultImageRemote": { 21 | "description": "Default remote location to use if unspecified", 22 | "type": "string" 23 | }, 24 | "DefaultImageFormat": { 25 | "description": "Default image format", 26 | "type": "string" 27 | }, 28 | "PullUpdateTime": { 29 | "description": "number of seconds an image is assumed up-to-date after pull", 30 | "type": "integer", 31 | "minimum": 1 32 | }, 33 | "ImageExpirationTimeout": { 34 | "description": "time descriptor detailing how long until an image will expire after lookup or pull", 35 | "type": "string" 36 | } 37 | }, 38 | "required": [ 39 | "WorkerThreads", "DefaultImageRemote", "DefaultImageFormat", "PullUpdateTime", 40 | ] 41 | } 42 | 43 | -------------------------------------------------------------------------------- /wlm_integration/torque/Makefile: -------------------------------------------------------------------------------- 1 | ######## 2 | ## qsetenv: Makefile 3 | ## 4 | ## Author: Douglas Jacobsen 5 | ## Date : 2014/09/10 6 | ## 7 | ######## 8 | include ../../config.mk 9 | -include ../../config.inc 10 | 11 | ## configuration 12 | CFLAGS=-O2 -Wall 13 | TORQUE_DIR=$(shell qsub --about 2>&1 | awk '{ i=0; while (i++ < NF) { if ($$i == "InstallDir:") { print $$(i+1) } } }' ) 14 | TORQUE_VERSION=$(shell qsub --about 2>&1 | awk '/Version:/{ print $$2}') 15 | CFLAGS+= -DTORQUE_VERSION="\"$(TORQUE_VERSION)\"" 16 | CPPFLAGS=-I$(TORQUE_DIR)/include 17 | LDFLAGS=-L$(TORQUE_DIR)/lib -Wl,-rpath,$(TORQUE_DIR)/lib 18 | 19 | all: qsetenv qgetenv qstatenv qsetenv.8 20 | 21 | qsetenv: qsetenv.c 22 | $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $< -ltorque -o $@ 23 | 24 | qstatenv: qstatenv.c 25 | $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $< -ltorque -o $@ 26 | 27 | qgetenv: qgetenv.c 28 | $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $< -ltorque -o $@ 29 | 30 | qsetenv.8: qsetenv.man8 31 | groff $(@:.8=.man8) > $@ 32 | 33 | install: all 34 | mkdir -p -m 755 $(DESTDIR)/libexec 35 | mkdir -p -m 755 $(DESTDIR)/share/man/man8 36 | $(INSTALL) --owner=root --group=root --mode=555 qstatenv $(DESTDIR)/libexec/qstatenv 37 | $(INSTALL) --owner=root --group=root --mode=555 qsetenv $(DESTDIR)/libexec/qsetenv 38 | $(INSTALL) --owner=root --group=root --mode=555 qgetenv $(DESTDIR)/libexec/qgetenv 39 | $(INSTALL) --owner=root --group=root --mode=444 qsetenv.8 $(DESTDIR)/share/man/man8/qsetenv.8 40 | 41 | 42 | clean: qsetenv qgetenv qstatenv qsetenv.8 43 | for file in $^; do if [[ -e "$$file" ]]; then rm "$$file"; fi; done 44 | -------------------------------------------------------------------------------- /imagegw/shifter_imagegw/__init__.py.in: -------------------------------------------------------------------------------- 1 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 2 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright notice, 10 | # this list of conditions and the following disclaimer in the documentation 11 | # and/or other materials provided with the distribution. 12 | # 3. Neither the name of the University of California, Lawrence Berkeley 13 | # National Laboratory, U.S. Dept. of Energy nor the names of its 14 | # contributors may be used to endorse or promote products derived from this 15 | # software without specific prior written permission.` 16 | # 17 | # See LICENSE for full text. 18 | """Base functions and classes for shifter image management 19 | 20 | shifter_imagegw includes all software required for the importing, managing, 21 | and removing shifter images to and from computational platforms. The files 22 | within are used by either the web RESTful API (recommend run with gunicorn) 23 | or the thread-based workers, which actually perform any needed actions on the 24 | systems. 25 | """ 26 | __all__ = ['api', 'imageworker', 'imagemngr'] 27 | CONFIG_PATH = '@SHIFTER_SYSCONFDIR@' 28 | -------------------------------------------------------------------------------- /imagegw/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim as tools 2 | 3 | RUN \ 4 | apt-get -y update && apt-get -y install curl gnupg golang git make go-md2man 5 | 6 | RUN \ 7 | echo 'deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list && \ 8 | curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/Release.key | apt-key add - && \ 9 | apt-get -y update && \ 10 | apt-get -y install umoci 11 | 12 | RUN \ 13 | go get -d github.com/opencontainers/image-tools/cmd/oci-image-tool && \ 14 | cd ~/go/src/github.com/opencontainers/image-tools/ && \ 15 | make && make install 16 | 17 | # Need newer version of skopeo then what is available from kubic 18 | FROM debian:sid as skopeo 19 | RUN apt-get -y update && apt-get -y install skopeo 20 | 21 | 22 | FROM python:3.8-slim 23 | 24 | RUN apt-get -y update && apt-get -y install squashfs-tools munge libassuan0 libgpgme11 ibdevmapper1.02.1 25 | 26 | RUN mkdir /var/run/munge && chown munge /var/run/munge 27 | 28 | COPY --from=tools /usr/bin/umoci /usr/bin/oci-image-tool /usr/bin/ 29 | COPY --from=skopeo /usr/bin/skopeo /usr/bin/ 30 | COPY --from=skopeo /etc/containers/ /etc/containers/ 31 | 32 | WORKDIR /usr/src/app 33 | 34 | ADD requirements.txt /usr/src/app/ 35 | 36 | RUN pip install --no-cache-dir -r requirements.txt 37 | 38 | COPY . /usr/src/app 39 | 40 | RUN echo "CONFIG_PATH='/config'" >> /usr/src/app/shifter_imagegw/__init__.py 41 | 42 | ENV PYTHONPATH=/usr/src/app/ 43 | 44 | ENTRYPOINT [ "./entrypoint.sh" ] 45 | CMD [ ] 46 | 47 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. shifter documentation master file, created by 2 | sphinx-quickstart on Sun May 1 23:12:17 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | shifter - Environment Containers for HPC 7 | ======================================== 8 | 9 | shifter is a purpose-built tool for adapting concepts from Linux containers to 10 | extreme scale High Performance Computing resources. It allows a user to create 11 | their own software environment, typically with Docker, then run it at a 12 | supercomputing facility. 13 | 14 | The core goal of shifter is to increase scientific computing productivity. 15 | This is achieved by: 16 | 17 | 1. Increasing scientist productivity by simplifying software deployment and 18 | management; allow your code to be portable! 19 | 2. Enabling scientists to share HPC software directly using the Docker 20 | framework and Dockerhub community of software. 21 | 3. Encouraging repeatable and reproducible science with more durable 22 | software environments. 23 | 4. Providing software solutions to improve system utilization by optimizing 24 | common bottlenecks in software delivery and I/O in-general. 25 | 5. Empowering the user - deploy your own software environment 26 | 27 | Contents: 28 | 29 | .. toctree:: 30 | :maxdepth: 2 31 | 32 | faq 33 | bestpractices 34 | mpi/mpich_abi 35 | install/centos6 36 | install/cle6 37 | install/manualinstallgpu 38 | wlm/slurm 39 | 40 | 41 | 42 | Indices and tables 43 | ================== 44 | 45 | * :ref:`genindex` 46 | * :ref:`modindex` 47 | * :ref:`search` 48 | 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | ssh.key 3 | ssh.pub 4 | munge.key 5 | test.json 6 | munge.test 7 | munge.expired 8 | munge.replay 9 | tags 10 | *.o 11 | *.lo 12 | *.la 13 | *~ 14 | depcomp 15 | install-sh 16 | libtool.m4 17 | missing 18 | Makefile.in 19 | Makefile 20 | src/unsetupRoot 21 | src/setupRoot 22 | src/shifter 23 | src/shifterimg 24 | *.swp 25 | .cache 26 | *.log 27 | *.deps 28 | *.libs 29 | auxdir/config.guess 30 | auxdir/config.sub 31 | auxdir/ltmain.sh 32 | auxdir/ltoptions.m4 33 | auxdir/ltsugar.m4 34 | auxdir/ltversion.m4 35 | auxdir/lt~obsolete.m4 36 | auxdir/py-compile 37 | aclocal.m4 38 | config.h 39 | config.h.in 40 | config.status 41 | configure 42 | libtool 43 | stamp-h1 44 | autom4te.cache/ 45 | test_ImageData 46 | test_MountList 47 | test_UdiRootConfig 48 | test_VolumeMap 49 | test_shifter 50 | test_shifter_core 51 | test_shifter_core_AsRoot 52 | test_shifter_core_AsRootDangerous 53 | test_utility 54 | *.gcno 55 | *.gcda 56 | *.trs 57 | imagegw/shifter_imagegw/__init__.py 58 | udiRoot.conf.example 59 | shifter*.tar.*z* 60 | dep/build/ 61 | dep/build_mount/ 62 | dep/cpputest/ 63 | dep/mount 64 | dep/udiRoot_dep.tar 65 | etc_files/group 66 | etc_files/passwd 67 | extra/modules.tar 68 | extra/shifter_slurm_dws_support 69 | extra/systemd/shifter_imagegw_worker@.service 70 | src/test/test_udiRoot.conf 71 | wlm_integration/slurm/test/test_udiRoot.conf 72 | wlm_integration/slurm/test/test_shifterSpank_config 73 | wlm_integration/slurm/test/test_shifterSpank_prolog 74 | wlm_integration/slurm/test/test_shifterSpank_cgroup 75 | wlm_integration/slurm/test/test_shifterSpank_util 76 | tokens.cfg 77 | imagegw/private 78 | *.bak 79 | .coverage 80 | rpms 81 | doc/html 82 | local/ 83 | 84 | -------------------------------------------------------------------------------- /extra/shifter_cray_mpich.spec.in: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package shifter_cray_mpich 3 | # 4 | # Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. 5 | # 6 | # All modifications and additions to the file contributed by third parties 7 | # remain the property of their copyright owners, unless otherwise agreed 8 | # upon. The license for this file, and modifications and additions to the 9 | # file, is the same license as for the pristine package itself (unless the 10 | # license for the pristine package is not an Open Source License, in which 11 | # case the license is the MIT License). An "Open Source License" is a 12 | # license that conforms to the Open Source Definition (Version 1.9) 13 | # published by the Open Source Initiative. 14 | 15 | # Please submit bugfixes or comments via http://bugs.opensuse.org/ 16 | # 17 | 18 | %define cray_mpich_version {{CRAY_MPICH_VERSION}} 19 | 20 | Name: shifter_cray_mpich_%{cray_mpich_version} 21 | Version: %{cray_mpich_version} 22 | Release: 1 23 | Summary: cray mpich Binaries relocated for shifter's use 24 | Source: shifter-cray-mpich-%{version}.tar.gz 25 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 26 | License: Proprietary 27 | AutoReq: 0 28 | AutoProv: 0 29 | 30 | %description 31 | 32 | %prep 33 | %setup -q -n mpich-%{version} 34 | 35 | %build 36 | 37 | %install 38 | mkdir -p "$RPM_BUILD_ROOT/usr/lib/shifter/opt/mpich-%{cray_mpich_version}" 39 | mv * "$RPM_BUILD_ROOT/usr/lib/shifter/opt/mpich-%{cray_mpich_version}/" 40 | 41 | %post 42 | %postun 43 | 44 | %files 45 | %dir /usr/lib/shifter/opt/mpich-%{cray_mpich_version} 46 | /usr/lib/shifter/opt/mpich-%{cray_mpich_version}/* 47 | 48 | %changelog 49 | 50 | -------------------------------------------------------------------------------- /extra/cle6/ansible/roles/shifter/tasks/main.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - include_vars: "cluster.yaml" 3 | 4 | ## determine nodetype 5 | - set_fact: 6 | nodetype: default 7 | - set_fact: 8 | nodetype: compute 9 | when: ansible_local.cray_system.platform == "compute" 10 | - set_fact: 11 | nodetype: login 12 | when: (ansible_local.cray_system.hostid in cray_login.settings.login_nodes.data.members) 13 | - set_fact: 14 | nodetype: elogin 15 | when: (ansible_local.cray_system_elogin is defined) 16 | 17 | - set_fact: 18 | _shifterBaseSiteFs: "{{ shifterBaseSiteFs|default([]) }}" 19 | _shifterTypeSiteFs: "{{ shifterSiteFsByType[nodetype]|default(shifterSiteFsByType['default']) }}" 20 | - set_fact: 21 | shifterAllSiteFs: >- 22 | {%- set _l = _shifterBaseSiteFs %} 23 | {%- set _ = _l.extend(_shifterTypeSiteFs) %} 24 | {{- _l -}} 25 | 26 | - set_fact: 27 | shifterEtcPath: "{{ shifterEtcPathByType[nodetype]|default(shifterEtcPathByType['default']) }}" 28 | shifterRootfsType: "{{ shifterRootfsTypeByType[nodetype]|default(shifterRootfsTypeByType['default']) }}" 29 | shifterOptUdiImagePath: "{{ shifterOptUdiImagePathByType[nodetype]|default(shifterOptUdiImagePathByType['default']) }}" 30 | 31 | - file: path=/etc/shifter state=directory owner=root group=root mode=0755 32 | 33 | - template: src="udiRoot.conf.j2" dest="/etc/shifter/udiRoot.conf" owner=root group=root mode=0644 34 | - copy: src="{{item}}" dest="/etc/shifter/{{item}}" owner=root group=root mode=0755 35 | with_items: 36 | - premount.sh 37 | - postmount.sh 38 | 39 | - command: depmod -a 40 | - modprobe: name="{{item}}" state=present 41 | with_items: 42 | - ext4 43 | - xfs 44 | ignore_errors: True 45 | -------------------------------------------------------------------------------- /extra/shifter_cle6_kmod_deps.spec.cray: -------------------------------------------------------------------------------- 1 | # 2 | # spec file for package shifter_cle6_kmod_deps 3 | # 4 | # Copyright (c) 2016 Regents of the University of California 5 | # 6 | # 7 | 8 | Name: shifter_cle6_kmod_deps-%(uname -r) 9 | Version: 1.0 10 | Release: 3 11 | License: GPL 12 | BuildRequires: kernel-source kernel-syms 13 | BuildRoot: %{_tmppath}/%{name}-%{version}-build 14 | Summary: kernel mod deps for cle6 15 | 16 | %description 17 | xfs, ext4 and deps 18 | 19 | %prep 20 | 21 | %build 22 | cd /usr/src/linux 23 | if [ -e "arch/x86/configs/cray_ari_c_defconfig" ]; then 24 | # assuming we are on a chroot environment 25 | cp arch/x86/configs/cray_ari_c_defconfig .config 26 | else 27 | # assuming we are on a compute node 28 | cp /proc/config.gz ./ 29 | gunzip config.gz 30 | mv config .config 31 | fi 32 | make oldconfig 33 | make modules_prepare 34 | make M=fs/xfs CONFIG_XFS_FS=m 35 | make M=lib CONFIG_LIBCRC32C=m 36 | make M=fs/ext4 CONFIG_EXT4_FS=m 37 | make M=fs/jbd2 CONFIG_JBD2=m 38 | 39 | %install 40 | cd /usr/src/linux 41 | make M=fs/xfs CONFIG_XFS_FS=m modules_install INSTALL_MOD_PATH=%{buildroot} 42 | make M=lib CONFIG_LIBCRC32C=m modules_install INSTALL_MOD_PATH=%{buildroot} 43 | make M=fs/ext4 CONFIG_EXT4_FS=m modules_install INSTALL_MOD_PATH=%{buildroot} 44 | make M=fs/jbd2 CONFIG_JBD2=m modules_install INSTALL_MOD_PATH=%{buildroot} 45 | 46 | %post 47 | depmod -a 48 | 49 | %postun 50 | depmod -a 51 | 52 | %files 53 | %defattr(-,root,root) 54 | /lib/* 55 | 56 | %changelog 57 | * Mon Aug 08 2016 Miguel Gila 1.0-3 58 | - Added if case to support building on chroot environment 59 | * Wed Jul 20 2016 Miguel Gila 1.0-2 60 | - Fixed Kernel config file location 61 | -------------------------------------------------------------------------------- /extra/build_cray_kernel_modules.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | BUILDDIR=`pwd` 4 | KVER=$( uname -r | sed 's|\(.*\)-cray.*|\1|g') 5 | NETWORK=${1:-gem} 6 | NODETYPE=${2:-c} 7 | ARCH=${3:-x86} 8 | 9 | KDIR=/usr/src/linux-$KVER 10 | if [ ! -e "$KDIR" ]; then 11 | echo "Cannot find kernel sources: $KDIR" 1>&2 12 | exit 1 13 | fi 14 | CONFIG_FILE=$KDIR/arch/$ARCH/configs/cray_${NETWORK}_${NODETYPE}_defconfig 15 | if [ ! -e "$CONFIG_FILE" ]; then 16 | echo "Cannot find a configuration file for the specified setup: $CONFIG_FILE" 1>&2 17 | exit 1 18 | fi 19 | 20 | BDIR=$( mktemp -d ) 21 | FSTYPE=$( df -TP $BDIR | tail -n +2 | awk '{print $2}' ) 22 | 23 | if [ "x$FSTYPE" == "xgpfs" -o "x$FSTYPE" == "xdvs" -o "x$FSTYPE" == "x" ]; then 24 | echo "Will not build kernel on fs type $FSTYPE" 1>&2 25 | rmdir $BDIR 26 | exit 1 27 | fi 28 | 29 | TGT_CONFIG_FILE=$BDIR/linux-$KVER/.config 30 | cp -rp $KDIR $BDIR 31 | cp $CONFIG_FILE $TGT_CONFIG_FILE 32 | echo "CONFIG_BLK_DEV_LOOP=m" >> $TGT_CONFIG_FILE 33 | echo "CONFIG_EXT4_FS=m" >> $TGT_CONFIG_FILE 34 | echo "CONFIG_CRAMFS=m" >> $TGT_CONFIG_FILE 35 | echo "CONFIG_SQUASHFS=m" >> $TGT_CONFIG_FILE 36 | echo "CONFIG_JBD2=m" >> $TGT_CONFIG_FILE 37 | echo "CONFIG_FS_MBCACHE=m" >> $TGT_CONFIG_FILE 38 | echo "CONFIG_XFS_FS=m" >> $TGT_CONFIG_FILE 39 | echo "CONFIG_XFS_QUOTA=y" >> $TGT_CONFIG_FILE 40 | echo "CONFIG_XFS_DMAPI=m" >> $TGT_CONFIG_FILE 41 | echo "CONFIG_XFS_POSIX_ACL=y" >> $TGT_CONFIG_FILE 42 | echo "CONFIG_XFS_RT=y" >> $TGT_CONFIG_FILE 43 | 44 | cd $BDIR/linux-$KVER 45 | yes "" | make oldconfig ## reconfigure kernel accepting defaults 46 | make modules 47 | 48 | find . -name \*.ko -type f -print0 | tar -cf $BUILDDIR/modules.tar --null -T - 49 | cd $BUILDDIR 50 | 51 | rm -rf $BDIR/linux-$KVER 52 | rmdir $BDIR 53 | -------------------------------------------------------------------------------- /imagegw/test.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "WorkerThreads":2, 3 | "LogLevel":"info", 4 | "DefaultLustreReplication": 1, 5 | "DefaultOstCount": 16, 6 | "DefaultImageLocation": "index.docker.io", 7 | "DefaultImageFormat": "squashfs", 8 | "PullUpdateTimeout": 300, 9 | "ImageExpirationTimeout": "90:00:00:00", 10 | "CacheDirectory": "/tmp/imagegw/", 11 | "ExpandDirectory": "/tmp/imagegw/", 12 | "MongoDBURI":"mongodb://localhost/", 13 | "MongoDB":"ShifterTest", 14 | "Metrics":true, 15 | "Authentication":"mock", 16 | "ImportUsers":"all", 17 | 18 | "Locations": { 19 | "index.docker.io": { 20 | "remotetype": "dockerv2", 21 | "authentication": "http" 22 | }, 23 | "urltest": { 24 | "remotetype": "dockerv2", 25 | "url": "https://index.docker.io/", 26 | "authentication": "http" 27 | } 28 | }, 29 | 30 | "Platforms": { 31 | "systema": { 32 | "mungeSocketPath": "/tmp/systema/munge.socket", 33 | "accesstype": "remote", 34 | "mountCommand": "/bin/mount", 35 | "admins": ["root"], 36 | "host": [ 37 | "localhost" 38 | ], 39 | "ssh": { 40 | "username": "user", 41 | "key": "/tmp/ssh.key", 42 | "imageDir": "/tmp/systema/images" 43 | } 44 | }, 45 | "systemb": { 46 | "mungeSocketPath": "/tmp/systemb/munge.socket", 47 | "accesstype": "local", 48 | "usergroupService": "local", 49 | "admins": "root", 50 | "local": { 51 | "imageDir": "/tmp/systemb/images" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/test_shifterSpank_prolog.cpp: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of the University of California, Lawrence Berkeley 13 | National Laboratory, U.S. Dept. of Energy nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | See LICENSE for full text. 18 | */ 19 | 20 | #include "shifterSpank.h" 21 | 22 | #include 23 | 24 | TEST_GROUP(shifterSpankPrologGroup) { 25 | }; 26 | 27 | TEST(shifterSpankPrologGroup, prologInit) { 28 | shifterSpank_config *config = shifterSpank_init(NULL, 0, NULL, 0); 29 | 30 | int ret = shifterSpank_job_prolog(config); 31 | CHECK(ret == SUCCESS); 32 | 33 | config->imageType = strdup("local"); 34 | config->image = strdup("/"); 35 | ret = shifterSpank_job_prolog(config); 36 | CHECK(ret == SUCCESS); 37 | } 38 | 39 | int main(int argc, char** argv) { 40 | return CommandLineTestRunner::RunAllTests(argc, argv); 41 | } 42 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/test_shifterSpank_util.cpp: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of the University of California, Lawrence Berkeley 13 | National Laboratory, U.S. Dept. of Energy nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | See LICENSE for full text. 18 | */ 19 | 20 | #include "shifterSpank.h" 21 | 22 | #include 23 | 24 | TEST_GROUP(shifterSpankUtilGroup) { 25 | }; 26 | 27 | extern "C" { 28 | extern int forkAndExecvLogToSlurm(const char *name, const char *args[]); 29 | }; 30 | 31 | TEST(shifterSpankUtilGroup, ForkExecvLog) { 32 | const char *args[] = { 33 | "/usr/bin/echo", 34 | "this is a test", 35 | NULL 36 | }; 37 | int ret = 0; 38 | 39 | ret = forkAndExecvLogToSlurm("echoTest", args); 40 | CHECK(ret == 0); 41 | } 42 | 43 | int main(int argc, char** argv) { 44 | return CommandLineTestRunner::RunAllTests(argc, argv); 45 | } 46 | -------------------------------------------------------------------------------- /wlm_integration/torque/qsetenv.man8: -------------------------------------------------------------------------------- 1 | .TH qsetenv 8 "10 Sep 2014" "LBNL/NERSC" "Administration Commands" 2 | .SH NAME 3 | qsetenv \- set environmental variable in pending job 4 | .SH SYNOPSIS 5 | .B qsetenv 6 | [ 7 | .B -v 8 | ] [ 9 | .B -h 10 | ] 11 | .I pbs_server 12 | .I job_descriptor 13 | .I VarName 14 | .I Value 15 | .SH DESCRIPTION 16 | .B qsetenv 17 | Appends a single environmental variable key=value pair to the list of 18 | environmental variables in a pending job. qsetenv will create the list in the 19 | job record if it does not previously exist. No existing records will be 20 | removed, but only appended. Therefore if a variable has an existing value 21 | the shell within the job should evaluate the appended (qsetenv-set) value 22 | last. To change another user's jobs, administrative access to the scheduler is 23 | required. 24 | .SH OPTIONS 25 | .IP -h,--help 26 | Show help message (and exit 0 without changing any jobs) 27 | .IP -V,--version 28 | Show qsetenv version and linked torque version (and exit 0 without changing any jobs) 29 | .IP pbs_server 30 | PBS/torque server to connect to 31 | .IP job_descriptor 32 | full job identifier (e.g., 12345.hopque02) 33 | .IP VarName 34 | the environment variable name to set 35 | .IP Value 36 | the environment variable value to set 37 | .SH EXAMPLE 38 | .B qsetenv 39 | cvrsvc09-ib 123456.cvrsvc09-ib CHOS sl5carver 40 | .SH "EXIT STATUS" 41 | Upon successful job modification the exit status will be zero. 42 | If help or version options are specified, qsetenv with exit with status zero. 43 | 44 | If qsetenv fails to modify the job (pbs_alterjob(3) fails), an exit status of one is returned. 45 | .SH BUGS 46 | Not fully tested yet. 47 | .SH AUTHOR 48 | Douglas Jacobsen 49 | .SH "SEE ALSO" 50 | .BR qsub (1B), 51 | .BR qalter (1B), 52 | .BR pbs_alterjob (3B) 53 | -------------------------------------------------------------------------------- /imagegw/test/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Startup script for mock system 4 | # 5 | 6 | # 7 | # Check for config 8 | # 9 | if [ ! -e /config ] ; then 10 | echo "Missing config directory." 11 | echo "Use the volume mount to pass in configuration data." 12 | exit 1 13 | fi 14 | 15 | # Copy shifter config 16 | cp /config/udiRoot.conf /etc/shifter/udiRoot.conf 17 | 18 | # Replace system name if SYSTEM variable is defined 19 | # 20 | if [ ! -z "$SYSTEM" ] ; then 21 | sed -i "s/systema/$SYSTEM/" /etc/shifter/udiRoot.conf 22 | fi 23 | 24 | # Add the key, entrypoint and munge key 25 | if [ -e /config/ssh.pub ] ; then 26 | chmod 700 /root/.ssh 27 | chown -R root /root/.ssh 28 | cp /config/ssh.pub /root/.ssh/authorized_keys 29 | fi 30 | 31 | # Copy and fix up munge key 32 | # 33 | if [ -e /config/munge.key ] ; then 34 | cp /config/munge.key /etc/munge/munge.key 35 | chmod 600 /etc/munge/munge.key 36 | chown munge /etc/munge/munge.key && \ 37 | chown munge /etc/munge/munge.key 38 | /etc/init.d/munge start 39 | fi 40 | 41 | # Copy any pre/post mount scripts 42 | # 43 | [ -e /config/premount.sh ] && cp /config/premount.sh /etc/shifter/premount.sh 44 | [ -e /config/postmount.sh ] && cp /config/postmount.sh /etc/shifter/postmount.sh 45 | 46 | # 47 | # Add a test user if ADDUSER is defined 48 | # 49 | if [ ! -z "$ADDUSER" ] ; then 50 | useradd -m $ADDUSER -s /bin/bash 51 | cp -a /root/.ssh/ /home/$ADDUSER/ 52 | chown $ADDUSER -R /home/$ADDUSER/.ssh/ 53 | fi 54 | 55 | # Do this at the end in case we add a user 56 | mkdir -p /opt/shifter/default/etc_files 57 | getent passwd > /opt/shifter/default/etc_files/passwd 58 | getent group > /opt/shifter/default/etc_files/group 59 | cp /etc/nsswitch.conf /opt/shifter/default/etc_files/ 60 | 61 | # Start up sshd (typically a bad idea) 62 | # 63 | /usr/sbin/sshd -D 64 | -------------------------------------------------------------------------------- /src/test/etc/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/nsswitch.conf 3 | # 4 | # An example Name Service Switch config file. This file should be 5 | # sorted with the most-used services at the beginning. 6 | # 7 | # The entry '[NOTFOUND=return]' means that the search for an 8 | # entry should stop if the search in the previous entry turned 9 | # up nothing. Note that if the search failed due to some other reason 10 | # (like no NIS server responding) then the search continues with the 11 | # next entry. 12 | # 13 | # Valid entries include: 14 | # 15 | # nisplus Use NIS+ (NIS version 3) 16 | # nis Use NIS (NIS version 2), also called YP 17 | # dns Use DNS (Domain Name Service) 18 | # files Use the local files 19 | # db Use the local database (.db) files 20 | # compat Use NIS on compat mode 21 | # hesiod Use Hesiod for user lookups 22 | # [NOTFOUND=return] Stop searching if not found so far 23 | # 24 | 25 | # To use db, put the "db" in front of "files" for entries you want to be 26 | # looked up first in the databases 27 | # 28 | # Example: 29 | #passwd: db files nisplus nis 30 | #shadow: db files nisplus nis 31 | #group: db files nisplus nis 32 | 33 | passwd: files 34 | shadow: files 35 | group: files 36 | #initgroups: files 37 | 38 | #hosts: db files nisplus nis dns 39 | hosts: files dns myhostname 40 | 41 | # Example - obey only what nisplus tells us... 42 | #services: nisplus [NOTFOUND=return] files 43 | #networks: nisplus [NOTFOUND=return] files 44 | #protocols: nisplus [NOTFOUND=return] files 45 | #rpc: nisplus [NOTFOUND=return] files 46 | #ethers: nisplus [NOTFOUND=return] files 47 | #netmasks: nisplus [NOTFOUND=return] files 48 | 49 | bootparams: nisplus [NOTFOUND=return] files 50 | 51 | ethers: files 52 | netmasks: files 53 | networks: files 54 | protocols: files 55 | rpc: files 56 | services: files 57 | 58 | netgroup: files 59 | 60 | publickey: nisplus 61 | 62 | automount: files 63 | aliases: files nisplus 64 | 65 | -------------------------------------------------------------------------------- /src/test/chroot1/etc/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/nsswitch.conf 3 | # 4 | # An example Name Service Switch config file. This file should be 5 | # sorted with the most-used services at the beginning. 6 | # 7 | # The entry '[NOTFOUND=return]' means that the search for an 8 | # entry should stop if the search in the previous entry turned 9 | # up nothing. Note that if the search failed due to some other reason 10 | # (like no NIS server responding) then the search continues with the 11 | # next entry. 12 | # 13 | # Valid entries include: 14 | # 15 | # nisplus Use NIS+ (NIS version 3) 16 | # nis Use NIS (NIS version 2), also called YP 17 | # dns Use DNS (Domain Name Service) 18 | # files Use the local files 19 | # db Use the local database (.db) files 20 | # compat Use NIS on compat mode 21 | # hesiod Use Hesiod for user lookups 22 | # [NOTFOUND=return] Stop searching if not found so far 23 | # 24 | 25 | # To use db, put the "db" in front of "files" for entries you want to be 26 | # looked up first in the databases 27 | # 28 | # Example: 29 | #passwd: db files nisplus nis 30 | #shadow: db files nisplus nis 31 | #group: db files nisplus nis 32 | 33 | passwd: files 34 | shadow: files 35 | group: files 36 | #initgroups: files 37 | 38 | #hosts: db files nisplus nis dns 39 | hosts: files dns myhostname 40 | 41 | # Example - obey only what nisplus tells us... 42 | #services: nisplus [NOTFOUND=return] files 43 | #networks: nisplus [NOTFOUND=return] files 44 | #protocols: nisplus [NOTFOUND=return] files 45 | #rpc: nisplus [NOTFOUND=return] files 46 | #ethers: nisplus [NOTFOUND=return] files 47 | #netmasks: nisplus [NOTFOUND=return] files 48 | 49 | bootparams: nisplus [NOTFOUND=return] files 50 | 51 | ethers: files 52 | netmasks: files 53 | networks: files 54 | protocols: files 55 | rpc: files 56 | services: files 57 | 58 | netgroup: files 59 | 60 | publickey: nisplus 61 | 62 | automount: files 63 | aliases: files nisplus 64 | 65 | -------------------------------------------------------------------------------- /src/test/chroot2/etc/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/nsswitch.conf 3 | # 4 | # An example Name Service Switch config file. This file should be 5 | # sorted with the most-used services at the beginning. 6 | # 7 | # The entry '[NOTFOUND=return]' means that the search for an 8 | # entry should stop if the search in the previous entry turned 9 | # up nothing. Note that if the search failed due to some other reason 10 | # (like no NIS server responding) then the search continues with the 11 | # next entry. 12 | # 13 | # Valid entries include: 14 | # 15 | # nisplus Use NIS+ (NIS version 3) 16 | # nis Use NIS (NIS version 2), also called YP 17 | # dns Use DNS (Domain Name Service) 18 | # files Use the local files 19 | # db Use the local database (.db) files 20 | # compat Use NIS on compat mode 21 | # hesiod Use Hesiod for user lookups 22 | # [NOTFOUND=return] Stop searching if not found so far 23 | # 24 | 25 | # To use db, put the "db" in front of "files" for entries you want to be 26 | # looked up first in the databases 27 | # 28 | # Example: 29 | #passwd: db files nisplus nis 30 | #shadow: db files nisplus nis 31 | #group: db files nisplus nis 32 | 33 | passwd: files 34 | shadow: files 35 | group: files 36 | #initgroups: files 37 | 38 | #hosts: db files nisplus nis dns 39 | hosts: files dns myhostname 40 | 41 | # Example - obey only what nisplus tells us... 42 | #services: nisplus [NOTFOUND=return] files 43 | #networks: nisplus [NOTFOUND=return] files 44 | #protocols: nisplus [NOTFOUND=return] files 45 | #rpc: nisplus [NOTFOUND=return] files 46 | #ethers: nisplus [NOTFOUND=return] files 47 | #netmasks: nisplus [NOTFOUND=return] files 48 | 49 | bootparams: nisplus [NOTFOUND=return] files 50 | 51 | ethers: files 52 | netmasks: files 53 | networks: files 54 | protocols: files 55 | rpc: files 56 | services: files 57 | 58 | netgroup: files 59 | 60 | publickey: nisplus 61 | 62 | automount: files 63 | aliases: files nisplus 64 | 65 | -------------------------------------------------------------------------------- /src/test/chroot3/etc/nsswitch.conf: -------------------------------------------------------------------------------- 1 | # 2 | # /etc/nsswitch.conf 3 | # 4 | # An example Name Service Switch config file. This file should be 5 | # sorted with the most-used services at the beginning. 6 | # 7 | # The entry '[NOTFOUND=return]' means that the search for an 8 | # entry should stop if the search in the previous entry turned 9 | # up nothing. Note that if the search failed due to some other reason 10 | # (like no NIS server responding) then the search continues with the 11 | # next entry. 12 | # 13 | # Valid entries include: 14 | # 15 | # nisplus Use NIS+ (NIS version 3) 16 | # nis Use NIS (NIS version 2), also called YP 17 | # dns Use DNS (Domain Name Service) 18 | # files Use the local files 19 | # db Use the local database (.db) files 20 | # compat Use NIS on compat mode 21 | # hesiod Use Hesiod for user lookups 22 | # [NOTFOUND=return] Stop searching if not found so far 23 | # 24 | 25 | # To use db, put the "db" in front of "files" for entries you want to be 26 | # looked up first in the databases 27 | # 28 | # Example: 29 | #passwd: db files nisplus nis 30 | #shadow: db files nisplus nis 31 | #group: db files nisplus nis 32 | 33 | passwd: files 34 | shadow: files 35 | group: files 36 | #initgroups: files 37 | 38 | #hosts: db files nisplus nis dns 39 | hosts: files dns myhostname 40 | 41 | # Example - obey only what nisplus tells us... 42 | #services: nisplus [NOTFOUND=return] files 43 | #networks: nisplus [NOTFOUND=return] files 44 | #protocols: nisplus [NOTFOUND=return] files 45 | #rpc: nisplus [NOTFOUND=return] files 46 | #ethers: nisplus [NOTFOUND=return] files 47 | #netmasks: nisplus [NOTFOUND=return] files 48 | 49 | bootparams: nisplus [NOTFOUND=return] files 50 | 51 | ethers: files 52 | netmasks: files 53 | networks: files 54 | protocols: files 55 | rpc: files 56 | services: files 57 | 58 | netgroup: files 59 | 60 | publickey: nisplus 61 | 62 | automount: files 63 | aliases: files nisplus 64 | 65 | -------------------------------------------------------------------------------- /contrib/shifter-imagegw_init_d: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Author: 4 | # Miguel Gila 5 | # 6 | # 7 | 8 | # 9 | # shifter-imagegw This starts and stops shifter-imagegw 10 | # 11 | # chkconfig: 2345 11 88 12 | # description: todo 13 | # 14 | # config: /etc/sysconfig/shifter-imagegw 15 | # pidfile: /var/run/shifter-imagegw.pid 16 | # 17 | # 18 | 19 | # Source function library. 20 | . /etc/rc.d/init.d/functions 21 | 22 | PATH=/usr/bin:/sbin:/bin:/usr/sbin 23 | export PATH 24 | 25 | [ -f /etc/sysconfig/shifter-imagegw ] && . /etc/sysconfig/shifter-imagegw 26 | lockfile=${LOCKFILE-/var/lock/subsys/shifter-imagegw} 27 | pidfile=${PIDFILE-/var/run/shifter-imagegw.pid} 28 | command=${PUPPETD-/opt/shifter/default/shifter-imagegw} 29 | RETVAL=0 30 | util='shifter-imagegw' 31 | 32 | start() { 33 | echo -n "Starting ${util}: " 34 | if [ -s ${pidfile} ]; then 35 | RETVAL=1 36 | echo -n "Already running!" && warning 37 | echo 38 | else 39 | nohup ${command} 2>&1 > /var/log/${util}.log & 40 | RETVAL=$? 41 | PID=$! 42 | [ $RETVAL = 0 ] && touch ${lockfile} && success || failure 43 | echo 44 | echo $PID > ${pidfile} 45 | fi 46 | } 47 | 48 | stop() { 49 | echo -n $"Stopping ${util}: " 50 | killproc $pidopts $command 51 | killall /opt/shifter/15.12.0/imagegw_venv/bin/python 52 | RETVAL=$? 53 | echo 54 | [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile} 55 | } 56 | 57 | restart() { 58 | stop 59 | start 60 | } 61 | 62 | rh_status() { 63 | status $pidopts $command 64 | RETVAL=$? 65 | return $RETVAL 66 | } 67 | 68 | rh_status_q() { 69 | rh_status >/dev/null 2>&1 70 | } 71 | 72 | case "$1" in 73 | start) 74 | start 75 | ;; 76 | stop) 77 | stop 78 | ;; 79 | restart) 80 | restart 81 | ;; 82 | status) 83 | rh_status 84 | ;; 85 | *) 86 | echo $"Usage: $0 {start|stop|status|restart}" 87 | exit 1 88 | esac 89 | 90 | exit $RETVAL 91 | -------------------------------------------------------------------------------- /src/test/test_udiRoot.conf.in: -------------------------------------------------------------------------------- 1 | nodeContextPrefix= 2 | udiMount=/var/udiMount 3 | loopMount=/var/loopUdiMount 4 | imagePath=/usr/syscom/shifter 5 | modprobePath=/sbin/modprobe 6 | insmodPath=/sbin/insmod 7 | cpPath=/bin/cp 8 | mvPath=/bin/mv 9 | chmodPath=/bin/chmod 10 | ddPath=/bin/dd 11 | rootfsType=@@@ROOTFSTYPE@@@ 12 | allowLocalChroot=1 13 | udiRootPath=@@@PREFIX@@@ 14 | sitePreMountHook=@@@CONFIG_DIR@@@/premount.sh 15 | sitePostMountHook=@@@CONFIG_DIR@@@/postmount.sh 16 | siteFs=/home;/mnt 17 | optUdiImage=@@@PREFIX@@@/deps/udiImage 18 | etcPath=@@@PREFIX@@@/etc_files 19 | kmodBasePath=@@@PREFIX@@@/kmod 20 | kmodCacheFile=/tmp/udiRootLoadedModules.txt 21 | batchType=slurm 22 | imageGateway=http://localhost:5000 23 | system=testSystem 24 | perNodeCachePath=/tmp 25 | perNodeCacheAllowedFsType=xfs 26 | perNodeCacheSizeLimit=100G 27 | mkfsXfsPath=/usr/sbin/mkfs.xfs 28 | siteEnv=SHIFTER_RUNTIME=1 \ 29 | TEST_ENV=yes 30 | siteEnvAppend=PATH=/opt/udiImage/bin\ 31 | MANPATH=/opt/udiImage/share/man 32 | siteEnvPrepend=PKG_CONFIG_PATH=/this/is/fake 33 | 34 | defaultModules = mpich 35 | 36 | module_mpich_userhook = /path/to/userhook 37 | module_mpich_roothook = /path/to/roothook 38 | module_mpich_siteEnvPrepend = LD_LIBRARY_PATH=/opt/udiImage/mpich/lib64 \ 39 | PATH=/opt/udiImage/mpich/bin 40 | module_mpich_siteEnvAppend = PATH=/opt/udiImage/mpich/sbin 41 | module_mpich_siteEnv = SHIFTER_MODULE_MPICH=1 42 | module_mpich_siteEnvUnset = FAKE_MPI_VARIABLE 43 | module_mpich_siteFs = /mpich/a:/mpicha 44 | module_mpich_copyPath = /path/to/localized/mpich/stuff 45 | module_mpich_conflict = openmpi 46 | 47 | module_openmpi_userhook = /path/to/openmpi_userhook 48 | module_openmpi_siteEnvPrepend = LD_LIBRARY_PATH=/opt/udiImage/openmpi/lib64 \ 49 | PATH=/opt/udiImage/openmpi/bin 50 | module_openmpi_siteEnvAppend = PATH=/opt/udiImage/openmpi/sbin 51 | module_openmpi_siteEnv = SHIFTER_MODULE_OPENMPI=1 52 | module_openmpi_siteEnvUnset = FAKE_MPI_VARIABLE 53 | module_openmpi_conflict = mpich 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shifter - Containers for HPC 2 | 3 | Shifter enables container images for HPC. In a nutshell, Shifter allows an HPC system to efficiently and safely allow end-users 4 | to run a docker image. Shifter consists of a few moving parts 1) a utility that typically runs on the compute node that creates 5 | the run time environment for the application 2) an image gateway service that pulls images from a registry and repacks it in a 6 | format suitable for the HPC system (typically squashfs) 3) and example scripts/plugins to integrate Shifter with various batch 7 | scheduler systems. 8 | 9 | 10 | TravisCI Build Status 11 | 12 | 13 | Coverity Scan Build Status 14 | 15 | 16 | 17 | # Mailing List 18 | 19 | For updates and community support, please subscribe to the email list at https://groups.google.com/forum/#!forum/shifter-hpc. 20 | 21 | # Release Cycle 22 | 23 | Shifter has had two major releases (16.08 and 18.03) and several minor release within those over the past few years. Milestone tags will be labelled like YYYY.MM.vv (i.e. 2015.12.00) where vv is a minor release incremented with each snapshot generated. We plan to release new major versions biannually with point releases as required. 24 | 25 | # Contributing 26 | 27 | If you want to contribute code or documentation, please join our slack chat channel at https://shifter-hpc.slack.com to 28 | coordinate efforts. Code can be presented for inclusion with the shifter project by providing Pull Requests against the 29 | shifter master branch on github from your own forked repo. 30 | 31 | # Change Log 32 | 33 | See NEWS for a history of CHANGES 34 | 35 | # Website 36 | 37 | https://www.nersc.gov/research-and-development/user-defined-images/ 38 | 39 | # Documentation 40 | 41 | https://github.com/NERSC/shifter/tree/master/doc 42 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/test_shifterSpank_config.cpp: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of the University of California, Lawrence Berkeley 13 | National Laboratory, U.S. Dept. of Energy nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | See LICENSE for full text. 18 | */ 19 | 20 | #include "shifterSpank.h" 21 | 22 | #include 23 | 24 | TEST_GROUP(shifterSpankConfigGroup) { 25 | }; 26 | 27 | TEST(shifterSpankConfigGroup, BasicInitTest) { 28 | shifterSpank_config *config = shifterSpank_init(NULL, 0, NULL, 0); 29 | CHECK(config != NULL); 30 | CHECK(config->udiConfig != NULL); 31 | 32 | shifterSpank_config_free(config); 33 | 34 | char *args[] = { 35 | strdup("extern_setup=/usr/bin/echo"), 36 | NULL 37 | }; 38 | config = shifterSpank_init(NULL, 1, args, 0); 39 | CHECK(config != NULL); 40 | CHECK(config->extern_setup != NULL); 41 | CHECK(strcmp(config->extern_setup, "/usr/bin/echo") == 0); 42 | shifterSpank_config_free(config); 43 | 44 | free(args[0]); 45 | 46 | } 47 | 48 | int main(int argc, char** argv) { 49 | return CommandLineTestRunner::RunAllTests(argc, argv); 50 | } 51 | -------------------------------------------------------------------------------- /contrib/shifter-imagegw_build_env: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # 4 | # Author: 5 | # Miguel Gila 6 | # 7 | # 8 | 9 | if [ -z ${ROOT_TREE} ]; then 10 | ROOT_TREE='/opt/shifter/15.12.0/imagegw' 11 | fi 12 | 13 | if [ -z ${PYTHON_VENV} ]; then 14 | PYTHON_VENV='imagegw_venv' 15 | fi 16 | 17 | # CWD should be the local contrib directory 18 | CWD=${PWD} 19 | REQ_FILE="${CWD}/../src/requirements.txt" 20 | DEP_RPM_LIST="mongodb-server mongodb zlib zlib-devel munge munge-devel openssl openssl-devel" 21 | 22 | uname -a |grep Linux 2>&1 >> /dev/null 23 | if [ $? -eq 0 ]; then 24 | # a very ugly way to detect RHEL-compatible 6 OS 25 | cat /etc/redhat-release |grep 6 2>&1 >> /dev/null 26 | if [ $? -eq 0 ]; then 27 | echo "*** Installing dependencies ${DEP_RPM_LIST}" 28 | sudo yum install -y ${DEP_RPM_LIST} 29 | sudo /etc/init.d/mongod start 30 | fi 31 | fi 32 | 33 | echo "*** Installing Python 2.7.9" 34 | cd ${ROOT_TREE} 35 | MYPYTHONPATH=${ROOT_TREE}/python_2.7.9 36 | curl 'https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz' -o Python-2.7.9.tgz 37 | tar xzf Python-2.7.9.tgz 38 | cd Python-2.7.9/ 39 | ./configure --prefix=${MYPYTHONPATH} 40 | make -j4 && make install 41 | echo ">>> Python 2.7.9 build status: $?" 42 | cd .. 43 | find ./Python-2.7.9 -exec rm -rf {} \; 44 | 45 | echo "*** Installing Virtualenv 13.1.2" 46 | cd ${ROOT_TREE} 47 | curl 'https://pypi.python.org/packages/source/v/virtualenv/virtualenv-13.1.2.tar.gz#md5=b989598f068d64b32dead530eb25589a' -o virtualenv-13.1.2.tar.gz 48 | tar xzf virtualenv-13.1.2.tar.gz 49 | virtualenv-13.1.2/virtualenv.py ${PYTHON_VENV} --python=${MYPYTHONPATH}/bin/python2.7 50 | echo ">>> Virtualenv 13.1.2 build status: $?" 51 | 52 | echo "*** Installing python packages using pip on virtual environment ${PYTHON_VENV}" 53 | cd ${ROOT_TREE} 54 | source ${PYTHON_VENV}/bin/activate 55 | #pip install pymongo flask pysocks requests 56 | if [ -e ${REQ_FILE} ] ; then 57 | pip install -r ${REQ_FILE} 58 | echo ">>> pip install status: $?" 59 | else 60 | echo ">>> Cannot find requirements.txt file ${REQ_FILE}." 61 | fi 62 | 63 | echo "*** Done" 64 | -------------------------------------------------------------------------------- /extra/shifter_slurm_dws_support.c: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright notice, 10 | * this list of conditions and the following disclaimer in the documentation 11 | * and/or other materials provided with the distribution. 12 | * 3. Neither the name of the University of California, Lawrence Berkeley 13 | * National Laboratory, U.S. Dept. of Energy nor the names of its 14 | * contributors may be used to endorse or promote products derived from this 15 | * software without specific prior written permission. 16 | * 17 | * See LICENSE for full text. 18 | */ 19 | 20 | #ifndef _GNU_SOURCE 21 | #define _GNU_SOURCE 22 | #endif 23 | #include 24 | #include 25 | 26 | #include "shifter_core.h" 27 | 28 | extern int _shifterCore_bindMount(UdiRootConfig *confg, MountList *mounts, const char *from, const char *to, size_t flags, int overwrite); 29 | 30 | int main(int argc, char **argv) { 31 | UdiRootConfig config; 32 | MountList mounts; 33 | char dwMountPoint[PATH_MAX]; 34 | memset(&config, 0, sizeof(UdiRootConfig)); 35 | memset(&mounts, 0, sizeof(MountList)); 36 | if (parse_MountList(&mounts) != 0) { 37 | /* error */ 38 | } 39 | if (parse_UdiRootConfig(CONFIG_FILE, &config, UDIROOT_VAL_ALL) != 0) { 40 | fprintf(stderr, "FAILED to parse udiRoot configuration.\n"); 41 | exit(1); 42 | } 43 | 44 | snprintf(dwMountPoint, PATH_MAX, "%s/var/opt/cray/dws", config.udiMountPoint); 45 | 46 | unmountTree(&mounts, dwMountPoint); 47 | 48 | _shifterCore_bindMount(&config, &mounts, "/var/opt/cray/dws", dwMountPoint, VOLMAP_FLAG_RECURSIVE, 1); 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/shifter_mem.h: -------------------------------------------------------------------------------- 1 | /** @file shifter_mem.h 2 | * @brief Core include for heap operations 3 | * 4 | * @author Douglas M. Jacobsen 5 | */ 6 | 7 | /* Shifter, Copyright (c) 2017, The Regents of the University of California, 8 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 9 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of the University of California, Lawrence Berkeley 19 | * National Laboratory, U.S. Dept. of Energy nor the names of its 20 | * contributors may be used to endorse or promote products derived from this 21 | * software without specific prior written permission. 22 | * 23 | * See LICENSE for full text. 24 | */ 25 | 26 | #ifndef __SHFTR_MEM_INCLUDE 27 | #define __SHFTR_MEM_INCLUDE 28 | 29 | #ifndef _GNU_SOURCE 30 | #define _GNU_SOURCE 31 | #endif 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | #define _realloc(__p, __sz) \ 38 | shifter_realloc(__p, __sz, __FILE__, __LINE__, __func__) 39 | 40 | #define _malloc(__sz) \ 41 | shifter_malloc(__sz, __FILE__, __LINE__, __func__) 42 | 43 | #define _strdup(__str) \ 44 | shifter_strdup(__str, __FILE__, __LINE__, __func__) 45 | 46 | #define _strndup(__str, __sz) \ 47 | shifter_strndup(__str, __sz, __FILE__, __LINE__, __func__) 48 | 49 | void *shifter_realloc(void *, size_t, const char *, int, const char *); 50 | void *shifter_malloc(size_t, const char *, int, const char *); 51 | char *shifter_strdup(const char *, const char *, int, const char *); 52 | char *shifter_strndup(const char *, size_t, const char *, int, const char *); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/test/test_shifterimg.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file test_shifterimg.cpp 3 | * @brief test harness for functions in shifterimg 4 | * 5 | * @author Douglas M. Jacobsen 6 | */ 7 | 8 | /* Shifter, Copyright (c) 2017, The Regents of the University of California, 9 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 10 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions are met: 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University of California, Lawrence Berkeley 20 | * National Laboratory, U.S. Dept. of Energy nor the names of its 21 | * contributors may be used to endorse or promote products derived from this 22 | * software without specific prior written permission. 23 | * 24 | * See LICENSE for full text. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "shifterimg.h" 32 | 33 | extern "C" { 34 | extern void _add_allowed(enum AclCredential aclType, struct options *config, const char *arg); 35 | } 36 | 37 | TEST_GROUP(ShifterimgTestGroup) { 38 | }; 39 | 40 | TEST(ShifterimgTestGroup, addAllowedTest) { 41 | struct options config; 42 | memset(&config, 0, sizeof(struct options)); 43 | 44 | _add_allowed(USER_ACL, &config, "1,2,3,4"); 45 | CHECK(config.allowed_uids != NULL); 46 | CHECK(config.allowed_gids == NULL); 47 | CHECK(config.allowed_uids_len == 4); 48 | for (size_t i = 0; i < config.allowed_uids_len; i++) { 49 | CHECK(config.allowed_uids[i] == (int)i + 1); 50 | } 51 | free(config.allowed_uids); 52 | } 53 | 54 | int main(int argc, char **argv) { 55 | return CommandLineTestRunner::RunAllTests(argc, argv); 56 | } 57 | -------------------------------------------------------------------------------- /src/test/etc/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | bin:x:1:1:bin:/bin:/sbin/nologin 3 | daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 | adm:x:3:4:adm:/var/adm:/sbin/nologin 5 | lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 | sync:x:5:0:sync:/sbin:/bin/sync 7 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 | halt:x:7:0:halt:/sbin:/sbin/halt 9 | mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 | operator:x:11:0:operator:/root:/sbin/nologin 11 | games:x:12:100:games:/usr/games:/sbin/nologin 12 | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 | nobody:x:99:99:Nobody:/:/sbin/nologin 14 | dbus:x:81:81:System message bus:/:/sbin/nologin 15 | polkitd:x:999:998:User for polkitd:/:/sbin/nologin 16 | unbound:x:998:997:Unbound DNS resolver:/etc/unbound:/sbin/nologin 17 | colord:x:997:996:User for colord:/var/lib/colord:/sbin/nologin 18 | usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin 19 | avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin 20 | avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin 21 | saslauth:x:996:76:"Saslauthd user":/run/saslauthd:/sbin/nologin 22 | libstoragemgmt:x:995:994:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin 23 | qemu:x:107:107:qemu user:/:/sbin/nologin 24 | rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin 25 | rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin 26 | radvd:x:75:75:radvd user:/:/sbin/nologin 27 | ntp:x:38:38::/etc/ntp:/sbin/nologin 28 | chrony:x:994:993::/var/lib/chrony:/sbin/nologin 29 | abrt:x:173:173::/etc/abrt:/sbin/nologin 30 | pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin 31 | rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin 32 | nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin 33 | gdm:x:42:42::/var/lib/gdm:/sbin/nologin 34 | gnome-initial-setup:x:993:991::/run/gnome-initial-setup/:/sbin/nologin 35 | postfix:x:89:89::/var/spool/postfix:/sbin/nologin 36 | sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 37 | tcpdump:x:72:72::/:/sbin/nologin 38 | dmj:x:1000:1000:Doug Jacobsen:/home/dmj:/bin/bash 39 | tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin 40 | dockerroot:x:992:989:Docker User:/var/lib/docker:/sbin/nologin 41 | vboxadd:x:991:1::/var/run/vboxadd:/bin/false 42 | -------------------------------------------------------------------------------- /src/test/chroot1/etc/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | bin:x:1:1:bin:/bin:/sbin/nologin 3 | daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 | adm:x:3:4:adm:/var/adm:/sbin/nologin 5 | lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 | sync:x:5:0:sync:/sbin:/bin/sync 7 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 | halt:x:7:0:halt:/sbin:/sbin/halt 9 | mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 | operator:x:11:0:operator:/root:/sbin/nologin 11 | games:x:12:100:games:/usr/games:/sbin/nologin 12 | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 | nobody:x:99:99:Nobody:/:/sbin/nologin 14 | dbus:x:81:81:System message bus:/:/sbin/nologin 15 | polkitd:x:999:998:User for polkitd:/:/sbin/nologin 16 | unbound:x:998:997:Unbound DNS resolver:/etc/unbound:/sbin/nologin 17 | colord:x:997:996:User for colord:/var/lib/colord:/sbin/nologin 18 | usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin 19 | avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin 20 | avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin 21 | saslauth:x:996:76:"Saslauthd user":/run/saslauthd:/sbin/nologin 22 | libstoragemgmt:x:995:994:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin 23 | qemu:x:107:107:qemu user:/:/sbin/nologin 24 | rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin 25 | rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin 26 | radvd:x:75:75:radvd user:/:/sbin/nologin 27 | ntp:x:38:38::/etc/ntp:/sbin/nologin 28 | chrony:x:994:993::/var/lib/chrony:/sbin/nologin 29 | abrt:x:173:173::/etc/abrt:/sbin/nologin 30 | pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin 31 | rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin 32 | nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin 33 | gdm:x:42:42::/var/lib/gdm:/sbin/nologin 34 | gnome-initial-setup:x:993:991::/run/gnome-initial-setup/:/sbin/nologin 35 | postfix:x:89:89::/var/spool/postfix:/sbin/nologin 36 | sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 37 | tcpdump:x:72:72::/:/sbin/nologin 38 | dmj:x:1000:1000:Doug Jacobsen:/home/dmj:/bin/bash 39 | tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin 40 | dockerroot:x:992:989:Docker User:/var/lib/docker:/sbin/nologin 41 | vboxadd:x:991:1::/var/run/vboxadd:/bin/false 42 | -------------------------------------------------------------------------------- /src/test/chroot2/etc/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | bin:x:1:1:bin:/bin:/sbin/nologin 3 | daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 | adm:x:3:4:adm:/var/adm:/sbin/nologin 5 | lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 | sync:x:5:0:sync:/sbin:/bin/sync 7 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 | halt:x:7:0:halt:/sbin:/sbin/halt 9 | mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 | operator:x:11:0:operator:/root:/sbin/nologin 11 | games:x:12:100:games:/usr/games:/sbin/nologin 12 | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 | nobody:x:99:99:Nobody:/:/sbin/nologin 14 | dbus:x:81:81:System message bus:/:/sbin/nologin 15 | polkitd:x:999:998:User for polkitd:/:/sbin/nologin 16 | unbound:x:998:997:Unbound DNS resolver:/etc/unbound:/sbin/nologin 17 | colord:x:997:996:User for colord:/var/lib/colord:/sbin/nologin 18 | usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin 19 | avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin 20 | avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin 21 | saslauth:x:996:76:"Saslauthd user":/run/saslauthd:/sbin/nologin 22 | libstoragemgmt:x:995:994:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin 23 | qemu:x:107:107:qemu user:/:/sbin/nologin 24 | rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin 25 | rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin 26 | radvd:x:75:75:radvd user:/:/sbin/nologin 27 | ntp:x:38:38::/etc/ntp:/sbin/nologin 28 | chrony:x:994:993::/var/lib/chrony:/sbin/nologin 29 | abrt:x:173:173::/etc/abrt:/sbin/nologin 30 | pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin 31 | rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin 32 | nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin 33 | gdm:x:42:42::/var/lib/gdm:/sbin/nologin 34 | gnome-initial-setup:x:993:991::/run/gnome-initial-setup/:/sbin/nologin 35 | postfix:x:89:89::/var/spool/postfix:/sbin/nologin 36 | sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 37 | tcpdump:x:72:72::/:/sbin/nologin 38 | dmj:x:1000:1000:Doug Jacobsen:/home/dmj:/bin/bash 39 | tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin 40 | dockerroot:x:992:989:Docker User:/var/lib/docker:/sbin/nologin 41 | vboxadd:x:991:1::/var/run/vboxadd:/bin/false 42 | -------------------------------------------------------------------------------- /src/test/chroot3/etc/passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | bin:x:1:1:bin:/bin:/sbin/nologin 3 | daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 | adm:x:3:4:adm:/var/adm:/sbin/nologin 5 | lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 | sync:x:5:0:sync:/sbin:/bin/sync 7 | shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 | halt:x:7:0:halt:/sbin:/sbin/halt 9 | mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 | operator:x:11:0:operator:/root:/sbin/nologin 11 | games:x:12:100:games:/usr/games:/sbin/nologin 12 | ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 13 | nobody:x:99:99:Nobody:/:/sbin/nologin 14 | dbus:x:81:81:System message bus:/:/sbin/nologin 15 | polkitd:x:999:998:User for polkitd:/:/sbin/nologin 16 | unbound:x:998:997:Unbound DNS resolver:/etc/unbound:/sbin/nologin 17 | colord:x:997:996:User for colord:/var/lib/colord:/sbin/nologin 18 | usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin 19 | avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin 20 | avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin 21 | saslauth:x:996:76:"Saslauthd user":/run/saslauthd:/sbin/nologin 22 | libstoragemgmt:x:995:994:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin 23 | qemu:x:107:107:qemu user:/:/sbin/nologin 24 | rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin 25 | rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin 26 | radvd:x:75:75:radvd user:/:/sbin/nologin 27 | ntp:x:38:38::/etc/ntp:/sbin/nologin 28 | chrony:x:994:993::/var/lib/chrony:/sbin/nologin 29 | abrt:x:173:173::/etc/abrt:/sbin/nologin 30 | pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin 31 | rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin 32 | nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin 33 | gdm:x:42:42::/var/lib/gdm:/sbin/nologin 34 | gnome-initial-setup:x:993:991::/run/gnome-initial-setup/:/sbin/nologin 35 | postfix:x:89:89::/var/spool/postfix:/sbin/nologin 36 | sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin 37 | tcpdump:x:72:72::/:/sbin/nologin 38 | dmj:x:1000:1000:Doug Jacobsen:/home/dmj:/bin/bash 39 | tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin 40 | dockerroot:x:992:989:Docker User:/var/lib/docker:/sbin/nologin 41 | vboxadd:x:991:1::/var/run/vboxadd:/bin/false 42 | -------------------------------------------------------------------------------- /wlm_integration/torque/qsetenv.8: -------------------------------------------------------------------------------- 1 | qsetenv(8) Administration Commands qsetenv(8) 2 | 3 | 4 | 5 | NAME 6 | qsetenv - set environmental variable in pending job 7 | 8 | SYNOPSIS 9 | qsetenv [ -v ] [ -h ] pbs_server job_descriptor VarName Value 10 | 11 | DESCRIPTION 12 | qsetenv Appends a single environmental variable key=value pair to the 13 | list of environmental variables in a pending job. qsetenv will create 14 | the list in the job record if it does not previously exist. No exist- 15 | ing records will be removed, but only appended. Therefore if a vari- 16 | able has an existing value the shell within the job should evaluate the 17 | appended (qsetenv-set) value last. To change another user's jobs, 18 | administrative access to the scheduler is required. 19 | 20 | OPTIONS 21 | -h,--help 22 | Show help message (and exit 0 without changing any jobs) 23 | 24 | -V,--version 25 | Show qsetenv version and linked torque version (and exit 0 with- 26 | out changing any jobs) 27 | 28 | pbs_server 29 | PBS/torque server to connect to 30 | 31 | job_descriptor 32 | full job identifier (e.g., 12345.hopque02) 33 | 34 | VarName 35 | the environment variable name to set 36 | 37 | Value the environment variable value to set 38 | 39 | EXAMPLE 40 | qsetenv cvrsvc09-ib 123456.cvrsvc09-ib CHOS sl5carver 41 | 42 | EXIT STATUS 43 | Upon successful job modification the exit status will be zero. If help 44 | or version options are specified, qsetenv with exit with status zero. 45 | 46 | If qsetenv fails to modify the job (pbs_alterjob(3) fails), an exit 47 | status of one is returned. 48 | 49 | BUGS 50 | Not fully tested yet. 51 | 52 | AUTHOR 53 | Douglas Jacobsen 54 | 55 | SEE ALSO 56 | qsub(1B), qalter(1B), pbs_alterjob(3B) 57 | 58 | 59 | 60 | LBNL/NERSC 10 Sep 2014 qsetenv(8) 61 | -------------------------------------------------------------------------------- /extra/CI/test_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | ## Shifter, Copyright (c) 2015, The Regents of the University of California, 5 | ## through Lawrence Berkeley National Laboratory (subject to receipt of any 6 | ## required approvals from the U.S. Dept. of Energy). All rights reserved. 7 | ## 8 | ## Redistribution and use in source and binary forms, with or without 9 | ## modification, are permitted provided that the following conditions are met: 10 | ## 1. Redistributions of source code must retain the above copyright notice, 11 | ## this list of conditions and the following disclaimer. 12 | ## 2. Redistributions in binary form must reproduce the above copyright notice, 13 | ## this list of conditions and the following disclaimer in the documentation 14 | ## and/or other materials provided with the distribution. 15 | ## 3. Neither the name of the University of California, Lawrence Berkeley 16 | ## National Laboratory, U.S. Dept. of Energy nor the names of its 17 | ## contributors may be used to endorse or promote products derived from this 18 | ## software without specific prior written permission.` 19 | ## 20 | ## See LICENSE for full text. 21 | 22 | function runTest() { 23 | test=$1 24 | source=$2 25 | sources="$test-$source" 26 | echo "Running $test" 27 | timeout 90 ./$test -v 28 | if [[ "x$DO_ROOT_TESTS" == "x1" && -x ${test}_AsRoot ]]; then 29 | echo "Running $test as Root" 30 | sudo timeout 90 ./${test}_AsRoot 31 | sources="$sources ${test}_AsRoot-$source" 32 | fi 33 | if [[ "x$DO_ROOT_DANGEROUS_TESTS" == "x1" && -x ${test}_AsRootDangerous ]]; then 34 | echo "Running $test as Root with a side of DANGER" 35 | sudo timeout 90 ./${test}_AsRootDangerous 36 | sources="$sources ${test}_AsRootDangerous-$source" 37 | fi 38 | echo "Running valgrind for $test" 39 | valgrind --tool=memcheck --leak-check=full --suppressions=valgrind.suppressions -v ./$test >> valgrind.out 2>&1 || echo "ignore valgrind errors" 40 | echo "Coverage" 41 | gcov -b $sources 42 | } 43 | 44 | touch valgrind.out 45 | runTest test_ImageData ImageData 46 | runTest test_MountList MountList 47 | runTest test_UdiRootConfig UdiRootConfig 48 | runTest test_shifter_core shifter_core 49 | runTest test_shifter shifter 50 | runTest test_utility utility 51 | runTest test_VolumeMap VolumeMap 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | "Shifter, Copyright (c) 2015, The Regents of the University of California, through Lawrence Berkeley National Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved." 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | (1) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory, U.S. Dept. of Energy nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | 13 | You are under no obligation whatsoever to provide any bug fixes, patches, or upgrades to the features, functionality or performance of the source code ("Enhancements") to anyone; however, if you choose to make your Enhancements available either publicly, or directly to Lawrence Berkeley National Laboratory, without imposing a separate written license agreement for such Enhancements, then you hereby grant the following license: a non-exclusive, royalty-free perpetual license to install, use, modify, prepare derivative works, incorporate into other computer software, distribute, and sublicense such enhancements or derivative works thereof, in binary and source code form. 14 | -------------------------------------------------------------------------------- /auxdir/x_ac_munge.m4: -------------------------------------------------------------------------------- 1 | ##***************************************************************************** 2 | ## $Id$ 3 | ##***************************************************************************** 4 | # AUTHOR: 5 | # Chris Dunlap (originally for OpenSSL) 6 | # Modified for munge by Christopher Morrone 7 | # 8 | # SYNOPSIS: 9 | # X_AC_MUNGE() 10 | # 11 | # DESCRIPTION: 12 | # Check the usual suspects for an munge installation, 13 | # updating CPPFLAGS and LDFLAGS as necessary. 14 | # 15 | # WARNINGS: 16 | # This macro must be placed after AC_PROG_CC and before AC_PROG_LIBTOOL. 17 | ##***************************************************************************** 18 | 19 | AC_DEFUN([X_AC_MUNGE], [ 20 | 21 | _x_ac_munge_dirs="/usr /usr/local /opt/freeware /opt/munge" 22 | _x_ac_munge_libs="lib64 lib" 23 | 24 | AC_ARG_WITH( 25 | [munge], 26 | AS_HELP_STRING(--with-munge=PATH,Specify path to munge installation), 27 | [_x_ac_munge_dirs="$withval $_x_ac_munge_dirs"]) 28 | 29 | AC_CACHE_CHECK( 30 | [for munge installation], 31 | [x_ac_cv_munge_dir], 32 | [ 33 | for d in $_x_ac_munge_dirs; do 34 | test -d "$d" || continue 35 | test -d "$d/include" || continue 36 | test -f "$d/include/munge.h" || continue 37 | for bit in $_x_ac_munge_libs; do 38 | test -d "$d/$bit" || continue 39 | 40 | _x_ac_munge_libs_save="$LIBS" 41 | LIBS="-L$d/$bit -lmunge $LIBS" 42 | AC_LINK_IFELSE( 43 | [AC_LANG_CALL([], munge_encode)], 44 | AS_VAR_SET(x_ac_cv_munge_dir, $d)) 45 | LIBS="$_x_ac_munge_libs_save" 46 | test -n "$x_ac_cv_munge_dir" && break 47 | done 48 | test -n "$x_ac_cv_munge_dir" && break 49 | done 50 | ]) 51 | 52 | if test -z "$x_ac_cv_munge_dir"; then 53 | AC_MSG_WARN([unable to locate munge installation]) 54 | else 55 | MUNGE_LIBS="-lmunge" 56 | MUNGE_CPPFLAGS="-I$x_ac_cv_munge_dir/include" 57 | MUNGE_DIR="$x_ac_cv_munge_dir" 58 | if test "$ac_with_rpath" = "yes"; then 59 | MUNGE_LDFLAGS="-Wl,-rpath -Wl,$x_ac_cv_munge_dir/$bit -L$x_ac_cv_munge_dir/$bit -lmunge" 60 | else 61 | MUNGE_LDFLAGS="-L$x_ac_cv_munge_dir/$bit -lmunge" 62 | fi 63 | fi 64 | 65 | AC_SUBST(MUNGE_LIBS) 66 | AC_SUBST(MUNGE_CPPFLAGS) 67 | AC_SUBST(MUNGE_LDFLAGS) 68 | AC_SUBST(MUNGE_DIR) 69 | 70 | AM_CONDITIONAL(WITH_MUNGE, test -n "$x_ac_cv_munge_dir") 71 | ]) 72 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: true 2 | dist: bionic 3 | language: python 4 | python: 5 | - "3.8" 6 | compiler: 7 | - clang 8 | - gcc 9 | # command to install dependencies 10 | before_install: 11 | - sudo chmod 755 /var/log 12 | - sudo add-apt-repository "deb http://us.archive.ubuntu.com/ubuntu/ bionic universe multiverse" 13 | - sudo apt-get update -qq 14 | - sudo apt-get install -qq libjson-c-dev munge libmunge2 libmunge-dev libcurl4-openssl-dev autoconf automake libtool curl make valgrind xfsprogs squashfs-tools libcap-dev 15 | - sudo modprobe squashfs 16 | - sudo modprobe xfs 17 | - cat /proc/filesystems 18 | install: 19 | - pip install -r imagegw/requirements.txt 20 | - pip install coverage 21 | - pip install cpp-coveralls 22 | - LOC=$(dirname $(which coveralls) ); sudo mv $LOC/coveralls $LOC/cpp-coveralls 23 | - pip install coveralls 24 | - pip install coveralls-merge 25 | - pip install pexpect 26 | # command to run tests 27 | before_script: 28 | - cp imagegw/test.json.example test.json 29 | - mkdir /tmp/imagegw /tmp/systema /tmp/systemb 30 | - rm imagegw/test/sha256sum 31 | script: 32 | - echo "Disabling autoclear for Travis and Kernel 5.4" 33 | - sed -i 's/useAutoclear = 1;/useAutoclear = 0;/' ./src/shifter_core.c 34 | - export PROC_COUNT=$(cat /proc/cpuinfo | egrep '^processor' | wc -l) 35 | - ./autogen.sh 36 | - ./configure --prefix=/usr --sysconfdir=/etc/shifter --disable-staticsshd 37 | - MAKEFLAGS="-j$PROC_COUNT" make 38 | - MAKEFLAGS="-j$PROC_COUNT" make check 39 | - sudo make install 40 | - cd src/test 41 | - export DO_ROOT_TESTS=1 42 | - export DO_ROOT_DANGEROUS_TESTS=1 43 | - ../../extra/CI/test_script.sh 44 | - cd ../.. 45 | - export ORIGPATH=$PATH 46 | - export PATH=$PWD/imagegw/test:$PATH 47 | - PYTHONPATH=$PWD/imagegw nosetests -s --with-coverage imagegw/test 48 | - export PATH=$ORIGPATH 49 | - export BUILDDIR=$(pwd) 50 | - cd / 51 | - $BUILDDIR/extra/CI/integration_test.sh 52 | - cd $BUILDDIR 53 | services: 54 | - mongodb 55 | - redis 56 | after_failure: 57 | - df /tmp 58 | - dmesg 59 | - find /tmp/|head -100 60 | - ls -latrh /tmp/* 61 | - ls -latrh /tmp/imagegw/* 62 | - ls -latrh /tmp/systema/images/* 63 | - cat /var/log/shifter_imagegw/error.log 64 | - cat /var/log/shifter_imagegw/access.log 65 | after_success: 66 | - cpp-coveralls --exclude dep -n --dump cpp_coveralls.json 67 | - coveralls-merge cpp_coveralls.json 68 | notifications: 69 | slack: shifter-hpc:G2yziADLjfv5y0KoCVT907cS 70 | -------------------------------------------------------------------------------- /auxdir/x_ac_jsonc.m4: -------------------------------------------------------------------------------- 1 | ##***************************************************************************** 2 | ## $Id$ 3 | ##***************************************************************************** 4 | # AUTHOR: 5 | # Chris Dunlap (originally for OpenSSL) 6 | # Modified for json by Christopher Morrone 7 | # 8 | # SYNOPSIS: 9 | # X_AC_JSON() 10 | # 11 | # DESCRIPTION: 12 | # Check the usual suspects for an json installation, 13 | # updating CPPFLAGS and LDFLAGS as necessary. 14 | # 15 | # WARNINGS: 16 | # This macro must be placed after AC_PROG_CC and before AC_PROG_LIBTOOL. 17 | ##***************************************************************************** 18 | 19 | AC_DEFUN([X_AC_JSON], [ 20 | 21 | _x_ac_json_dirs="/usr /usr/local /opt/json /opt/slurm/json-c/default" 22 | _x_ac_json_libs="lib64 lib" 23 | 24 | AC_ARG_WITH( 25 | [json-c], 26 | AS_HELP_STRING(--with-json-c=PATH,Specify path to json-c installation), 27 | [_x_ac_json_dirs="$withval $_x_ac_json_dirs"]) 28 | 29 | AC_CACHE_CHECK( 30 | [for json-c installation], 31 | [x_ac_cv_json_dir], 32 | [ 33 | for d in $_x_ac_json_dirs; do 34 | test -d "$d" || continue 35 | test -d "$d/include" || continue 36 | test -d "$d/include/json-c" || continue 37 | test -f "$d/include/json-c/json.h" || continue 38 | for bit in $_x_ac_json_libs; do 39 | test -d "$d/$bit" || continue 40 | 41 | _x_ac_json_libs_save="$LIBS" 42 | LIBS="-L$d/$bit -ljson-c $LIBS" 43 | AC_LINK_IFELSE( 44 | [AC_LANG_CALL([], json_tokener_parse)], 45 | AS_VAR_SET(x_ac_cv_json_dir, $d)) 46 | LIBS="$_x_ac_json_libs_save" 47 | test -n "$x_ac_cv_json_dir" && break 48 | done 49 | test -n "$x_ac_cv_json_dir" && break 50 | done 51 | ]) 52 | 53 | if test -z "$x_ac_cv_json_dir"; then 54 | AC_MSG_WARN([unable to locate json installation]) 55 | else 56 | JSON_LIBS="-ljson-c" 57 | JSON_CPPFLAGS="-I$x_ac_cv_json_dir/include" 58 | JSON_DIR="$x_ac_cv_json_dir" 59 | if test "$ac_with_rpath" = "yes"; then 60 | JSON_LDFLAGS="-Wl,-rpath -Wl,$x_ac_cv_json_dir/$bit -L$x_ac_cv_json_dir/$bit" 61 | else 62 | JSON_LDFLAGS="-L$x_ac_cv_json_dir/$bit -ljson-c" 63 | fi 64 | fi 65 | 66 | AC_SUBST(JSON_LIBS) 67 | AC_SUBST(JSON_CPPFLAGS) 68 | AC_SUBST(JSON_LDFLAGS) 69 | AC_SUBST(JSON_DIR) 70 | 71 | AM_CONDITIONAL(WITH_JSON, test -n "$x_ac_cv_json_dir") 72 | ]) 73 | -------------------------------------------------------------------------------- /imagegw/test/munge_test.py: -------------------------------------------------------------------------------- 1 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 2 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright notice, 10 | # this list of conditions and the following disclaimer in the documentation 11 | # and/or other materials provided with the distribution. 12 | # 3. Neither the name of the University of California, Lawrence Berkeley 13 | # National Laboratory, U.S. Dept. of Energy nor the names of its 14 | # contributors may be used to endorse or promote products derived from this 15 | # software without specific prior written permission.` 16 | # 17 | # See LICENSE for full text. 18 | 19 | import os 20 | import unittest 21 | from shifter_imagegw import munge 22 | 23 | 24 | class MungeTestCase(unittest.TestCase): 25 | 26 | def setUp(self): 27 | self.test_dir = os.path.dirname(os.path.abspath(__file__)) + \ 28 | "/../test/" 29 | self.encoded = "xxxx\n" 30 | self.message = "test" 31 | self.expired = "expired" 32 | with open(self.test_dir + "munge.test", 'w') as f: 33 | f.write(self.encoded) 34 | 35 | def tearDown(self): 36 | with open(self.test_dir + "munge.expired", 'w') as f: 37 | f.write('') 38 | 39 | def test_munge(self): 40 | resp = munge.munge(self.message) 41 | assert resp is not None 42 | 43 | def test_unmunge(self): 44 | resp = munge.unmunge(self.encoded) 45 | assert resp['MESSAGE'] == self.message 46 | 47 | def test_unmunge_expired(self): 48 | with open(self.test_dir + "munge.expired", 'w') as f: 49 | f.write(self.expired) 50 | with self.assertRaises(OSError): 51 | munge.unmunge(self.expired) 52 | 53 | def test_unmunge_replay(self): 54 | resp = munge.unmunge(self.encoded) 55 | assert resp['MESSAGE'] == self.message 56 | with self.assertRaises(OSError): 57 | munge.unmunge(self.encoded) 58 | 59 | 60 | if __name__ == '__main__': 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # NOTE: This Dockerfile is used to build a test shifter image. The image can be used 2 | # to mimic a system (login node) that would have shifter installed. 3 | # This is only used for testing purposes. 4 | # It runs munge and sshd which would normally be a bad idea for a container. 5 | # 6 | # If you are looking to build an image for the gateway. Look at the Dockerfile 7 | # in imagegw/src. 8 | 9 | FROM ubuntu:18.04 10 | MAINTAINER Shane Canon 11 | 12 | # Thanks to Sven Dowideit 13 | # for a Dockerfile that configured ssh 14 | 15 | # Install requirements to build shifter, run munge, and openssh 16 | RUN apt-get update && \ 17 | apt-get install -y gcc autoconf make libtool g++ munge libmunge-dev \ 18 | libcurl4-openssl-dev libjson-c-dev build-essential openssh-server libcap-dev \ 19 | curl && \ 20 | mkdir /var/run/sshd && \ 21 | echo 'root:lookatmenow' | chpasswd && \ 22 | sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ 23 | sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd && \ 24 | echo "export VISIBLE=now" >> /etc/profile 25 | 26 | ENV NOTVISIBLE "in users profile" 27 | 28 | ADD . /src/ 29 | 30 | RUN \ 31 | cd /src/ && \ 32 | cp /bin/mount /src/dep/mount && \ 33 | touch configure.ac && \ 34 | sh ./autogen.sh && \ 35 | tar cf /src/dep/udiRoot_dep.tar /bin/mount && \ 36 | ./configure --prefix=/opt/shifter/udiRoot/1.0 --sysconfdir=/etc/shifter \ 37 | --with-libcurl --with-munge --disable-nativeSlurm --disable-staticsshd && \ 38 | make && make install 39 | 40 | ADD imagegw/test/entrypoint.sh /entrypoint.sh 41 | 42 | # Fix up perms and other things 43 | RUN \ 44 | mkdir /root/.ssh && chmod 700 /root/.ssh && \ 45 | echo " StrictHostKeyChecking no" >> /etc/ssh/ssh_config && \ 46 | chmod 755 /var/log/ && \ 47 | echo 'PATH=$PATH:/opt/shifter/udiRoot/1.0/bin/' > /etc/profile.d/shifter.sh && \ 48 | chmod 755 /etc/profile.d/shifter.sh 49 | 50 | # chmod 600 /etc/munge/munge.key && chown munge /etc/munge/munge.key && \ 51 | 52 | ADD ./imagegw/test/premount.sh /etc/shifter/premount.sh 53 | ADD ./imagegw/test/postmount.sh /etc/shifter/postmount.sh 54 | RUN mkdir -p /images/test/ 55 | ADD ./imagegw/test/test.squashfs /images/test 56 | COPY ./imagegw/shifter_imagegw/fasthash.py /usr/local/bin 57 | RUN chmod a+rx /usr/local/bin/fasthash.py 58 | 59 | 60 | EXPOSE 22 61 | ENTRYPOINT [ "/entrypoint.sh" ] 62 | -------------------------------------------------------------------------------- /doc/command/shifter.rst: -------------------------------------------------------------------------------- 1 | shifter 2 | ======= 3 | 4 | Synopsis 5 | -------- 6 | *shifter* [options] _command_ [command options] 7 | 8 | Description 9 | ----------- 10 | *shifter* generates or attaches to an existing shifter container environment 11 | and launches a process within that container environment. This is done with 12 | minimal overhead to ensure that container creation and process execution are 13 | done as quickly as possible in support of High Performance Computing needs. 14 | 15 | Options 16 | ------- 17 | --image Image Selection Specification 18 | -V|--volume Volume bind mount 19 | -h|--help This help text 20 | -v|--verbose Increased logging output 21 | 22 | Image Selection 23 | --------------- 24 | *shifter* identifies the desired image by examining its environment and command 25 | line options. In order of precedence, shifter selects image by looking at the 26 | following sources: 27 | - SHIFTER environment variable containing both image type and image speicifier 28 | - SHIFTER_IMAGE and SHIFTER_IMAGETYPE environment variables 29 | - SLURM_SPANK_SHIFTER_IMAGE and SLURM_SPANK_SHIFTER_IMAGETYPE environment variables 30 | - --image command line option 31 | 32 | Thus, the batch system can set effective defaults for image selection by manipulating 33 | the job environemnt, however, the user can always override by specifying the --image 34 | command line argument. 35 | 36 | The format of --image or the SHIFTER environment variable are the same: 37 | imageType:imageSpecifier 38 | 39 | where imageType is typically "docker" but could be other, site-defined types. 40 | imageSpecifier is somewhat dependent on the imageType, however, for docker, the 41 | image gateway typically assigns the sha256 hash of the image manifest to be 42 | the specifier. 43 | 44 | shifter will attempt to see if the global environment already has a shifter 45 | image configured matching the users arguments. If a compatible image is already 46 | setup on the system the existing environment will be used to launch the 47 | requested process. If not, shifter will generate a new mount namespace, and 48 | setup a new shifter environment. This ensures that multiple shifter instances 49 | can be used simultaneously on the same node. Note that each shifter instance 50 | will consume at least one loop device, thus it is recommended that sites allow 51 | for at least two available loop devices per shifter instance that might be 52 | reasonably started on a compute node. At NERSC, we allow up to 128 loop 53 | devices per compute node. 54 | 55 | User-Specified Volume Mounts 56 | ---------------------------- 57 | 58 | -------------------------------------------------------------------------------- /doc/install/centos7.rst: -------------------------------------------------------------------------------- 1 | Installing Shifter on a RHEL/Centos/Scientific Linux 7 System 2 | ************************************************************* 3 | 4 | Building RPMs 5 | ============= 6 | 7 | First, ensure your build system has all necessary packages installed:: 8 | 9 | yum install epel-release 10 | yum install rpm-build gcc glibc-devel munge libcurl-devel json-c \ 11 | json-c-devel pam-devel munge-devel libtool autoconf automake \ 12 | gcc-c++ python-pip xfsprogs squashfs-tools python-devel 13 | 14 | Next, if not using a prepared source tarball, generate one from the repo:: 15 | 16 | git clone https://github.com/NERSC/shifter.git 17 | [[ perform any needed git operations to get a particular branch or commit 18 | you require. We currently recommend the 16.08.3_2 tag. ]] 19 | VERSION=$(grep Version: shifter/shifter.spec | awk '{print $2}') 20 | cp -rp shifter "shifter-$VERSION" 21 | tar cf "shifter-$VERSION.tar.gz" "shifter-$VERSION" 22 | 23 | Build the RPMs from your tarball:: 24 | 25 | rpmbuild -tb "shifter-$VERSION.tar.gz" 26 | 27 | *Note about Slurm support* 28 | To build with Slurm support do:: 29 | 30 | rpmbuild -tb "shifter-$VERSION.tar.gz" --define "with_slurm /usr" 31 | 32 | Change "/usr" to the base path Slurm is installed in. 33 | 34 | Installing the Image Manager 35 | ============================ 36 | 37 | Install the Shifter runtime RPM 38 | 39 | yum -y install shifter{,-imagegw}-1*rpm 40 | 41 | Create a config, create directories, start Mongo. 42 | 43 | cp /etc/shifter/imagemanager.json.example /etc/shifter/imagemanager.json 44 | mkdir /images 45 | mkdir -p /data/db 46 | mongod --smallfiles & 47 | 48 | Start Munge 49 | 50 | echo "abcdefghijklkmnopqrstuvwxyz0123456" > /etc/munge/munge.key 51 | chown munge.munge /etc/munge/munge.key 52 | chmod 600 /etc/munge/munge.key 53 | runuser -u munge munged 54 | 55 | Start the image gateway and a worker for "mycluster" 56 | 57 | gunicorn -b 0.0.0.0:5000 --backlog 2048 shifter_imagegw.api:app & 58 | 59 | Installing the Runtime 60 | ============================ 61 | 62 | yum -y install shifter{,-runtime}-1*rpm 63 | cp /etc/shifter/udiRoot.conf.example etc/shifter/udiRoot.conf 64 | sed -i 's|etcPath=.*|etcPath=/etc/shifter/shifter_etc_files/|' /etc/shifter/udiRoot.conf 65 | sed -i 's|imagegwapi:5000|localhost:5000|' /etc/shifter/udiRoot.conf 66 | echo "abcdefghijklkmnopqrstuvwxyz0123456" > /etc/munge/munge.key 67 | chown munge.munge /etc/munge/munge.key 68 | chmod 600 /etc/munge/munge.key 69 | runuser -u munge munged 70 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | SUBDIRS = test 4 | 5 | AM_CPPFLAGS = -DCONFIG_FILE=\"${sysconfdir}/udiRoot.conf\" -DLIBEXECDIR=\"${libexecdir}/shifter\" -Wall 6 | 7 | if ALLOW_STATICSSHD 8 | SSH_CPPFLAGS=-DALLOW_STATICSSHD=1 9 | else 10 | SSH_CPPFLAGS= 11 | endif 12 | 13 | sbin_PROGRAMS = setupRoot unsetupRoot 14 | bin_PROGRAMS = shifter shifterimg 15 | 16 | SHIFTER_SOURCES = \ 17 | shifter.c \ 18 | UdiRootConfig.h \ 19 | UdiRootConfig.c \ 20 | utility.h \ 21 | utility.c \ 22 | shifter_core.h \ 23 | shifter_core.c \ 24 | shifter_mem.h \ 25 | shifter_mem.c \ 26 | ImageData.h \ 27 | ImageData.c \ 28 | VolumeMap.h \ 29 | VolumeMap.c \ 30 | PathList.h \ 31 | PathList.c \ 32 | MountList.h \ 33 | MountList.c 34 | 35 | SETUPROOT_SOURCES = \ 36 | setupRoot.c \ 37 | UdiRootConfig.h \ 38 | UdiRootConfig.c \ 39 | utility.h \ 40 | utility.c \ 41 | shifter_core.h \ 42 | shifter_core.c \ 43 | shifter_mem.h \ 44 | shifter_mem.c \ 45 | ImageData.h \ 46 | ImageData.c \ 47 | VolumeMap.h \ 48 | VolumeMap.c \ 49 | PathList.h \ 50 | PathList.c \ 51 | MountList.h \ 52 | MountList.c 53 | 54 | UNSETUPROOT_SOURCES = \ 55 | unsetupRoot.c \ 56 | UdiRootConfig.h \ 57 | UdiRootConfig.c \ 58 | utility.h \ 59 | utility.c \ 60 | shifter_core.h \ 61 | shifter_core.c \ 62 | shifter_mem.h \ 63 | shifter_mem.c \ 64 | ImageData.h \ 65 | ImageData.c \ 66 | VolumeMap.h \ 67 | VolumeMap.c \ 68 | PathList.h \ 69 | PathList.c \ 70 | MountList.h \ 71 | MountList.c 72 | 73 | SHIFTERIMG_SOURCES = \ 74 | shifterimg.c \ 75 | shifterimg.h \ 76 | ImageData.h \ 77 | ImageData.c \ 78 | utility.h \ 79 | utility.c \ 80 | UdiRootConfig.h \ 81 | UdiRootConfig.c \ 82 | VolumeMap.h \ 83 | VolumeMap.c \ 84 | shifter_core.h \ 85 | shifter_core.c \ 86 | shifter_mem.h \ 87 | shifter_mem.c \ 88 | MountList.c \ 89 | PathList.c 90 | 91 | 92 | shifter_SOURCES = $(SHIFTER_SOURCES) 93 | setupRoot_SOURCES = $(SETUPROOT_SOURCES) 94 | setupRoot_CPPFLAGS = $(AM_CPPFLAGS) $(SSH_CPPFLAGS) 95 | unsetupRoot_SOURCES = $(UNSETUPROOT_SOURCES) 96 | shifterimg_SOURCES = $(SHIFTERIMG_SOURCES) 97 | shifterimg_LDFLAGS = $(MUNGE_LDFLAGS) $(JSON_LDFLAGS) $(LIBCURL) $(MUNGE_LDFLAGS) 98 | shifterimg_CPPFLAGS = $(AM_CPPFLAGS) $(MUNGE_CPPFLAGS) $(JSON_CPPFLAGS) $(LIBCURL_CPPFLAGS) $(MUNGE_CPPFLAGS) 99 | 100 | install-exec-hook: 101 | /bin/chmod 4755 $(DESTDIR)$(bindir)/shifter 102 | -------------------------------------------------------------------------------- /imagegw/README.md: -------------------------------------------------------------------------------- 1 | # Image Gateway API 2 | 3 | The image gateway handles creating, tracking, and cleaning up images. It provides a RESTful interface for client interactions, a manager layer that manages and tracks the images, and workers that do most of the fetching, packing and transferring of images. 4 | 5 | To start the image gateway do something like: 6 | 7 | ## May need to add something to PYTHONPATH depending on where shifter_imagegw 8 | ## is installed 9 | gunicorn -b 0.0.0.0:5000 --backlog 2048 \ 10 | --access-logfile=/var/log/shifter_imagegw/access.log \ 11 | --log-file=/var/log/shifter_imagegw/error.log \ 12 | shifter_imagegw.api:app 13 | 14 | ## Start Gateway with Docker and Docker-Compose 15 | 16 | If docker and docker-compose are installed, you can try starting a test environment with docker-compose. There is a Makefile 17 | target that makes this easy. 18 | 19 | make -f Makefile.test starttest 20 | 21 | This will create a munge key and ssh keys in test/config. This directory gets volumed mounted into the API and Worker images. 22 | See the docker-compose.yml for details. You can modify the docker-compose and create a configuration directory to run a non-test 23 | instance of the API and worker service. 24 | 25 | ## API 26 | 27 | The image manager provides a RESTful API. It has three main verbs that it supports. The API is a thin translation layer on top of the manager layer. Most of the actual action is handled by functions in the management layer. 28 | 29 | ### Lookup 30 | 31 | curl -H "authentication: mungehash" -X GET http://localhost:5555/api/lookup/system/docker/ubuntu:latest 32 | 33 | ### Pull 34 | 35 | curl -H "authentication: mungehash" -X POST http://localhost:5555/api/pull/system/docker/ubuntu:latest 36 | 37 | ### List 38 | 39 | TODO 40 | 41 | ### Expire 42 | 43 | Not fully implemented yet. 44 | 45 | ## Manager layer 46 | 47 | The manager layer contains functions that map to the API layer but also has a 48 | number of helper functions. The manager layer uses a Mongo database to keep 49 | track of the images. It uses python threads to asynchronously spawn task to pull, pack, 50 | and transfer images. 51 | 52 | ### Configuration 53 | 54 | See imagemanger.json 55 | 56 | ### Troubleshooting 57 | 58 | TODO 59 | 60 | ## workers 61 | 62 | The image manager uses python thread-based workers to do the low-level image 63 | manipulation. This separation is primarily so the operations can be queued to 64 | prevent overloading the image manager, but also enables the workers being 65 | remotely executed. 66 | 67 | ### Configuration 68 | 69 | See imagemanager.json 70 | 71 | ### Troubleshooting 72 | 73 | TODO 74 | -------------------------------------------------------------------------------- /imagegw/test/auth_test.py: -------------------------------------------------------------------------------- 1 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 2 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright notice, 10 | # this list of conditions and the following disclaimer in the documentation 11 | # and/or other materials provided with the distribution. 12 | # 3. Neither the name of the University of California, Lawrence Berkeley 13 | # National Laboratory, U.S. Dept. of Energy nor the names of its 14 | # contributors may be used to endorse or promote products derived from this 15 | # software without specific prior written permission.` 16 | # 17 | # See LICENSE for full text. 18 | 19 | import os 20 | import unittest 21 | from shifter_imagegw.auth import Authentication 22 | 23 | 24 | class AuthTestCase(unittest.TestCase): 25 | 26 | def setUp(self): 27 | self.test_dir = os.path.dirname(os.path.abspath(__file__)) + \ 28 | "/../test/" 29 | self.encoded = "xxxx\n" 30 | self.message = "test" 31 | self.expired = "expired" 32 | with open(self.test_dir + "munge.test", 'w') as f: 33 | f.write(self.encoded) 34 | self.system = 'systema' 35 | self.config = { 36 | "Authentication": "munge", 37 | "Platforms": {self.system: {"mungeSocketPath": "/tmp/munge.s"}} 38 | } 39 | self.auth = Authentication(self.config) 40 | 41 | def tearDown(self): 42 | with open(self.test_dir + "munge.expired", 'w') as f: 43 | f.write('') 44 | 45 | def test_auth(self): 46 | """ Test success """ 47 | resp = self.auth.authenticate(self.encoded, self.system) 48 | assert resp is not None 49 | self.assertIsInstance(resp, dict) 50 | 51 | def test_auth_replay(self): 52 | resp = self.auth.authenticate(self.encoded, self.system) 53 | assert resp is not None 54 | with self.assertRaises(OSError): 55 | resp = self.auth.authenticate(self.encoded, self.system) 56 | 57 | def test_auth_bad(self): 58 | with self.assertRaises(OSError): 59 | self.auth.authenticate("bad", self.system) 60 | 61 | 62 | if __name__ == '__main__': 63 | unittest.main() 64 | -------------------------------------------------------------------------------- /src/shifterimg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file shifterimg.h 3 | * @brief header file for shifterimg 4 | * 5 | * @author Douglas M. Jacobsen 6 | */ 7 | 8 | /* Shifter, Copyright (c) 2017, The Regents of the University of California, 9 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 10 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions are met: 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University of California, Lawrence Berkeley 20 | * National Laboratory, U.S. Dept. of Energy nor the names of its 21 | * contributors may be used to endorse or promote products derived from this 22 | * software without specific prior written permission. 23 | * 24 | * See LICENSE for full text. 25 | */ 26 | 27 | enum ImageGwAction { 28 | MODE_LOOKUP = 0, 29 | MODE_PULL, 30 | MODE_IMAGES, 31 | MODE_LOGIN, 32 | MODE_PULL_NONBLOCK, 33 | MODE_EXPIRE, 34 | MODE_AUTOEXPIRE, 35 | MODE_INVALID 36 | }; 37 | 38 | enum AclCredential { 39 | USER_ACL = 0, 40 | GROUP_ACL, 41 | INVALID_ACL 42 | }; 43 | 44 | typedef struct _LoginCredential { 45 | char *system; 46 | char *location; 47 | char *cred; 48 | } LoginCredential; 49 | 50 | struct options { 51 | int verbose; 52 | enum ImageGwAction mode; 53 | char *type; 54 | char *tag; 55 | char *rawtype; 56 | char *rawtag; 57 | char *location; 58 | char *rawlocation; 59 | LoginCredential **loginCredentials; 60 | 61 | int *allowed_uids; 62 | size_t allowed_uids_len; 63 | size_t allowed_uids_sz; 64 | 65 | int *allowed_gids; 66 | size_t allowed_gids_len; 67 | size_t allowed_gids_sz; 68 | }; 69 | 70 | typedef struct _ImageGwState { 71 | char *message; 72 | int isJsonMessage; 73 | size_t expContentLen; 74 | size_t messageLen; 75 | size_t messageCurr; 76 | int messageComplete; 77 | } ImageGwState; 78 | 79 | typedef struct _ImageGwImageRec { 80 | char *entryPoint; 81 | char **env; 82 | char *workdir; 83 | char **groupAcl; 84 | char *identifier; 85 | char *type; 86 | char *status; 87 | double last_pull; 88 | char *system; 89 | char **tag; 90 | char **userAcl; 91 | } ImageGwImageRec; 92 | -------------------------------------------------------------------------------- /doc/PrivateImagesAndACLS.md: -------------------------------------------------------------------------------- 1 | # Private Registries and ACLs (17.04 or newer) 2 | 3 | Private registries are useful for cases where a user has applications or source 4 | code that need to be protected. This may be because of competitive reasons 5 | (e.g. an application that hasn't been published yet) or the image may have 6 | licensed applications that can't be generally shared. Shifter needs to 7 | provide a way to fetch these images from a secure repository such as a private 8 | DockerHub repo and also protect it locally so others users can't run the image. 9 | This document explains how to use this feature. 10 | 11 | ## Usage 12 | 13 | The repository must already be configured by the site admin to be supported. 14 | Once it is configured use the shifterimg tool to store your credentials for 15 | accessing the private repo. You must provide the name of the registry as 16 | configured by the site or use default. 17 | 18 | shifterimg login default 19 | default username: 20 | default password: 21 | 22 | This credential will be stored as a file in your home directory similar to the way docker stores the credential. 23 | 24 | You can now try pulling the image and include a list of users that should be allowed to use the pulled image. 25 | 26 | shifter --user alice,bob,charlie pull usera/privaterepo:latest 27 | 28 | This would allow users alice, bob and charlie to use the image. ACLs can be changed to re-pulling the image but with a different list of users. **If the image is pulled with no ACLs specified, then it will be publicly visible.** 29 | 30 | ## Design and Theory of operation 31 | 32 | When dealing with private registries we need to handle both gathering 33 | the users credentials to access the registry and manage access to the 34 | downloaded images. The general flow for the user is shown above. 35 | 36 | ## Under the hood 37 | 38 | ### Credentials: 39 | 40 | shifterimg login will save a munge encrypted string username:password. 41 | This will be sent along with the request in the auth header. 42 | 43 | imagegw will decrypt this and store it in the session structure. 44 | 45 | 46 | ### Allowed UIDs and GIDs: 47 | 48 | shifterimg pull will send a allowed_uids and allowed_gids in the data part of the 49 | POST 50 | 51 | imagegw will parse the allowed_uids/gids and convert them to a list of integers. 52 | imagegw will store these lists in the mongo record. 53 | imagegw will write these values as comma, sepearated text string in the meta 54 | file of the image. 55 | 56 | imagegw will overwrite the values if an images is pulled. 57 | 58 | ## Edge Cases 59 | 60 | TODO: Explain some of the various edge cases and how those are 61 | handled. 62 | 63 | * Public images 64 | * Private Images without ACLs 65 | * etc 66 | -------------------------------------------------------------------------------- /imagegw/test/skopeo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Mock skopeo utility 4 | 5 | PF="" 6 | 7 | if [ "z$1" = "z--policy" ] ; then 8 | PF=$2 9 | shift 2 10 | fi 11 | 12 | D=$(dirname $0) 13 | 14 | if [ "z$1" = "zinspect" ] ; then 15 | if "z$2" = "zprivate" ] ; then 16 | echo "authentication required" 17 | fi 18 | echo '{ "Architecture": "amd64", "Created": "2017-01-10T21:42:25.588561677Z", "Digest": "sha256:468b48e3864f5489a6fa4a35843292b101ac73c31e3272688fa3220ff485f549", "DockerVersion": "1.13.0-rc4", "Labels": {}, "Layers": [ "sha256:f810322bba2c5f0a6dd58ba31eba0543baabb4533e479ab2db376aaa8064be55", "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", "sha256:86fa702c53d11ca5a8c206ae62fd45f1911007e999f49ec4116cb7c4f9f40cbd", "sha256:57dae26e12847ce0a71649c7d7e07fa79b9daf09586831230d3600ef6963bc2d", "sha256:744ea9668b0c7373dd2c779279d5f707746b11bcdd47f91922d1031d9135e8ee", "sha256:ba650fd71ca9d6a2aed9243ecf92a71496effbf6c848b579ef0eb5ba058c356f", "sha256:64bf384bc6dfa0c22b42dd1300cc2141951b7293ef2c4a2754386cdea997453c", "sha256:e44d7fd484bc1990e3ca0730c3b45db8e44937ac7fc476085ad02bd817338c84" ], "Name": "docker.io/scanon/shaneprivate", "Os": "linux", "RepoTags": [ "latest" ] }' 19 | 20 | elif [ "z$1" = "zcopy" ] ; then 21 | DEST=$(echo $5|sed 's/oci:..//'|sed 's/:image//') 22 | mkdir -p $DEST 23 | mkdir $DEST/blobs 24 | #index 25 | echo '{"schemaVersion":2,"manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:41691e1851314e2f37eee22c2a9969500d0dcab259f1357f447ef28155f22efc","size":348,"platform":{"architecture":"amd64","os":"linux"}}]}' > $DEST/index.json 26 | 27 | # manifest 28 | CDIR="$3/sha256" 29 | mkdir -p $CDIR 30 | echo '{"schemaVersion":2,"config":{"mediaType":"application/vnd.oci.image.config.v1+json","digest":"sha256:0f5f445df8ccbd8a062ad3d02d459e8549d9998c62a5b7cbf77baf68aa73bf5b","size":585},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","digest":"sha256:df20fa9351a15782c64e6dddb2d4a6f50bf6d3688060a34c4014b0d9a752eb4c","size":2797541}]}' > $CDIR/41691e1851314e2f37eee22c2a9969500d0dcab259f1357f447ef28155f22efc 31 | 32 | # digest 33 | echo '{"created":"2020-05-29T21:19:46.363518345Z","architecture":"amd64","os":"linux","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Labels":{"alabel": "avalue"}},"rootfs":{"type":"layers","diff_ids":["sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a"]},"history":[{"created":"2020-05-29T21:19:46.192045972Z","created_by":"/bin/sh -c #(nop) ADD file:c92c248239f8c7b9b3c067650954815f391b7bcb09023f984972c082ace2a8d0 in / "},{"created":"2020-05-29T21:19:46.363518345Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}]}' > $CDIR/0f5f445df8ccbd8a062ad3d02d459e8549d9998c62a5b7cbf77baf68aa73bf5b 34 | 35 | fi 36 | -------------------------------------------------------------------------------- /auxdir/x_ac_slurm.m4: -------------------------------------------------------------------------------- 1 | ##***************************************************************************** 2 | ## $Id$ 3 | ##***************************************************************************** 4 | # AUTHOR: 5 | # Douglas Jacobsen 6 | # Totally ripped off from x_ac_munge.m4, by: 7 | # Chris Dunlap (originally for OpenSSL) 8 | # Modified for munge by Christopher Morrone 9 | # 10 | # SYNOPSIS: 11 | # X_AC_SLURM() 12 | # 13 | # DESCRIPTION: 14 | # Check the usual suspects for a slurm installation, 15 | # updating CPPFLAGS and LDFLAGS as necessary. 16 | # 17 | # WARNINGS: 18 | # This macro must be placed after AC_PROG_CC and before AC_PROG_LIBTOOL. 19 | ##***************************************************************************** 20 | 21 | AC_DEFUN([X_AC_SLURM], [ 22 | 23 | _x_ac_slurm_dirs="/usr /usr/local /opt/slurm /opt/slurm/default" 24 | _x_ac_slurm_libs="lib64 lib" 25 | 26 | AC_ARG_WITH( 27 | [slurm], 28 | AS_HELP_STRING(--with-slurm=PATH,Specify path to slurm installation), 29 | [_x_ac_slurm_dirs="$withval $_x_ac_slurm"]) 30 | 31 | AC_ARG_ENABLE( 32 | [nativeSlurm], AS_HELP_STRING([--disable-nativeSlurm], [Disable if slurm is working with alps]) 33 | ) 34 | 35 | AC_CACHE_CHECK( 36 | [for slurm installation], 37 | [x_ac_cv_slurm_dir], 38 | [ 39 | for d in $_x_ac_slurm_dirs; do 40 | test -d "$d" || continue 41 | test -d "$d/include" || continue 42 | test -f "$d/include/slurm/slurm.h" || continue 43 | for bit in $_x_ac_slurm_libs; do 44 | test -d "$d/$bit" || continue 45 | 46 | _x_ac_slurm_libs_save="$LIBS" 47 | LIBS="-L$d/$bit -lslurm $LIBS" 48 | AC_LINK_IFELSE( 49 | [AC_LANG_CALL([], slurm_ping)], 50 | AS_VAR_SET(x_ac_cv_slurm_dir, $d)) 51 | LIBS="$_x_ac_slurm_libs_save" 52 | test -n "$x_ac_cv_slurm_dir" && break 53 | done 54 | test -n "$x_ac_cv_slurm_dir" && break 55 | done 56 | ]) 57 | 58 | if test -z "$x_ac_cv_slurm_dir"; then 59 | AC_MSG_WARN([unable to locate slurm installation]) 60 | else 61 | SLURM_LIBS="-lslurm" 62 | SLURM_CPPFLAGS="-I$x_ac_cv_slurm_dir/include" 63 | SLURM_DIR="$x_ac_cv_slurm_dir" 64 | if test "$ac_with_rpath" = "yes"; then 65 | SLURM_LDFLAGS="-Wl,-rpath -Wl,$x_ac_cv_slurm_dir/$bit -L$x_ac_cv_slurm_dir/$bit" 66 | else 67 | SLURM_LDFLAGS="-L$x_ac_cv_slurm_dir/$bit" 68 | fi 69 | fi 70 | 71 | SLURM_NATIVE_SLURM=0 72 | AS_IF([test "x$enable_nativeSlurm" != "xno"], [ 73 | SLURM_NATIVE_SLURM=1 74 | ]) 75 | 76 | AC_SUBST(SLURM_LIBS) 77 | AC_SUBST(SLURM_CPPFLAGS) 78 | AC_SUBST(SLURM_LDFLAGS) 79 | AC_SUBST(SLURM_DIR) 80 | AC_SUBST(SLURM_NATIVE_SLURM) 81 | 82 | AM_CONDITIONAL(WITH_SLURM, test -n "$x_ac_cv_slurm_dir") 83 | ]) 84 | -------------------------------------------------------------------------------- /src/shifter_mem.c: -------------------------------------------------------------------------------- 1 | /** @file shifter_mem.h 2 | * @brief Core include for heap operations 3 | * 4 | * @author Douglas M. Jacobsen 5 | */ 6 | 7 | /* Shifter, Copyright (c) 2017, The Regents of the University of California, 8 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 9 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of the University of California, Lawrence Berkeley 19 | * National Laboratory, U.S. Dept. of Energy nor the names of its 20 | * contributors may be used to endorse or promote products derived from this 21 | * software without specific prior written permission. 22 | * 23 | * See LICENSE for full text. 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | void *shifter_realloc(void *ptr, size_t alloc_size, const char *file, int line, 32 | const char *function) 33 | { 34 | void *ret = realloc(ptr, alloc_size); 35 | if (ret == NULL) { 36 | fprintf(stderr, "FAILED to allocate memory at %s: %d in %s\n", 37 | file, line, function); 38 | abort(); 39 | } 40 | return ret; 41 | } 42 | 43 | void *shifter_malloc(size_t alloc_size, const char *file, int line, 44 | const char *function) 45 | { 46 | void *ret = malloc(alloc_size); 47 | if (ret == NULL) { 48 | fprintf(stderr, "FAILED to allocate memory at %s: %d in %s\n", 49 | file, line, function); 50 | abort(); 51 | } 52 | return ret; 53 | } 54 | 55 | char *shifter_strdup(const char *input, const char *file, int line, 56 | const char *function) 57 | { 58 | char *ret = strdup(input); 59 | if (ret == NULL) { 60 | fprintf(stderr, "FAILED to duplicate string at %s: %d in %s\n", 61 | file, line, function); 62 | abort(); 63 | } 64 | return ret; 65 | } 66 | 67 | char *shifter_strndup(const char *input, size_t len, const char *file, int line, 68 | const char *function) 69 | { 70 | char *ret = strndup(input, len); 71 | if (ret == NULL) { 72 | fprintf(stderr, "FAILED to duplicate string at %s: %d in %s\n", 73 | file, line, function); 74 | abort(); 75 | } 76 | return ret; 77 | } 78 | -------------------------------------------------------------------------------- /extra/setup_udiRoot_etc_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ## Shifter, Copyright (c) 2015, The Regents of the University of California, 3 | ## through Lawrence Berkeley National Laboratory (subject to receipt of any 4 | ## required approvals from the U.S. Dept. of Energy). All rights reserved. 5 | ## 6 | ## Redistribution and use in source and binary forms, with or without 7 | ## modification, are permitted provided that the following conditions are met: 8 | ## 1. Redistributions of source code must retain the above copyright notice, 9 | ## this list of conditions and the following disclaimer. 10 | ## 2. Redistributions in binary form must reproduce the above copyright notice, 11 | ## this list of conditions and the following disclaimer in the documentation 12 | ## and/or other materials provided with the distribution. 13 | ## 3. Neither the name of the University of California, Lawrence Berkeley 14 | ## National Laboratory, U.S. Dept. of Energy nor the names of its 15 | ## contributors may be used to endorse or promote products derived from this 16 | ## software without specific prior written permission. 17 | ## 18 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | ## POSSIBILITY OF SUCH DAMAGE. 29 | ## 30 | ## You are under no obligation whatsoever to provide any bug fixes, patches, or 31 | ## upgrades to the features, functionality or performance of the source code 32 | ## ("Enhancements") to anyone; however, if you choose to make your Enhancements 33 | ## available either publicly, or directly to Lawrence Berkeley National 34 | ## Laboratory, without imposing a separate written license agreement for such 35 | ## Enhancements, then you hereby grant the following license: a non-exclusive, 36 | ## royalty-free perpetual license to install, use, modify, prepare derivative 37 | ## works, incorporate into other computer software, distribute, and sublicense 38 | ## such enhancements or derivative works thereof, in binary and source code 39 | ## form. 40 | 41 | mkdir -m 755 -p $PREFIX/etc_files 42 | getent passwd > $PREFIX/etc_files/passwd 43 | getent group > $PREFIX/etc_files/group 44 | #cp /etc/resolv.conf $PREFIX/etc_files/resolv.conf 45 | cp /etc/clustername $PREFIX/etc_files/clustername 46 | cp -rp etc_static/* $PREFIX/etc_files 47 | -------------------------------------------------------------------------------- /doc/import.md: -------------------------------------------------------------------------------- 1 | # Importing Images (beta) 2 | 3 | While Shifter is primarily designed to run images built using Docker, it also 4 | supports directly importing pre-prepared images. Since some sites may not 5 | wish to support this or limit its usage, it requires extra configuration. 6 | 7 | ## Security Considerations 8 | 9 | Before enabling this feature, the administrator should understand the 10 | increased risks of allowing direct imports of images perpared outside 11 | of Shifter. The Shifter gateway should not be capable 12 | of creating images that contain security attributes. This helps minimize 13 | the risk of images introducing additional security risks. If you enable 14 | the importing of images, you should take extra precautions in how images 15 | are prepared and who you trust to import them. Images should ideally 16 | be prepared as a unprivileged user and the -no-xattrs flag should be 17 | passed to the mksquashfs command to mitigate the risks of security attributes 18 | being included in the image. When using the workload manager integration 19 | (e.g. Slurm plugin), it is especially critical that direct 20 | import users block xattrs since the mounts may be visible 21 | to processes running outside the runtime. 22 | 23 | ## Approach 24 | 25 | Importing images works by copying a pre-prepared image into the shared 26 | location, generating a pseudo-hash for the image, and adding an entry in 27 | the Shifter image list. 28 | 29 | ## Enabling support 30 | 31 | To enable support, add an "ImportUsers" parameters into the top section of 32 | the imagemanager.json file. This can be a list of user names (in JSON list 33 | format) or the keyword "all". For example: 34 | 35 | ~~~~ 36 | ... 37 | "ExpandDirectory": "/tmp/images/expand/", 38 | "ImportUsers":"all" 39 | "Locations": { 40 | ... 41 | ~~~~ 42 | 43 | The fasthash script needs to be installed as `fasthash` in a location on 44 | the search path for the image gateway for local mode or in the search path 45 | on the remote system for remote mode. This script generates a pseudo-hash 46 | for the image based on the contents of the image. 47 | 48 | 49 | ## Usage 50 | 51 | The user issuing the import most have the squashed image in a location that is 52 | accessible by the shifter user (e.g. the account used to run the gateway). 53 | 54 | The command line tools do not currently support import. So a curl command 55 | must be issued. Here is an example of an import command to import the squashfs image 56 | located at /tmp/image.squashfs and call it 57 | load_test:v1 in Shifter. 58 | 59 | ~~~~bash 60 | curl -d '{"filepath":"/tmp/myimage.squashfs","format":"squashfs"}' \ 61 | -H "authentication: $(munge -n)" \ 62 | http://:5000/api/doimport/mycluster/custom/load_test:v1/ 63 | ~~~~ 64 | 65 | Once an image is imported, it is run with Shifter like other images. 66 | The only difference is the type is "custom" instead of the default "docker". 67 | 68 | ```bash 69 | shifter --image=custom:load_test:v1 /bin/app 70 | ``` 71 | -------------------------------------------------------------------------------- /doc/modules.rst: -------------------------------------------------------------------------------- 1 | Shifter Modules 2 | =============== 3 | 4 | To adapt containers to a particular system and meet specific user needs, 5 | Shifter provides sites the ability to configure "modules" which more flexibly 6 | implement the the globally applied modifications that Shifter can perform 7 | for all container invocations. 8 | 9 | A Shifter module allows specific content to be injected into the container, 10 | environment variables to be manipulated, and hooks both as root during 11 | container instantiation (not _within_ the container), and as the user 12 | (in the container) immediately before process start. The capabilities 13 | allow a site to customize all user containers and provide local support for 14 | a variety of system capabilities, and then give the users the option to use 15 | the local support (enable the module) or disable it if their container has 16 | other needs. 17 | 18 | Example Modules: 19 | ================ 20 | 21 | CVMFS at NERSC: 22 | --------------- 23 | NERSC makes CVMFS available on the /cvmfs_nfs mount point, where cvmfs is 24 | made available via NFS and aggressively cached in a number of ways. 25 | 26 | If a user wants to use it in their container, a simple module could be: 27 | 28 | udiRoot.conf: 29 | module_cvmfs_siteFs = /cvmfs_nfs:/cvmfs 30 | module_cvmfs_siteEnv = SHIFTER_MODULE_CVMFS=1 31 | 32 | Then the shifter invocation would be: 33 | 34 | shifter --image= --module=cvmfs ... 35 | 36 | This can also be achieved with volume mounts, but the module system allows 37 | a user to _avoid_ getting cvmfs, unless they want it. 38 | 39 | Cray mpich Support 40 | ================== 41 | 42 | Cray mpich support makes use of the ABI compatibility interface. If a user has 43 | an application linked against vanilla mpich, then the Cray version can be 44 | interposed via linking operations. 45 | 46 | Thus if the site prepares a copy of the CrayPE environment for use by shifter 47 | (using the prep_cray_mpi_libs.py script in the "extra" directory of the shifter 48 | distribution), then uses the copyPath (or siteFs) mechanism to inject those 49 | libraries into the container, and finally uses LD_LIBRARY_PATH to force the 50 | application to see the new version, then the user can use the same container on 51 | a variety of systems. 52 | 53 | udiRoot.conf: 54 | module_mpich_copyPath = /shared/shifter/modules/mpich 55 | module_mpich_siteEnvPrepend = LD_LIBRARY_PATH=/opt/udiImage/modules/mpich/lib64 56 | module_mpich_userhook = /opt/udiImage/modules/mpich/bin/init.sh 57 | 58 | If the user prefers their own mpich version, and wants to make use of the 59 | shifter ssh interface, then they can avoid using the mpich module. If the site 60 | makes the mpich module default, the user can still disable it with by specifying 61 | "--module=none", which turns off all modules. 62 | 63 | The userhook script above is executed immediately prior to the user process 64 | being executed and can be used to validate that the application in the 65 | container is compatible with the MPI libraries being injected. 66 | 67 | -------------------------------------------------------------------------------- /wlm_integration/slurm/wrapper.h: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of the University of California, Lawrence Berkeley 13 | National Laboratory, U.S. Dept. of Energy nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | See LICENSE for full text. 18 | */ 19 | 20 | #ifndef __SHIFTERSPANK_WRAPPER 21 | #define __SHIFTERSPANK_WRAPPER 22 | 23 | #ifndef _GNU_SOURCE 24 | #define _GNU_SOURCE 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | int wrap_spank_setenv(shifterSpank_config *, const char *envname, 37 | const char *value, int overwrite); 38 | 39 | int wrap_spank_job_control_setenv(shifterSpank_config *, const char *envname, 40 | const char *value, int overwrite); 41 | 42 | int wrap_spank_get_jobid(shifterSpank_config *, uint32_t *job); 43 | int wrap_spank_get_uid(shifterSpank_config *, uid_t *uid); 44 | int wrap_spank_get_gid(shifterSpank_config *, gid_t *gid); 45 | int wrap_spank_get_stepid(shifterSpank_config *, uint32_t *stepid); 46 | int wrap_spank_get_stepid_noconfig(void *, uint32_t *stepid); 47 | int wrap_spank_get_supplementary_gids(shifterSpank_config *, gid_t **gids, int *ngids); 48 | void wrap_spank_log_error(const char *msg); 49 | void wrap_spank_log_info(const char *msg); 50 | void wrap_spank_log_verbose(const char *msg); 51 | void wrap_spank_log_debug(const char *msg); 52 | 53 | int wrap_spank_stepd_connect(shifterSpank_config *ssconfig, char *dir, 54 | char *hostname, uint32_t jobid, uint32_t stepid, uint16_t *protocol); 55 | int wrap_spank_stepd_add_extern_pid(shifterSpank_config *ssconfig, 56 | uint32_t stepd_fd, uint16_t protocol, pid_t pid); 57 | int wrap_spank_extra_job_attributes(shifterSpank_config *ssconfig, 58 | uint32_t jobid, 59 | char **nodelist, 60 | size_t *nnodes, 61 | size_t *tasksPerNode, 62 | uint16_t *shared); 63 | 64 | int wrap_force_arg_parse(shifterSpank_config *ssconfig); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /imagegw/shifter_imagegw/tarfilemp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This is a monkey patch to address an issue in tarfile handling xattr. 3 | Details of this can be found here. 4 | 5 | https://github.com/docker/docker-registry/pull/381 6 | 7 | This is __proc_pax from ./Lib/tarfile.py from v2.7.6 8 | catching raw (non-utf8) bytes to support some xattr headers in tar archives 9 | 10 | This is for the use-case of reading the tar archive, not for the use case of 11 | interacting with inodes on the filesystem that have xattr's. 12 | -- vbatts 13 | ''' 14 | 15 | import re 16 | import tarfile 17 | 18 | 19 | def _proc_pax(self, filetar): 20 | """Process an extended or global header as described in 21 | POSIX.1-2001. 22 | """ 23 | # Read the header information. 24 | buf = filetar.fileobj.read(self._block(self.size)) 25 | 26 | # A pax header stores supplemental information for either 27 | # the following file (extended) or all following files 28 | # (global). 29 | if self.type == tarfile.XGLTYPE: 30 | pax_headers = filetar.pax_headers 31 | else: 32 | pax_headers = filetar.pax_headers.copy() 33 | 34 | # Parse pax header information. A record looks like that: 35 | # "%d %s=%s\n" % (length, keyword, value). length is the size 36 | # of the complete record including the length field itself and 37 | # the newline. keyword and value are both UTF-8 encoded strings. 38 | regex = re.compile(r"(\d+) ([^=]+)=", re.U) 39 | pos = 0 40 | while True: 41 | match = regex.match(buf, pos) 42 | if not match: 43 | break 44 | 45 | length, keyword = match.groups() 46 | length = int(length) 47 | value = buf[match.end(2) + 1:match.start(1) + length - 1] 48 | 49 | try: 50 | keyword = keyword.decode("utf8") 51 | except Exception: 52 | # just leave the raw bytes 53 | pass 54 | 55 | try: 56 | value = value.decode("utf8") 57 | except Exception: 58 | # just leave the raw bytes 59 | pass 60 | 61 | pax_headers[keyword] = value 62 | pos += length 63 | 64 | # Fetch the next header. 65 | try: 66 | next = self.fromtarfile(filetar) 67 | except tarfile.HeaderError: 68 | raise tarfile.SubsequentHeaderError("missing or bad subsequent header") 69 | 70 | if self.type in (tarfile.XHDTYPE, tarfile.SOLARIS_XHDTYPE): 71 | # Patch the TarInfo object with the extended header info. 72 | next._apply_pax_info(pax_headers, filetar.encoding, filetar.errors) 73 | next.offset = self.offset 74 | 75 | if "size" in pax_headers: 76 | # If the extended header replaces the size field, 77 | # we need to recalculate the offset where the next 78 | # header starts. 79 | offset = next.offset_data 80 | if next.isreg() or next.type not in tarfile.SUPPORTED_TYPES: 81 | offset += next._block(next.size) 82 | filetar.offset = offset 83 | 84 | return next 85 | 86 | 87 | tarfile.TarInfo._proc_pax = _proc_pax 88 | 89 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/test_shifterSpank_cgroup.cpp: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2016, The Regents of the University of California, 2 | through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 3. Neither the name of the University of California, Lawrence Berkeley 13 | National Laboratory, U.S. Dept. of Energy nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | See LICENSE for full text. 18 | */ 19 | 20 | #include "shifterSpank.h" 21 | #include "utility.h" 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | using namespace std; 31 | 32 | TEST_GROUP(shifterSpankCgroupGroup) { 33 | char *tmpDir; 34 | char cwd[PATH_MAX]; 35 | vector tmpDirs; 36 | vector tmpFiles; 37 | 38 | void setup() { 39 | getcwd(cwd, PATH_MAX); 40 | tmpDir = strdup("/tmp/shifter.XXXXXX"); 41 | if (mkdtemp(tmpDir) == NULL) { 42 | fprintf(stderr, "WARNING mkdtemp failed, some tests will crash.\n"); 43 | } 44 | } 45 | 46 | void teardown() { 47 | for (size_t idx = 0; idx < tmpFiles.size(); idx++) { 48 | unlink(tmpFiles[idx].c_str()); 49 | } 50 | tmpFiles.clear(); 51 | for (size_t idx = 0; idx < tmpDirs.size(); idx++) { 52 | rmdir(tmpDirs[idx].c_str()); 53 | } 54 | tmpDirs.clear(); 55 | chdir(cwd); 56 | rmdir(tmpDir); 57 | free(tmpDir); 58 | } 59 | }; 60 | 61 | int doNothingWithPath(shifterSpank_config *config, const char *path, void *data) { 62 | fprintf(stderr, "CGROUP PATH: %s\n", path); 63 | return 0; 64 | } 65 | 66 | TEST(shifterSpankCgroupGroup, generateCgroupPath) { 67 | shifterSpank_config *config = shifterSpank_init(NULL, 0, NULL, 0); 68 | 69 | char *path = setup_memory_cgroup(config, 10, 1000, doNothingWithPath, NULL); 70 | CHECK(path == NULL) 71 | shifterSpank_config_free(config); 72 | 73 | char *args[] = { 74 | alloc_strgenf("memory_cgroup=%s", tmpDir), 75 | NULL 76 | }; 77 | 78 | config = shifterSpank_init(NULL, 1, args, 0); 79 | path = setup_memory_cgroup(config, 10, 1000, doNothingWithPath, NULL); 80 | CHECK(path != NULL); 81 | fprintf(stderr, "GOT PATH: %s\n", path); 82 | } 83 | 84 | int main(int argc, char** argv) { 85 | return CommandLineTestRunner::RunAllTests(argc, argv); 86 | } 87 | -------------------------------------------------------------------------------- /imagegw/shifter_imagegw/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 4 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 5 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 1. Redistributions of source code must retain the above copyright notice, 10 | # this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright notice, 12 | # this list of conditions and the following disclaimer in the documentation 13 | # and/or other materials provided with the distribution. 14 | # 3. Neither the name of the University of California, Lawrence Berkeley 15 | # National Laboratory, U.S. Dept. of Energy nor the names of its 16 | # contributors may be used to endorse or promote products derived from this 17 | # software without specific prior written permission.` 18 | # 19 | # See LICENSE for full text. 20 | 21 | """ 22 | ------- 23 | util.py 24 | ------- 25 | 26 | Collection of functions that provide miscellaneous utilities 27 | 28 | """ 29 | 30 | import os 31 | import stat 32 | import shutil 33 | 34 | 35 | def program_exists(program): 36 | """ 37 | Checks if a program (bin) exists and raises an exception if not found. 38 | """ 39 | if which(program) is None: 40 | raise IOError('Binary %s not found or not executable.' % str(program)) 41 | return True 42 | 43 | 44 | def which(program): 45 | """ 46 | Sees if a program (bin) is executable and returns the path 47 | Borrowed from: 48 | http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python 49 | """ 50 | def is_exe(fpath): 51 | """ 52 | checks if a given path exists and that the file is executable 53 | """ 54 | return os.path.exists(fpath) and os.access(fpath, os.X_OK) 55 | 56 | def ext_candidates(fpath): 57 | """ 58 | returns possible names for the executable based on the OS standards 59 | """ 60 | yield fpath 61 | for ext in os.environ.get("PATHEXT", "").split(os.pathsep): 62 | yield fpath + ext 63 | 64 | fpath = os.path.split(program)[0] 65 | if fpath: 66 | if is_exe(program): 67 | return program 68 | else: 69 | for path in os.environ["PATH"].split(os.pathsep): 70 | exe_file = os.path.join(path, program) 71 | for candidate in ext_candidates(exe_file): 72 | if is_exe(candidate): 73 | return candidate 74 | 75 | return None 76 | 77 | def rmtree(path): 78 | def remove_readonly(func, path, _): 79 | "Clear the readonly bit and reattempt the removal" 80 | parent = os.path.dirname(path) 81 | os.chmod(parent, stat.S_IRWXU) 82 | if not os.path.islink(path): 83 | os.chmod(path, stat.S_IRWXU) 84 | func(path) 85 | 86 | shutil.rmtree(path, onerror=remove_readonly) 87 | -------------------------------------------------------------------------------- /doc/api/authentication.rst: -------------------------------------------------------------------------------- 1 | Authentication to the image gateway 2 | =================================== 3 | 4 | The image gateway requires authentication for all interactions. The purpose 5 | of the authentication in most cases to ensure the request came from the target 6 | platform (e.g., mycluster), and from a known user id on that system. To that 7 | end, the HTTP header must include an "authentication" field. 8 | 9 | The value of that field must be a munge-encoded message signed with the same 10 | munge credential as is configured for the target platform on the imagegw 11 | server system. For basic requests, it may be sufficient to simply munge encode 12 | an empty message (e.g., ""). 13 | 14 | The image gateway may, from time to time perform privileged operations as a 15 | result of the API calls (e.g., pull a privileged image from DockerHub). In 16 | that case the originating request must include a more extensive 17 | "authentication" header which includes the munge encrypted credentials 18 | (username and password) for the target platform (at least). 19 | 20 | Format of the "authentication" HTTP header 21 | ------------------------------------------ 22 | * _Non-privileged requests:_ munge encoded empty string 23 | * _Privileged requests:_ munge encoded JSON document including one or more 24 | credentials for the remote image resources 25 | 26 | JSON document format: 27 | ********************* 28 | 29 | { 30 | "authorized_locations": { 31 | "default":"username:password", 32 | "otherloc":"username:password", 33 | ... 34 | } 35 | } 36 | 37 | Specifications for authorized locations 38 | --------------------------------------- 39 | The credentials provided to the image gateway are for the remote locations. 40 | The identifier in the "authorized_locations" hash must match the locations in 41 | the image_manager.json configuration. The only exception to this is that it 42 | may be difficult for the client to determine which location a particular 43 | request may be routed to, owing to that, and the fact that the client can not 44 | know what the "default" remote location for the image manager is, a special 45 | "default" location may be specified which the image manager can use for 46 | interacting with the default location (if the default loation is selected) so 47 | long as a credential for a more specific name for the default loation is not 48 | provided. 49 | 50 | e.g., if the "default" location for the imagegw is registry-1.docker.io, and 51 | a credential is provided by the client for "registry-1.docker.io", then that 52 | credential must be used by the imagegw when interacting with 53 | registry-1.docker.io; if, however, only a "default" credential is provided, 54 | and "registry-1.docker.io" happens to be the default location, then the 55 | "default" credential may be used when interacting with registry-1.docker.io. 56 | 57 | The client may provide just the needed credential or many different credentials 58 | and the image manager is responsible to parse the data structure and determine 59 | which credential is most appropriate given the request. This is allowed 60 | because it may be challenging for the client to determine which location will 61 | be selected by the imagegw, since the configuration of the imagegw may not 62 | be accessible by the client. 63 | -------------------------------------------------------------------------------- /extra/oscap-scan.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | import subprocess 6 | import logging 7 | import glob 8 | import select 9 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 10 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 11 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 12 | # 13 | # Redistribution and use in source and binary forms, with or without 14 | # modification, are permitted provided that the following conditions are met: 15 | # 1. Redistributions of source code must retain the above copyright notice, 16 | # this list of conditions and the following disclaimer. 17 | # 2. Redistributions in binary form must reproduce the above copyright notice, 18 | # this list of conditions and the following disclaimer in the documentation 19 | # and/or other materials provided with the distribution. 20 | # 3. Neither the name of the University of California, Lawrence Berkeley 21 | # National Laboratory, U.S. Dept. of Energy nor the names of its 22 | # contributors may be used to endorse or promote products derived from this 23 | # software without specific prior written permission.` 24 | # 25 | # See LICENSE for full text. 26 | 27 | """ 28 | Wrapper to call oscap scanner. This is still a WIP. 29 | """ 30 | 31 | 32 | def check_io(child): 33 | """ 34 | Process IO lines 35 | """ 36 | ready_to_read = select.select([child.stdout, child.stderr], 37 | [], [], 1000)[0] 38 | for io in ready_to_read: 39 | line = io.readline() 40 | print line 41 | 42 | 43 | print "Warning: This wrapper is not yet fully functional. Do not use." 44 | profiled = '/usr/share/xml/scap/ssg/content/ssg-rhel7-ds.xml' 45 | image_loc = sys.argv[1] 46 | image_id = sys.argv[2] 47 | 48 | stdout_log_level = logging.DEBUG 49 | stderr_log_level = logging.ERROR 50 | etcp = os.path.join(image_loc, 'etc') 51 | for file in os.listdir(etcp): 52 | fname = glob.glob('%s/*-release' % (etcp)) 53 | finp = open(fname[0], 'r') 54 | fcont = finp.readline() 55 | print fcont 56 | 57 | if "Ubuntu" in fcont: 58 | print "Image is Ubuntu_based" 59 | 60 | elif fcont.find("CentOS") == 0: 61 | print "Image is centos based" 62 | 63 | elif fcont.find("Fedora") == 0: 64 | print "Image is Fedora based" 65 | 66 | elif "Debian" in fcont: 67 | print "Image is Debian based" 68 | elif "Red Hat" in fcont: 69 | print "Image is Redhat Linux based" 70 | elif "Scientific" in fcont: 71 | print "Image is Scientific Linux based" 72 | else: 73 | print "Some other unsupported flavour of Scanner" 74 | 75 | 76 | command = ['oscap-chroot', image_loc, 'xccdf', 'eval', 77 | '--fetch-remote-resources', '--profile', 78 | 'xccdf_org.ssgproject.content_profile_rht-ccp', 79 | '--report', '%s_report.html' % image_id, profiled] 80 | child = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, 81 | stderr=subprocess.PIPE) 82 | log_level = {child.stdout: stdout_log_level, child.stderr: stderr_log_level} 83 | 84 | 85 | # keep checking stdout/stderr until the child exits 86 | while child.poll() is None: 87 | check_io(child) 88 | 89 | check_io(child) # check again to catch anything after the process exits 90 | 91 | sys.exit(child.wait()) 92 | -------------------------------------------------------------------------------- /doc/faq.rst: -------------------------------------------------------------------------------- 1 | Shifter Frequently Asked Questions 2 | ================================== 3 | 4 | Note that this document is a work in progress, if you don't see your question 5 | or answer, please contact shifter-hpc@googlegroups.com 6 | 7 | Do the Image Manager and Image Worker processes need to run with root privilege? 8 | -------------------------------------------------------------------------------- 9 | No. The image manager doesn't really do any real work on its own, and the 10 | image worker uses only user-space tools to construct images (in the default 11 | configuration). A trusted machine should be used to run the imagegw to ensure 12 | that images are securely imported for your site. In particular, the python 13 | and squashfs tools installations should ideally be integrated as part of the 14 | system or be installed in trusted locations. 15 | 16 | Can Shifter import Docker images with unicode filenames embedded? 17 | ----------------------------------------------------------------- 18 | Yes. If you are seeing errors similar to the following in the image gateway log 19 | then you'll need to include the provide sitecustomize.py in your python setup 20 | or just point the gateway's PYTHONPATH to include it:: 21 | 22 | [2016-08-01 09:41:20,664: ERROR/MainProcess] Task shifter_imagegw.imageworker.dopull[XXXXXXX-omitted-XXXXXXX] raised unexpected: UnicodeDecodeError('ascii', '/path/is/omitted/some\xc3\xa9_unicode', 35, 36, 'ordinal not in range(128)') 23 | Traceback (most recent call last): 24 | File "/usr/lib64/python2.6/site-packages/shifter_imagegw/imageworker.py", line 304, in dopull 25 | if not pull_image(request,updater=us): 26 | File "/usr/lib64/python2.6/site-packages/shifter_imagegw/imageworker.py", line 161, in pull_image 27 | dh.extractDockerLayers(expandedpath, dh.get_eldest(), cachedir=cdir) 28 | File "/usr/lib64/python2.6/site-packages/shifter_imagegw/dockerv2.py", line 524, in extractDockerLayers 29 | tfp.extractall(path=basePath,members=members) 30 | File "/usr/lib64/python2.6/tarfile.py", line 2036, in extractall 31 | self.extract(tarinfo, path) 32 | File "/usr/lib64/python2.6/tarfile.py", line 2073, in extract 33 | self._extract_member(tarinfo, os.path.join(path, tarinfo.name)) 34 | File "/usr/lib64/python2.6/posixpath.py", line 70, in join 35 | path += '/' + b 36 | UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 35: ordinal not in range(128) 37 | 38 | To fix this, either set PYTHONPATH to include 39 | 40 | * /usr/libexec/shifter (RedHat variants) 41 | * /usr/lib/shifter (SLES variants) 42 | 43 | In order to get the shifter sitecustomize.py into your PYTHONPATH. 44 | 45 | If that isn't appropriate for your site, then you can examine the contents of 46 | the sitecustomize.py and prepare your own that does similar. 47 | 48 | Can Shifter use a proxy to access registries 49 | -------------------------------------------- 50 | Shifter does support using a proxy. This is controlled through the enviornment variables, http_proxy. 51 | This should be set to the appropriate proxy (e.g. https://myproxy.me.org). Domains can be excluded 52 | by setting no_proxy to a comma separated list of domains to exclude. A SOCKS proxy can be used for 53 | all connections by setting all_proxy to the socks proxy URL. 54 | -------------------------------------------------------------------------------- /extra/CI/integration_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | CIDIR="$BUILDDIR/extra/CI" 5 | if [[ ! -e "$CIDIR" ]]; then 6 | echo "No CI dir found!" 7 | exit 1 8 | fi 9 | 10 | PYDIR= 11 | for libpath in lib lib64; do 12 | for pypath in python2.6 python2.7 python3.7 python3.8; do 13 | for packagepath in site-packages dist-packages; do 14 | if [[ -e "/usr/$libpath/$pypath/$packagepath/shifter_imagegw" ]]; then 15 | PYDIR="/usr/$libpath/$pypath/$packagepath" 16 | fi 17 | done 18 | done 19 | done 20 | if [[ -z "$PYDIR" ]]; then 21 | echo "FAILED to find python dir" 22 | exit 1 23 | fi 24 | 25 | LIBEXECDIR= 26 | for path in /usr/libexec/shifter /usr/lib/shifter; do 27 | if [[ -e $path ]]; then 28 | LIBEXECDIR=$path 29 | fi 30 | done 31 | if [[ -z "$LIBEXECDIR" ]]; then 32 | echo "FAILED to find shifter libexec dir" 33 | exit 1 34 | fi 35 | 36 | export PYTHONPATH="$LIBEXECDIR:$PYDIR" 37 | 38 | echo "Setting up imagegw configuration" 39 | sudo cp "$CIDIR/imagemanager.json" /etc/shifter 40 | 41 | me=$(whoami) 42 | for i in /var/log/shifter_imagegw /images; do 43 | sudo mkdir -p $i 44 | sudo chown -R $me $i 45 | done 46 | 47 | echo "setting up munge" 48 | if [[ -e /usr/sbin/create-munge-key ]]; then 49 | sudo /usr/sbin/create-munge-key -f 50 | fi 51 | sudo service munge start 52 | 53 | echo "Starting imagegw api" 54 | python -m shifter_imagegw.api & 55 | 56 | echo "setting up base config" 57 | sudo /bin/bash -c "cat /etc/shifter/udiRoot.conf.example | \ 58 | sed 's|etcPath=.*|etcPath=/etc/shifter/shifter_etc_files|g' | \ 59 | sed 's|imageGateway=.*|imageGateway=http://localhost:8000|g' \ 60 | > /etc/shifter/udiRoot.conf" 61 | 62 | sudo mkdir -p /etc/shifter/shifter_etc_files 63 | sudo /bin/bash -c "getent passwd > /etc/shifter/shifter_etc_files/passwd" 64 | sudo /bin/bash -c "getent group > /etc/shifter/shifter_etc_files/group" 65 | sudo touch /etc/shifter/shifter_etc_files/shadow 66 | sudo cp "$BUILDDIR/etc_files/nsswitch.conf" /etc/shifter/shifter_etc_files/nsswitch.conf 67 | 68 | cat /etc/shifter/udiRoot.conf | egrep -v '^#' 69 | sudo mkdir -p $LIBEXECDIR/opt/udiImage 70 | 71 | echo "creating dummy command line tools for GPU support integration tests" 72 | sudo touch /bin/nvidia-smi 73 | sudo chmod 755 /bin/nvidia-smi 74 | sudo touch /bin/nvidia-modprobe 75 | sudo chmod 755 /bin/nvidia-modprobe 76 | 77 | ## need to sleep a bit to let gunicorn get started 78 | sleep 2 79 | 80 | 81 | echo "Pull Image" 82 | shifterimg pull ubuntu:16.04 83 | shifterimg lookup ubuntu:16.04 84 | ls -l /images 85 | shifter --image=ubuntu:16.04 echo test 86 | 87 | echo "var/tmp exists" 88 | ls -ld /var/tmp 89 | 90 | echo "Ensure container gets basic setup" 91 | python $CIDIR/integration/test_shifterConfig_format.py ubuntu:16.04 92 | 93 | echo "Check capabilities and bounding sets" 94 | python $CIDIR/integration/test_capabilities.py ubuntu:16.04 95 | 96 | echo "Check /etc/mtab symlink" 97 | python $CIDIR/integration/test_etcmtab.py ubuntu:16.04 98 | 99 | echo "Check /etc/passwd, /etc/group generation" 100 | python $CIDIR/integration/test_etcpasswd.py ubuntu:16.04 101 | 102 | #echo "Test GPU support" 103 | #python $CIDIR/integration/test_gpu_support.py ubuntu:16.04 104 | -------------------------------------------------------------------------------- /imagegw/imagecli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Shifter, Copyright (c) 2015, The Regents of the University of California, 3 | # through Lawrence Berkeley National Laboratory (subject to receipt of any 4 | # required approvals from the U.S. Dept. of Energy). All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright notice, 9 | # this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 3. Neither the name of the University of California, Lawrence Berkeley 14 | # National Laboratory, U.S. Dept. of Energy nor the names of its 15 | # contributors may be used to endorse or promote products derived from this 16 | # software without specific prior written permission.` 17 | # 18 | # See LICENSE for full text. 19 | 20 | """ 21 | Basic CLI tool to talk to the image manager. This is not well supported. 22 | """ 23 | 24 | import json 25 | import os 26 | import sys 27 | import requests 28 | from shifter_imagegw.munge import munge 29 | 30 | SERVER = os.environ['IMAGEGW'] 31 | MUNGEENV = os.environ['MUNGE'] 32 | 33 | def usage(program): 34 | """ usage line """ 35 | print "usage: %s system image" % (program) 36 | sys.exit(1) 37 | 38 | def main(): 39 | """ main """ 40 | program = sys.argv.pop(0) 41 | if len(sys.argv) < 1: 42 | usage(program) 43 | com = sys.argv.pop(0) 44 | if MUNGEENV == "1": 45 | mungetok = munge("test") 46 | elif os.path.exists(MUNGEENV): 47 | with open(MUNGEENV) as mungec: 48 | mungetok = mungec.read() 49 | else: 50 | mungetok = MUNGEENV 51 | url = "http://%s/api"%(SERVER) 52 | 53 | if com == 'lookup' and len(sys.argv) >= 2: 54 | (system, image) = sys.argv[0:2] 55 | header = {'authentication': mungetok.strip()} 56 | uri = "%s/lookup/%s/docker/%s/" % (url, system, image) 57 | req = requests.get(uri, headers=header) 58 | print req.text 59 | elif com == 'list' and len(sys.argv) >= 1: 60 | system = sys.argv[0] 61 | header = {'authentication': mungetok.strip()} 62 | uri = "%s/list/%s/" % (url, system) 63 | req = requests.get(uri, headers=header) 64 | if req.status_code != 200: 65 | print "List failed" 66 | sys.exit(1) 67 | resp = json.loads(req.text) 68 | for res in resp['list']: 69 | tags = res['tag'] 70 | if not isinstance(tags, list): 71 | tags = [tags] 72 | for img in tags: 73 | (image, tag) = img.split(':') 74 | print '%-25.25s %-20.10s %-12.12s %-10.10s' % \ 75 | (image, tag, req['id'], req['itype']) 76 | elif com == 'pull' and len(sys.argv) >= 2: 77 | (system, image) = sys.argv[0:2] 78 | header = {'authentication':mungetok.strip()} 79 | uri = "%s/pull/%s/docker/%s/" % (url, system, image) 80 | req = requests.post(uri, headers=header) 81 | print req.text 82 | else: 83 | usage(program) 84 | 85 | if __name__ == '__main__': 86 | main() 87 | -------------------------------------------------------------------------------- /src/unsetupRoot.c: -------------------------------------------------------------------------------- 1 | /** @file unsetupRoot.c 2 | * @brief Deconstruct a shifter image. 3 | * 4 | * @author Douglas M. Jacobsen 5 | */ 6 | 7 | /* Shifter, Copyright (c) 2015, The Regents of the University of California, 8 | * through Lawrence Berkeley National Laboratory (subject to receipt of any 9 | * required approvals from the U.S. Dept. of Energy). All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of the University of California, Lawrence Berkeley 19 | * National Laboratory, U.S. Dept. of Energy nor the names of its 20 | * contributors may be used to endorse or promote products derived from this 21 | * software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | * POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | * You are under no obligation whatsoever to provide any bug fixes, patches, or 36 | * upgrades to the features, functionality or performance of the source code 37 | * ("Enhancements") to anyone; however, if you choose to make your Enhancements 38 | * available either publicly, or directly to Lawrence Berkeley National 39 | * Laboratory, without imposing a separate written license agreement for such 40 | * Enhancements, then you hereby grant the following license: a non-exclusive, 41 | * royalty-free perpetual license to install, use, modify, prepare derivative 42 | * works, incorporate into other computer software, distribute, and sublicense 43 | * such enhancements or derivative works thereof, in binary and source code 44 | * form. 45 | */ 46 | 47 | 48 | #define _GNU_SOURCE 49 | #include 50 | #include 51 | 52 | #include "UdiRootConfig.h" 53 | #include "shifter_core.h" 54 | 55 | #include "config.h" 56 | 57 | int main(void) { 58 | UdiRootConfig udiConfig; 59 | 60 | memset(&udiConfig, 0, sizeof(UdiRootConfig)); 61 | 62 | clearenv(); 63 | setenv("PATH", "/usr/bin:/usr/sbin:/bin:/sbin", 1); 64 | 65 | if (parse_UdiRootConfig(CONFIG_FILE, &udiConfig, UDIROOT_VAL_ALL) != 0) { 66 | fprintf(stderr, "FAILED to parse udiRoot configuration. Exiting.\n"); 67 | exit(1); 68 | } 69 | 70 | destructUDI(&udiConfig, 1); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # $Id$ 4 | # $Source$ 5 | # 6 | # Run this script to generate aclocal.m4, config.h.in, 7 | # Makefile.in's, and ./configure... 8 | # 9 | # To specify extra flags to aclocal (include dirs for example), 10 | # set ACLOCAL_FLAGS 11 | # 12 | 13 | DIE=0 14 | 15 | # minimum required versions of autoconf/automake/libtool: 16 | ACMAJOR=2 17 | ACMINOR=59 18 | 19 | AMMAJOR=1 20 | AMMINOR=10 21 | AMPATCH=1 22 | 23 | LTMAJOR=1 24 | LTMINOR=5 25 | LTPATCH=8 26 | 27 | (autoconf --version 2>&1 | \ 28 | perl -n0e "(/(\d+)\.(\d+)/ && \$1>=$ACMAJOR && \$2>=$ACMINOR) || exit 1") || { 29 | echo 30 | echo "Error: You must have 'autoconf' version $ACMAJOR.$ACMINOR or greater" 31 | echo "installed to run $0. Get the latest version from" 32 | echo "ftp://ftp.gnu.org/pub/gnu/autoconf/" 33 | echo 34 | NO_AUTOCONF=yes 35 | DIE=1 36 | } 37 | 38 | amtest=" 39 | if (/(\d+)\.(\d+)((-p|\.)(\d+))*/) { 40 | exit 1 if (\$1 < $AMMAJOR || \$2 < $AMMINOR); 41 | exit 0 if (\$2 > $AMMINOR); 42 | exit 1 if (\$5 < $AMPATCH); 43 | }" 44 | 45 | (automake --version 2>&1 | perl -n0e "$amtest" ) || { 46 | echo 47 | echo "Error: You must have 'automake' version $AMMAJOR.$AMMINOR.$AMPATCH or greater" 48 | echo "installed to run $0. Get the latest version from" 49 | echo "ftp://ftp.gnu.org/pub/gnu/automake/" 50 | echo 51 | NO_AUTOCONF=yes 52 | DIE=1 53 | } 54 | 55 | lttest=" 56 | if (/(\d+)\.(\d+)((-p|\.)(\d+))*/) { 57 | exit 1 if (\$1 < $LTMAJOR); 58 | exit 1 if (\$1 == $LTMAJOR && \$2 < $LTMINOR); 59 | exit 1 if (\$1 == $LTMAJOR && \$2 == $LTMINOR && \$5 < $LTPATCH); 60 | }" 61 | 62 | (libtool --version 2>&1 | perl -n0e "$lttest" ) || { 63 | echo 64 | echo "Error: You must have 'libtool' version $LTMAJOR.$LTMINOR.$LTPATCH or greater" 65 | echo "installed to run $0. Get the latest version from" 66 | echo "ftp://ftp.gnu.org/pub/gnu/libtool/" 67 | echo 68 | DIE=1 69 | } 70 | 71 | 72 | test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { 73 | echo 74 | echo "Error: \`aclocal' appears to be missing. The installed version of" 75 | echo "\`automake' may be too old. Get the most recent version from" 76 | echo "ftp://ftp.gnu.org/pub/gnu/automake/" 77 | NO_ACLOCAL=yes 78 | DIE=1 79 | } 80 | 81 | if test $DIE -eq 1; then 82 | exit 1 83 | fi 84 | 85 | # make sure that auxdir exists 86 | mkdir auxdir 2>/dev/null 87 | 88 | # Remove config.h.in to make sure it is rebuilt 89 | rm -f config.h.in 90 | 91 | set -x 92 | rm -fr autom4te*.cache 93 | ${ACLOCAL:-aclocal} -I auxdir $ACLOCAL_FLAGS || exit 1 94 | ${LIBTOOLIZE:-libtoolize} --automake --copy --force || exit 1 95 | ${AUTOHEADER:-autoheader} || exit 1 96 | ${AUTOMAKE:-automake} --add-missing --copy --force-missing || exit 1 97 | #${AUTOCONF:-autoconf} --force --warnings=all || exit 1 98 | ${AUTOCONF:-autoconf} --force --warnings=no-obsolete || exit 1 99 | set +x 100 | 101 | if [ -e config.status ]; then 102 | echo "removing stale config.status." 103 | rm -f config.status 104 | fi 105 | if [ -e config.log ]; then 106 | echo "removing old config.log." 107 | rm -f config.log 108 | fi 109 | 110 | echo "now run ./configure to configure for your environment." 111 | echo 112 | echo "NOTE: This script has most likely just modified files that are under" 113 | echo " version control. Make sure that you really want these changes" 114 | echo " applied to the repository before you run \"git commit\"." 115 | -------------------------------------------------------------------------------- /wlm_integration/slurm/udiRoot-epilogue.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## Shifter, Copyright (c) 2015, The Regents of the University of California, 3 | ## through Lawrence Berkeley National Laboratory (subject to receipt of any 4 | ## required approvals from the U.S. Dept. of Energy). All rights reserved. 5 | ## 6 | ## Redistribution and use in source and binary forms, with or without 7 | ## modification, are permitted provided that the following conditions are met: 8 | ## 1. Redistributions of source code must retain the above copyright notice, 9 | ## this list of conditions and the following disclaimer. 10 | ## 2. Redistributions in binary form must reproduce the above copyright notice, 11 | ## this list of conditions and the following disclaimer in the documentation 12 | ## and/or other materials provided with the distribution. 13 | ## 3. Neither the name of the University of California, Lawrence Berkeley 14 | ## National Laboratory, U.S. Dept. of Energy nor the names of its 15 | ## contributors may be used to endorse or promote products derived from this 16 | ## software without specific prior written permission. 17 | ## 18 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | ## POSSIBILITY OF SUCH DAMAGE. 29 | ## 30 | ## You are under no obligation whatsoever to provide any bug fixes, patches, or 31 | ## upgrades to the features, functionality or performance of the source code 32 | ## ("Enhancements") to anyone; however, if you choose to make your Enhancements 33 | ## available either publicly, or directly to Lawrence Berkeley National 34 | ## Laboratory, without imposing a separate written license agreement for such 35 | ## Enhancements, then you hereby grant the following license: a non-exclusive, 36 | ## royalty-free perpetual license to install, use, modify, prepare derivative 37 | ## works, incorporate into other computer software, distribute, and sublicense 38 | ## such enhancements or derivative works thereof, in binary and source code 39 | ## form. 40 | 41 | jobIdRaw="$1" 42 | jobId=$( echo $jobIdRaw | awk -F. '{print $1}' ) 43 | user="$2" 44 | shift 2 45 | 46 | udiRootSetupPath=@@@PREFIX@@@ 47 | 48 | die() { 49 | local msg 50 | msg="$1" 51 | echo "$msg" 1>&2 52 | exit 1 53 | } 54 | 55 | [[ -n "$jobId" ]] || die "Job ID is undefined" 56 | [[ -n "$user" ]] || die "user is undefined" 57 | 58 | datadir="/var/run/udiRoot_jobs/$user/$jobId" 59 | 60 | [[ -d "$datadir" ]] || exit 61 | 62 | 63 | job_nodelist="$datadir/nodelist.$jobId" 64 | [[ -e "$job_nodelist" ]] && rm -f "$job_nodelist" 65 | 66 | hostname > $job_nodelist 67 | 68 | unique_nodes=$datadir/unique_nodes.$jobId 69 | cat "$job_nodelist" | sort -u > "$unique_nodes" 70 | 71 | ok=0 72 | cmdStr="${nodeContext}${udiRootSetupPath}/sbin/unsetupRoot" 73 | eval $cmdStr 74 | if [[ $? == 0 ]]; then 75 | ok=1 76 | fi 77 | 78 | if [[ "$ok" -eq 1 && -e "$datadir" && "$datadir" != "/" ]]; then 79 | rm -r "$datadir" 80 | fi 81 | exit $ret 82 | -------------------------------------------------------------------------------- /doc/sshd.rst: -------------------------------------------------------------------------------- 1 | The shifter sshd 2 | ================ 3 | 4 | The Workload Manager integration can cause an sshd to be started within each 5 | instance of the container. This feature is useful for allowing complex 6 | workflows to operate within the User Defined environment, and operate as if 7 | they were running on a cluster running the User Defined image. 8 | 9 | How to use it: User Perspective 10 | ------------------------------- 11 | To use the shifter ssh access, the "basic" way is to start a batch job 12 | specifying a shifter image. So long as your job has exclusive access to the 13 | compute nodes in its allocation, the shifter container should be setup, and 14 | be pre-loaded with the running sshd. You are the only user that can login via 15 | this sshd. 16 | 17 | Once your job is running, enter the shifter environment with the shifter 18 | command, e.g., :code:`shifter /bin/bash` 19 | 20 | Once in the shifter environment you should be able to simply `ssh` to any 21 | other node in your allocation, and remain within the container environment. 22 | 23 | Note, this works because of a special ssh configuration loaded into your 24 | container environment at runtime. If your home directory has a 25 | :code:`~/.ssh/config` it may override some of the necessary shifter sshd 26 | settings, in particular if you override IdentityFile for all hosts. 27 | 28 | With a complete implementation of the batch system integration, you should be 29 | able to get a complete listing of all the other hosts in your allocation by 30 | examining the contents of :code:`/var/hostsfile` within the shifter 31 | environment. 32 | 33 | TODO: To be continued... 34 | 35 | How to configure it: Administrator Perspective 36 | ---------------------------------------------- 37 | If you didn't disable the build of the sshd when shifter was compiled, it would 38 | be installed in the udiImage directory 39 | (:code:`%(libexec)/shifter/opt/udiImage`). The udiImage directory can be moved 40 | onto your parallel/network storage to ease maintenance. Just make sure to 41 | update the udiRoot.conf :code:`udiImagePath` to reflect the change. Under 42 | :code:`udiImage/etc` you'll find the default sshd_config and ssh_config files. 43 | The can be modified to suit your needs, however they have been pre-configured 44 | to attempt to meet most ssh needs of the shifter containers, namely: 45 | 46 | 1. Disable privileged login 47 | 2. Only allow the user to login 48 | 3. Only permit the user's udiRoot ssh key to login to the sshd 49 | 4. Intentionally omits an ssh host key as these are dynamically generated 50 | and accessed within the container environment 51 | 52 | When the container is setup, the :code:`udiImagePath` will be copied to 53 | :code:`/opt/udiImage` within the container. The ssh installation is 54 | based using this path. 55 | 56 | TODO: To be continued... 57 | 58 | How to configure it: WLM Integrator Perspective 59 | ----------------------------------------------- 60 | TODO: Not started yet. 61 | 62 | 63 | Nitty Gritty Details 64 | -------------------- 65 | TODO: Not started yet. 66 | 67 | Can I use the user sshd in Cray CLE5.2UP03 or UP04? 68 | +++++++++++++++++++++++++++++++++++++++++++++++++++ 69 | Yes, however the default environment does not (or did not) support it 70 | out-of-the-box. You'll need a few things: 71 | 72 | 1. shifter 16.08.3 or newer 73 | 2. 5.2UP04 or 5.2UP03 fully patched for the glibc issues earlier in 2016 74 | 3. A modified compute node /init 75 | 76 | The compute node /init needs to be updated to mount /dev/pts with proper 77 | options to allow pty allocation in the absence of pt_chown, e.g., replace:: 78 | 79 | mkdir -p "$udev_root/pts" 80 | mount -t devpts devpts "$udev_root/pts" 81 | 82 | with:: 83 | 84 | mkdir -p "$udev_root/pts" 85 | mount -t devpts -o gid=5,mode=620 devpts "$udev_root/pts" 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/MountList.h: -------------------------------------------------------------------------------- 1 | /* Shifter, Copyright (c) 2015, The Regents of the University of California, 2 | ## through Lawrence Berkeley National Laboratory (subject to receipt of any 3 | ## required approvals from the U.S. Dept. of Energy). All rights reserved. 4 | ## 5 | ## Redistribution and use in source and binary forms, with or without 6 | ## modification, are permitted provided that the following conditions are met: 7 | ## 1. Redistributions of source code must retain the above copyright notice, 8 | ## this list of conditions and the following disclaimer. 9 | ## 2. Redistributions in binary form must reproduce the above copyright notice, 10 | ## this list of conditions and the following disclaimer in the documentation 11 | ## and/or other materials provided with the distribution. 12 | ## 3. Neither the name of the University of California, Lawrence Berkeley 13 | ## National Laboratory, U.S. Dept. of Energy nor the names of its 14 | ## contributors may be used to endorse or promote products derived from this 15 | ## software without specific prior written permission. 16 | ## 17 | ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ## ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | ## LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | ## POSSIBILITY OF SUCH DAMAGE. 28 | ## 29 | ## You are under no obligation whatsoever to provide any bug fixes, patches, or 30 | ## upgrades to the features, functionality or performance of the source code 31 | ## ("Enhancements") to anyone; however, if you choose to make your Enhancements 32 | ## available either publicly, or directly to Lawrence Berkeley National 33 | ## Laboratory, without imposing a separate written license agreement for such 34 | ## Enhancements, then you hereby grant the following license: a non-exclusive, 35 | ## royalty-free perpetual license to install, use, modify, prepare derivative 36 | ## works, incorporate into other computer software, distribute, and sublicense 37 | ## such enhancements or derivative works thereof, in binary and source code 38 | ## form. 39 | */ 40 | 41 | #ifndef __SHFTR_MOUNTLIST_INCLUDE 42 | #define __SHFTR_MOUNTLIST_INCLUDE 43 | 44 | #ifndef _GNU_SOURCE 45 | #define _GNU_SOURCE 46 | #endif 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | #define MOUNT_ALLOC_BLOCK 10 57 | 58 | typedef enum _MountListSortOrder { 59 | MOUNT_SORT_UNSORTED = 0, 60 | MOUNT_SORT_FORWARD = 1, 61 | MOUNT_SORT_REVERSE = 2 62 | } MountListSortOrder; 63 | 64 | typedef struct _MountList { 65 | char **mountPointList; 66 | size_t capacity; 67 | size_t count; 68 | MountListSortOrder sorted; 69 | } MountList; 70 | 71 | int parse_MountList(MountList *mounts); 72 | void setSort_MountList(MountList *, MountListSortOrder); 73 | int insert_MountList(MountList *mounts, const char *mountPoint); 74 | int remove_MountList(MountList *mounts, const char *mountPoint); 75 | char **find_MountList(MountList *mounts, const char *mountPoint); 76 | char **findstartswith_MountList(MountList *mounts, const char *mountPoint); 77 | void free_MountList(MountList *mounts, int freeStruct); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /wlm_integration/slurm/test/Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS=foreign 2 | 3 | AM_CPPFLAGS = -DCONFIG_FILE=\"test_udiRoot.conf\" -DLIBEXECDIR=\"${libexecdir}/shifter\" 4 | CPPUTEST_CFLAGS = -I$(top_builddir)/dep/cpputest/include 5 | CPPUTEST_LDFLAGS = $(top_builddir)/dep/cpputest/lib*/libCppUTest.a 6 | TEST_CFLAGS = -fprofile-arcs -ftest-coverage -O0 -ggdb \ 7 | -I$(top_srcdir)/wlm_integration/slurm -I$(top_srcdir)/src \ 8 | $(AM_CPPFLAGS) $(SLURM_CPPFLAGS) $(CPPUTEST_CFLAGS) -DNO_ROOT_OWN_CHECK=1 \ 9 | -DROOTFS_TYPE="\"$(ROOTFS_TYPE)\"" 10 | TEST_LDFLAGS = $(CPPUTEST_LDFLAGS) 11 | 12 | dist_noinst_DATA = test_udiRoot.conf.in 13 | noinst_DATA = test_udiRoot.conf 14 | check_PROGRAMS = test_shifterSpank_config test_shifterSpank_util test_shifterSpank_prolog test_shifterSpank_cgroup 15 | TESTS = test_shifterSpank_config test_shifterSpank_util test_shifterSpank_prolog test_shifterSpank_cgroup 16 | 17 | test_udiRoot.conf: test_udiRoot.conf.in 18 | cat $(srcdir)/test_udiRoot.conf.in | sed "s|@@@PREFIX@@@|./|g" | sed "s|@@@CONFIG_DIR@@@|./|g" | sed "s|@@@ROOTFSTYPE@@@|$(ROOTFS_TYPE)|g" > test_udiRoot.conf 19 | chmod 644 test_udiRoot.conf 20 | 21 | 22 | test_shifterSpank_config_SOURCES = \ 23 | test_shifterSpank_config.cpp \ 24 | $(top_srcdir)/wlm_integration/slurm/shifterSpank.c \ 25 | mockwrapper.c \ 26 | $(top_srcdir)/src/UdiRootConfig.c \ 27 | $(top_srcdir)/src/utility.c \ 28 | $(top_srcdir)/src/VolumeMap.c \ 29 | $(top_srcdir)/src/ImageData.c \ 30 | $(top_srcdir)/src/shifter_core.c \ 31 | $(top_srcdir)/src/PathList.c \ 32 | $(top_srcdir)/src/MountList.c \ 33 | $(top_srcdir)/src/shifter_mem.c 34 | test_shifterSpank_config_CXXFLAGS = $(TEST_CFLAGS) 35 | test_shifterSpank_config_CFLAGS = $(TEST_CFLAGS) 36 | test_shifterSpank_config_LDFLAGS = $(TEST_LDFLAGS) 37 | 38 | test_shifterSpank_util_SOURCES = \ 39 | test_shifterSpank_util.cpp \ 40 | $(top_srcdir)/wlm_integration/slurm/shifterSpank.c \ 41 | mockwrapper.c \ 42 | $(top_srcdir)/src/UdiRootConfig.c \ 43 | $(top_srcdir)/src/utility.c \ 44 | $(top_srcdir)/src/VolumeMap.c \ 45 | $(top_srcdir)/src/ImageData.c \ 46 | $(top_srcdir)/src/shifter_core.c \ 47 | $(top_srcdir)/src/PathList.c \ 48 | $(top_srcdir)/src/MountList.c \ 49 | $(top_srcdir)/src/shifter_mem.c 50 | test_shifterSpank_util_CXXFLAGS = $(TEST_CFLAGS) 51 | test_shifterSpank_util_CFLAGS = $(TEST_CFLAGS) 52 | test_shifterSpank_util_LDFLAGS = $(TEST_LDFLAGS) 53 | 54 | test_shifterSpank_prolog_SOURCES = \ 55 | test_shifterSpank_prolog.cpp \ 56 | $(top_srcdir)/wlm_integration/slurm/shifterSpank.c \ 57 | mockwrapper.c \ 58 | $(top_srcdir)/src/UdiRootConfig.c \ 59 | $(top_srcdir)/src/utility.c \ 60 | $(top_srcdir)/src/VolumeMap.c \ 61 | $(top_srcdir)/src/ImageData.c \ 62 | $(top_srcdir)/src/shifter_core.c \ 63 | $(top_srcdir)/src/PathList.c \ 64 | $(top_srcdir)/src/MountList.c \ 65 | $(top_srcdir)/src/shifter_mem.c 66 | test_shifterSpank_prolog_CXXFLAGS = $(TEST_CFLAGS) 67 | test_shifterSpank_prolog_CFLAGS = $(TEST_CFLAGS) 68 | test_shifterSpank_prolog_LDFLAGS = $(TEST_LDFLAGS) 69 | 70 | test_shifterSpank_cgroup_SOURCES = \ 71 | test_shifterSpank_cgroup.cpp \ 72 | $(top_srcdir)/wlm_integration/slurm/shifterSpank.c \ 73 | mockwrapper.c \ 74 | $(top_srcdir)/src/UdiRootConfig.c \ 75 | $(top_srcdir)/src/utility.c \ 76 | $(top_srcdir)/src/VolumeMap.c \ 77 | $(top_srcdir)/src/ImageData.c \ 78 | $(top_srcdir)/src/shifter_core.c \ 79 | $(top_srcdir)/src/PathList.c \ 80 | $(top_srcdir)/src/MountList.c \ 81 | $(top_srcdir)/src/shifter_mem.c 82 | test_shifterSpank_cgroup_CXXFLAGS = $(TEST_CFLAGS) 83 | test_shifterSpank_cgroup_CFLAGS = $(TEST_CFLAGS) 84 | test_shifterSpank_cgroup_LDFLAGS = $(TEST_LDFLAGS) 85 | 86 | .PHONY: clean-local-check 87 | 88 | clean-local: clean-local-check 89 | clean-local-check: 90 | -rm -rf *.gcda 91 | -rm -rf *.gcno 92 | -rm -f test_udiRoot.conf 93 | --------------------------------------------------------------------------------