summaryrefslogtreecommitdiff
path: root/share/spack/docker/entrypoint.bash
blob: 98869fdfcaa8034157f4fc5567a915bd451cef75 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#! /usr/bin/env bash
#
# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

mode=oneshot

if [ "$( basename "$0" )" '=' 'spack-env' ] ; then
    mode=spackenv
elif [ "$( basename "$0" )" '=' 'docker-shell' ] ; then
    mode=dockershell
elif [ "$( basename "$0" )" '=' 'interactive-shell' ] ; then
    mode=interactiveshell
elif [ "$1" '=' 'docker-shell' ] ; then
    mode=dockershell
    shift
elif [ "$1" '=' 'interactive-shell' ] ; then
    mode=interactiveshell
    shift
fi

case "$mode" in
    "spackenv")
        # Scenario 1: Run as if the image had no ENTRYPOINT
        #
        # Necessary for use cases where the command to run and all
        # arguments must be accepted in the CMD portion. (e.g.: Gitlab CI
        # Runners)
        #
        # Roughly equivalent to
        #   docker run ... --entrypoint spack-env ... sh -c "..."
        #
        # The shell script runs with spack pre-loaded and ready to use.
        . $SPACK_ROOT/share/spack/setup-env.sh
        unset CURRENTLY_BUILDING_DOCKER_IMAGE
        exec "$@"
        ;;

    "dockershell")
        # Scenario 2: Accept shell code from a RUN command in a
        # Dockerfile
        #
        # For new Docker images that start FROM this image as its base.
        # Prepared so that subsequent RUN commands can take advantage of
        # Spack without having to manually (re)initialize.
        #
        # Example:
        #   FROM spack/centos7
        #   COPY spack.yaml .
        #   RUN spack install  # <- Spack is loaded and ready to use.
        #                      # No manual initialization necessary.
        . $SPACK_ROOT/share/spack/setup-env.sh
        exec bash -c "$*"
        ;;

    "interactiveshell")
        # Scenario 3: Run an interactive shell session with Spack
        # preloaded.
        #
        # Create a container meant for an interactive shell session.
        # Additional checks are performed to ensure that stdin is a tty
        # and additional shell completion files are sourced.  The user is
        # presented with a shell prompt from which they may issue Spack
        # commands.
        #
        # This is the default behavior when running with no CMD or
        # ENTRYPOINT overrides:
        #   docker run -it spack/centos7
        if [ -t 0 ] ; then
            . $SPACK_ROOT/share/spack/setup-env.sh
            . $SPACK_ROOT/share/spack/spack-completion.bash
            unset CURRENTLY_BUILDING_DOCKER_IMAGE
            exec bash -i
        else
            (
                echo -n "It looks like you're trying to run an"
                echo -n " intractive shell session, but either no"
                echo -n " psuedo-TTY is allocated for this container's"
                echo    " STDIN, or it is closed."
                echo

                echo -n "Make sure you run docker with the --interactive"
                echo -n " and --tty options."
                echo
            ) >&2

            exit 1
        fi
        ;;

    "oneshot")
        # Scenario 4: Run a one-shot Spack command from the host command
        # line.
        #
        # Triggered by providing arguments to `docker run`.  Arguments
        # are passed along to the container's underlying spack
        # installation, allowing users to use the image as if it were
        # spack, itself.  Pass volume mount information to `docker run`
        # to persist the effects of running in this mode.
        #
        # This is the default behavior when running with a CMD override.
        #
        # Examples:
        #   # concretize the same spec on different OSes
        #   docker run --rm spack/ubuntu-xenial spec zlib
        #   docker run --rm spack/centos7 spec zlib
        #
        #   # a "wetter" dry-run;
        #   # install a package and then throw away the results.
        #   docker run --rm spack/centos7 install libiconv
        #   docker run --rm spack/centos7 find libiconv
        #     ==> No package matches the query: libiconv
        #
        #   # use docker volumes to persist changes
        #   docker run --rm -v ...:/spack spack/centos7 install ...
        #   docker run --rm -v ...:/spack spack/centos7 install ...
        #   docker run --rm -v ...:/spack spack/centos7 install ...
        exec 3>&1
        exec 4>&2

        exec 1>&-
        exec 2>&-

        . $SPACK_ROOT/share/spack/setup-env.sh
        unset CURRENTLY_BUILDING_DOCKER_IMAGE

        exec 1>&3
        exec 2>&4

        exec 3>&-
        exec 4>&-

        spack "$@"
        exit $?
        ;;

    *)
        echo "INTERNAL ERROR - UNRECOGNIZED MODE: $mode" >&2
        exit 1
        ;;
esac