File: run-in-container

package info (click to toggle)
git-buildpackage 0.9.39
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,464 kB
  • sloc: python: 18,427; xml: 8,746; sh: 731; makefile: 139
file content (159 lines) | stat: -rwxr-xr-x 4,493 bytes parent folder | download
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/sh

set -eu

this="$(readlink -e "${0}")"

# assign defaults
project_dir="$(dirname "$(dirname "${this}")")"
debian_tag="${DEBIAN_TAG:-sid}"

usage() {
    cat << EOF
Usage: $(basename "${this}") [OPTION]... [ACTION]
Run tests or create package in a podman (or docker) container

Options:
    -h                print this usage and exit
    -C PROJECT_DIR    change to PROJECT_DIR (default: ${project_dir})
    -t DEBIAN_TAG     debian release tag (default: ${debian_tag})
    -c CONTAINER_CMD  container runner command (default: podman)

Actions:
    help       print this usage and exit
    package    create debian package artifacts
    test       run tests (default)

Example:
    $(basename "${this}") -C ~/code/git-buildpackage -t trixie package
EOF
}

die() { { echo "ERROR: ${*}"; usage; } >&2; exit 1; }

# convenience wrapper
container_build() {
    ${container_cmd} build \
        --force-rm="${DOCKER_BUILD_FORCE_RM:-false}" \
        --no-cache="${DOCKER_BUILD_NO_CACHE:-false}" \
        "${@}"
}

# take path to project dir; build docker image for base
base_build() {
    (
        cd "${project_dir}"
        [ -f .gitignore ] && cat .gitignore
        [ -f .gitmodules ] && sed -nr 's|\s+path = (.+)|\1|gp' .gitmodules
        cat <<EOF
${this##"${PWD}"/}
*.buildinfo
*.changes
*.deb
*.dsc
*.tar.xz
.dockerignore
.git*
EOF
    ) > "${project_dir}/.dockerignore"
    container_build \
        --pull="${DOCKER_BUILD_PULL:-false}" \
        --build-arg="FROM_IMAGE=debian:${debian_tag}" \
        -t "gbp-base:${debian_tag}" -f- "${project_dir}" <<'EOF'
ARG FROM_IMAGE
FROM ${FROM_IMAGE}
ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
WORKDIR /workdir/project
RUN set -euvx \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get update -y \
&& apt-get -y --no-install-recommends upgrade \
&& apt-get -y --no-install-recommends install \
build-essential devscripts equivs \
&& apt-get clean
COPY debian debian
RUN mk-build-deps -r -i debian/control -t 'apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends'
# To avoid constantly invalidating previous container layers, run the slow
# dependency installation early and copy files (along with any changed files)
# later
COPY . .
RUN groupadd luser && useradd -g luser luser && chown -R luser:luser ..
USER luser
EOF
    rm -vf "${project_dir}/.dockerignore"
}


# run tests
gbp_test() {
    base_build
    # Build another image, this time with .git so that the tests.component tests
    # aren't skipped, and with additional packages needed to run the full test
    # suite.
    container_build \
        -t "gbp-test:${debian_tag}" -f- "${project_dir}" <<EOF
FROM gbp-base:${debian_tag}
USER 0:0
RUN git config --global safe.directory '*'
VOLUME /workdir/project
RUN set -euvx \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get update -y \
&& apt-get -y --no-install-recommends upgrade \
&& apt-get -y --no-install-recommends install curl flake8 \
&& apt-get clean
EOF
    for L in C.UTF-8 C; do
        ${container_cmd} run --rm -ie"TEST_LOCALE=${L}" \
        --mount="type=bind,source=${project_dir},target=/workdir/project" \
        "gbp-test:${debian_tag}" sh <<'EOF'
set -euvx
export CI=true
make all+net
make -C docs
EOF
    done
}

# create debian package artifacts, copy to host
gbp_package() {
    base_build
    ${container_cmd} run --rm -iu0:0 \
        --mount="type=bind,source=${PWD},target=/mnt/host-volume" \
        "gbp-base:${debian_tag}" sh <<EOF
set -euvx
dpkg-buildpackage -j$(nproc) -sa -us -uc
find .. -maxdepth 1 -mindepth 1 -type f \
    -exec chown -v $(id -u):$(id -g) {} + \
    -a -exec cp -vat /mnt/host-volume {} +
EOF
}

while getopts ":hC:t:c:" opt; do
    case $opt in
        h) usage; exit 0;;
        C) project_dir="$(readlink -e "${OPTARG}")"
            [ -d "${project_dir}" ] || die "bad project dir ${OPTARG}";;
        t) debian_tag="${OPTARG}";;
        c) container_cmd="${OPTARG}";;
        :) die "missing argument: -${OPTARG}";;
        \?) die "bad option: -${OPTARG}";;
    esac
done

# Set default container command
container_cmd="${container_cmd:-podman}"

# Set default container command value if none set
case "${container_cmd}" in
    docker|podman) ;;
    *) die "container command is expected to be one of 'docker' or 'podman'" ;;
esac

shift $((OPTIND - 1))
case "${1:-test}" in
    'help') usage; exit 0;;
    'test') gbp_test; exit ${?};;
    'package') gbp_package; exit ${?};;
    *) die "bad action: ${1}";;
esac