Skip to content
Snippets Groups Projects
Commit f523998e authored by Adrien Béraud's avatar Adrien Béraud
Browse files

Revert "cqfd: bump cqfd to version 5.1.0"

This reverts commit 96221fb6.

Change-Id: I6217a0c3435d7e682105905c5edbcfc0d0f045d1
parent e53d18d9
No related branches found
No related tags found
No related merge requests found
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# #
# cqfd - a tool to wrap commands in controlled Docker containers # cqfd - a tool to wrap commands in controlled Docker containers
# #
# Copyright (C) 2015-2018 Savoir-faire Linux, Inc. # Copyright (C) 2015-2016 Savoir-faire Linux, Inc.
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -20,12 +20,9 @@ ...@@ -20,12 +20,9 @@
set -e set -e
PROGNAME=`basename $0` PROGNAME=`basename $0`
VERSION=5.1.0 cqfd_dir=".cqfd"
dockerfile=".cqfd/docker/Dockerfile" dockerfile="$cqfd_dir/docker/Dockerfile"
cqfdrc=".cqfdrc" cqfdrc=".cqfdrc"
cqfd_user='builder'
cqfd_user_home='/home/builder'
cqfd_user_cwd="$cqfd_user_home/src"
## usage() - print usage on stdout ## usage() - print usage on stdout
usage() { usage() {
...@@ -33,15 +30,12 @@ usage() { ...@@ -33,15 +30,12 @@ usage() {
Usage: $PROGNAME [OPTION ARGUMENT] [COMMAND] [ARGUMENTS] Usage: $PROGNAME [OPTION ARGUMENT] [COMMAND] [ARGUMENTS]
Options: Options:
-f <file> Use file as config file (default .cqfdrc). -f <file> Use file as config file (default .cqfdrc)
-d <dir> Use directory as cqfd directory (default .cqfd)
-b <flavor_name> Target a specific build flavor. -b <flavor_name> Target a specific build flavor.
-q Turn on quiet mode
-v or --version Show version.
-h or --help Show this help text.
Commands: Commands:
init Initialize project build container init Initialize project build container
flavors List flavors from config file to stdout
run Run argument(s) inside build container run Run argument(s) inside build container
release Run argument(s) and release software release Run argument(s) and release software
help Show this help text help Show this help text
...@@ -49,7 +43,7 @@ Commands: ...@@ -49,7 +43,7 @@ Commands:
By default, run is assumed, and the run command is the one By default, run is assumed, and the run command is the one
configured in .cqfdrc. configured in .cqfdrc.
cqfd is Copyright (C) 2015-2018 Savoir-faire Linux, Inc. cqfd is Copyright (C) 2015-2016 Savoir-faire Linux, Inc.
This program comes with ABSOLUTELY NO WARRANTY. This is free This program comes with ABSOLUTELY NO WARRANTY. This is free
software, and you are welcome to redistribute it under the terms software, and you are welcome to redistribute it under the terms
...@@ -57,22 +51,22 @@ Commands: ...@@ -57,22 +51,22 @@ Commands:
EOF EOF
} }
# parse_ini_config_file() # cfg_parser() - parse ini-style config files
# Will parse a ini-style config file, and evaluate it to a bash array.
# Ref: http://theoldschooldevops.com/2008/02/09/bash-ini-parser/ # Ref: http://theoldschooldevops.com/2008/02/09/bash-ini-parser/
# arg$1: path to ini file # arg$1: path to ini file
parse_ini_config_file() { cfg_parser() {
# bash 4.3 and later break compatibility # bash 4.3 and later break compatibility
local is_compatibility_mode=false
if [ $BASH_VERSINFO -ge 4 -a ${BASH_VERSINFO[1]} -gt 2 ]; then if [ $BASH_VERSINFO -ge 4 -a ${BASH_VERSINFO[1]} -gt 2 ]; then
is_compatibility_mode=true local compat=1
shopt -s compat42 shopt -s compat42
fi fi
if ! ini="$(<$1)"; then # read the file if ! ini="$(<$1)"; then # read the file
die "$1: No such file!" die "$1: No such file!"
fi fi
ini="${ini//[/\\[}" # escape [ ini="${ini//[/\[}" # escape [
ini="${ini//]/\\]}" # escape ] ini="${ini//]/\]}" # escape ]
IFS=$'\n' && ini=( ${ini} ) # convert to line-array IFS=$'\n' && ini=( ${ini} ) # convert to line-array
ini=( ${ini[*]//;*/} ) # remove comments with ; ini=( ${ini[*]//;*/} ) # remove comments with ;
ini=( ${ini[*]/\ =/=} ) # remove tabs before = ini=( ${ini[*]/\ =/=} ) # remove tabs before =
...@@ -80,7 +74,8 @@ parse_ini_config_file() { ...@@ -80,7 +74,8 @@ parse_ini_config_file() {
ini=( ${ini[*]/\ =\ /=} ) # remove anything with a space around = ini=( ${ini[*]/\ =\ /=} ) # remove anything with a space around =
ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix
ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1)
ini=( ${ini[*]/%\(/ \( \)} ) # close array parenthesis ini=( ${ini[*]/=/=\( } ) # convert item to array
ini=( ${ini[*]/%/ \)} ) # close array parenthesis
ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
...@@ -91,9 +86,7 @@ parse_ini_config_file() { ...@@ -91,9 +86,7 @@ parse_ini_config_file() {
fi fi
# restore previous bash behaviour # restore previous bash behaviour
if $is_compatibility_mode; then [ "$compat" = "1" ] && shopt -u compat42
shopt -u compat42
fi
} }
## die() - exit when an error occured ## die() - exit when an error occured
...@@ -105,92 +98,69 @@ die() { ...@@ -105,92 +98,69 @@ die() {
# docker_build() - Initialize build container # docker_build() - Initialize build container
docker_build() { docker_build() {
config_load
if [ ! -f $dockerfile ]; then if [ ! -f $dockerfile ]; then
die "no Dockerfile found at location $dockerfile" die "no Dockerfile found at location $dockerfile"
fi fi
if [ -z "$project_build_context" ]; then docker build -q -t "$docker_img_name" `dirname $dockerfile`
docker build ${quiet:+-q} -t "$docker_img_name" "$(dirname "$dockerfile")"
else
docker build ${quiet:+-q} -t "$docker_img_name" "${project_build_context}" -f "$dockerfile"
fi
} }
# docker_run() - run command in configured container # docker_run() - run command in configured container
# A few implementation details: # A few implementation details:
# #
# - The user executing the build commands inside the container is # - The user executing the build commands inside the container is
# named after $cqfd_user, with the same uid/gid as your user to keep # named 'builder', with the same uid/gid as your user to keep
# filesystem permissions in sync. # filesystem permissions in sync.
# #
# - Your project's source directory is always mapped to $cqfd_user_cwd # - Your project's source directory is always mapped to ~builder/src/
# #
# - Your ~/.ssh directory is mapped to ~${cqfd_user}/.ssh to provide # - Your ~/.ssh directory is mapped to ~builder/.ssh to provide access
# access to the ssh keys (your build may pull authenticated git # to the ssh keys (your build may pull authenticated git repos for
# repos for example). # example).
# #
# arg$1: the command string to execute as $cqfd_user # arg$1: the command string to execute as builder
# #
docker_run() { docker_run() {
local interactive_options [ -z "$JENKINS_URL" ] && local nojenkins=1
if tty -s; then # The user may set the CQFD_EXTRA_VOLUMES environment variable
interactive_options="-ti" # to map custom volumes inside his development container.
fi
# If possible, map cqfd_user from the calling user's
if [ -n "$USER" ]; then
cqfd_user="$USER"
fi
if [ -n "$HOME" ]; then
cqfd_user_home="$(cd $HOME; pwd)"
cqfd_user_cwd="$(pwd)"
fi
# Display a warning message if using no more supported options
if [ -n "$CQFD_EXTRA_VOLUMES" ]; then if [ -n "$CQFD_EXTRA_VOLUMES" ]; then
die 'Warning: CQFD_EXTRA_VOLUMES is no more supported, use local map extravol
CQFD_EXTRA_RUN_ARGS="-v <local_dir>:<container_dir>"' for map in $CQFD_EXTRA_VOLUMES; do
extravol+="-v $map "
done
fi fi
if [ -n "$CQFD_EXTRA_HOSTS" ]; then if [ -n "$CQFD_EXTRA_HOSTS" ]; then
die 'Warning: CQFD_EXTRA_HOSTS is no more supported, use local map extrahosts
CQFD_EXTRA_RUN_ARGS="--add-host <hostname>:<IP_address>"' for map in $CQFD_EXTRA_HOSTS; do
fi extrahosts+="--add-host $map "
if [ -n "$CQFD_EXTRA_ENV" ]; then done
die 'Warning: CQFD_EXTRA_ENV is no more supported, use
CQFD_EXTRA_RUN_ARGS="-e <var_name>=<value>"'
fi
if [ -n "$CQFD_EXTRA_PORTS" ]; then
die 'Warning: CQFD_EXTRA_PORTS is no more supported, use
CQFD_EXTRA_RUN_ARGS="-p <host_port>:<docker_port>"'
fi fi
# The user may set the CQFD_EXTRA_RUN_ARGS environment variables # CQFD_EXTRA_ENV is a space-separated list like VAR=value
# to pass custom run arguments to his development container. if [ -n "$CQFD_EXTRA_ENV" ]; then
local map extraenv
# Set HOME variable for the $cqfd_user, except if it was for map in $CQFD_EXTRA_ENV; do
# explicitely set via CQFD_EXTRA_RUN_ARGS extraenv+="-e $map "
local home_env_var="-e HOME=$cqfd_user_home" done
if echo "$CQFD_EXTRA_RUN_ARGS" | egrep -q "(-e[[:blank:]]*|--env[[:blank:]]+)HOME="; then
home_env_var=""
fi fi
tmp_launcher=$(make_launcher) docker run --privileged -v "$PWD":/home/builder/src \
-v ~/.ssh:/home/builder/.ssh \
docker run --privileged \
$CQFD_EXTRA_RUN_ARGS \
--rm \ --rm \
--log-driver=none \ $extravol \
-v $tmp_launcher:/bin/cqfd_launch \ $extrahosts \
-v ~/.ssh:$cqfd_user_home/.ssh \ $extraenv \
-v "$PWD":$cqfd_user_cwd \ ${nojenkins:+ -ti} \
$home_env_var \ ${SSH_AUTH_SOCK:+ -v $SSH_AUTH_SOCK:/home/builder/.sockets/ssh} \
$interactive_options \ ${SSH_AUTH_SOCK:+ -e SSH_AUTH_SOCK=/home/builder/.sockets/ssh} \
${SSH_AUTH_SOCK:+ -v $SSH_AUTH_SOCK:$cqfd_user_home/.sockets/ssh} \ $docker_img_name \
${SSH_AUTH_SOCK:+ -e SSH_AUTH_SOCK=$cqfd_user_home/.sockets/ssh} \ /bin/bash -c "groupadd -og $GROUPS -f builders && \
$docker_img_name cqfd_launch "$@" 2>&1 useradd -s /bin/bash -u $UID -g $GROUPS builder && \
chown $UID:$GROUPS /home/builder && \
rm -f $tmp_launcher su builder -p -c \"cd ~builder/src/ && $1\" 2>&1"
} }
# make_archive(): Create a release package. # make_archive(): Create a release package.
...@@ -204,9 +174,7 @@ make_archive() { ...@@ -204,9 +174,7 @@ make_archive() {
fi fi
for file in $release_files; do for file in $release_files; do
if [ ! -e $file ]; then [ -f $file ] || die "Cannot create release: missing $file"
die "Cannot release: can't find $file"
fi
done done
# template the generated archive's filename # template the generated archive's filename
...@@ -215,9 +183,7 @@ make_archive() { ...@@ -215,9 +183,7 @@ make_archive() {
local date_rfc3339=`date --rfc-3339='date'` local date_rfc3339=`date --rfc-3339='date'`
# default name for the archive if not set # default name for the archive if not set
if [ -z "$release_archive" ]; then [ -z "$release_archive" ] && release_archive="%Po-%Pn.tar.xz"
release_archive="%Po-%Pn.tar.xz"
fi
release_archive=`echo $release_archive | release_archive=`echo $release_archive |
sed -e 's!%%!%!g; sed -e 's!%%!%!g;
...@@ -231,146 +197,66 @@ make_archive() { ...@@ -231,146 +197,66 @@ make_archive() {
# also replace variable names - beware with eval # also replace variable names - beware with eval
eval release_archive=`echo $release_archive` eval release_archive=`echo $release_archive`
# setting tar_transform=yes will move files to the root of a tar archive XZ_OPT=-9 tar --transform "s/.*\///g" -cJf \
if [ "$release_transform" = "yes" ]; then
local tar_opts='--transform s/.*\///g'
fi
# support the following archive formats
case "$release_archive" in
*.tar.xz)
XZ_OPT=-9 tar $tar_opts -cJf \
"$release_archive" $release_files
;;
*.tar.gz)
tar $tar_opts -czf \
"$release_archive" $release_files "$release_archive" $release_files
;;
*.zip)
zip -q -9 -r "$release_archive" $release_files
;;
*)
;;
esac
}
# make_launcher - generate in-container launcher script
# return: the path to the launcher script on stdout
make_launcher()
{
local tmpfile=$(mktemp /tmp/tmp.XXXXXX)
chmod 0755 $tmpfile
cat >$tmpfile <<EOF
#!/bin/sh
# create container user to match expected environment
die () {
echo "error: \$*"
exit 1
}
test_cmd () {
command -v "\$1" > /dev/null 2>&1
}
debug () {
test -n "\$CQFD_DEBUG" && echo "debug: \$*"
}
# Check container requirements
test -x /bin/bash || { failed=1 && echo "error: /bin/bash does not exist or is not executable"; }
test_cmd groupadd || { failed=1 && echo "error: Missing command: groupadd"; }
test_cmd useradd || { failed=1 && echo "error: Missing command: useradd"; }
test_cmd chown || { failed=1 && echo "error: Missing command: chown"; }
test_cmd sudo && has_sudo=1 || test_cmd su ||
{ failed=1 && echo "error: Missing command: su or sudo"; }
test -n "\$failed" &&
die "Some dependencies are missing from the container, see above messages."
# Add the host's user and group to the container, and adjust ownership.
groupadd -og $GROUPS -f builders || die "groupadd command failed."
useradd -s /bin/bash -ou $UID -g $GROUPS -d "$cqfd_user_home" $cqfd_user \
|| die "useradd command failed."
chown $UID:$GROUPS $cqfd_user_home || die "chown command failed."
# run the provided command in the working directory
cd $cqfd_user_cwd || die "Changing directory to \"$cqfd_user_cwd\" failed."
if [ -n "\$has_sudo" ]; then
# Use sudo to provide a controlling TTY for the executed command
debug "Using \"sudo\" to execute command \"\$@\" as user \"$cqfd_user\""
sudo -E -u $cqfd_user sh -c "\$@"
else
debug "Using \"su\" to execute command \"\$@\" as user \"$cqfd_user\""
su $cqfd_user -p -c "\$@"
fi
EOF
echo $tmpfile
} }
# config_load() - load build settings from cqfdrc # config_load() - load build settings from cqfdrc
# $1: optional "flavor" of the build, is a suffix of command. # $1: optional "flavor" of the build, is a suffix of command.
config_load() { config_load() {
IFS="$IFS" parse_ini_config_file "$cqfdrc" local p_flavor="$1"
IFS="$IFS" cfg_parser "$cqfdrc"
cfg.section.project # load the [project] section cfg.section.project # load the [project] section
project_org="$org" project_org="$org"
project_name="$name" project_name="$name"
project_build_context="$build_context"
cfg.section.build # load the [build] section cfg.section.build # load the [build] section
# build parameters may be overriden by a flavor defined in the # build parameters may be overriden by a flavor defined in the
# build section's 'flavors' parameter. # build section's 'flavors' parameter.
local flavor="$1" if [ -n "$p_flavor" ]; then
if [ -n "$flavor" ]; then for flavor in $flavors; do
if grep -qw "$flavor" <<< "$flavors"; then if [ "$flavor" = "$p_flavor" ]; then
cfg.section."$flavor" # load the [$flavor] section local _found=1
break
fi
done
if [ -n "$_found" ]; then
cfg.section."$p_flavor" # load the [$p_flavor] section
else else
die "flavor \"$flavor\" not found in flavors list" die "flavor \"$p_flavor\" not found in flavors list"
fi fi
fi fi
build_cmd="$command" build_cmd="$command"
if [ -n "$distro" ]; then
dockerfile="$cqfd_dir/$distro/Dockerfile"
fi
release_files="`eval echo $files`" release_files="`eval echo $files`"
release_archive="$archive" release_archive="$archive"
release_transform="$tar_transform"
# This will look like fooinc_reponame # This will look like fooinc_reponame
if [ -n "$project_org" -a -n "$project_name" ]; then if [ -n "$project_org" -a -n "$project_name" ]; then
docker_img_name="cqfd_${project_org}_${project_name}" docker_img_name="${project_org}_${project_name}"
else else
die "project.org and project.name not configured" die "project.org and project.name not configured"
fi fi
# Adapt things for a specific container
if [ -n "$distro" ]; then
dockerfile=".cqfd/$distro/Dockerfile"
docker_img_name+="_$distro"
fi
} }
has_to_release=false
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
help|-h|"--help") help|-h|"--help")
usage usage
exit 0 exit 0
;; ;;
version|-v|"--version")
echo $VERSION
exit 0
;;
init) init)
config_load $flavor
docker_build docker_build
exit $? exit $?
;; ;;
flavors)
config_load
echo $flavors
exit 0
;;
-b) -b)
shift shift
flavor="$1" flavor="$1"
...@@ -379,13 +265,13 @@ while [ $# -gt 0 ]; do ...@@ -379,13 +265,13 @@ while [ $# -gt 0 ]; do
shift shift
cqfdrc="$1" cqfdrc="$1"
;; ;;
-q) -d)
quiet=true shift
cqfd_dir="$1"
dockerfile="$cqfd_dir/docker/Dockerfile"
;; ;;
run|release) run|release)
if [ "$1" = "release" ]; then [ "$1" = "release" ] && make_archive=1
has_to_release=true
fi
if [ $# -gt 1 ]; then if [ $# -gt 1 ]; then
shift shift
build_cmd_alt="$@" build_cmd_alt="$@"
...@@ -393,9 +279,7 @@ while [ $# -gt 0 ]; do ...@@ -393,9 +279,7 @@ while [ $# -gt 0 ]; do
break break
;; ;;
?*) ?*)
echo "Unknown command: $1" die "Unknown command: $1"
usage
exit 1
;; ;;
*) *)
# empty or no argument case # empty or no argument case
...@@ -414,6 +298,6 @@ fi ...@@ -414,6 +298,6 @@ fi
docker_run "$build_cmd" docker_run "$build_cmd"
if $has_to_release; then if [ "$make_archive" = "1" ]; then
make_archive make_archive
fi fi
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment