Hello World

File obs-docker-support of Package build

#!/bin/sh
################################################################
#
# Enable docker build support in container.
#
# Author: Marco Strigl
#
################################################################
#
# Copyright (c) 2017 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################

LOCAL_REPOS_D="/etc/repos_obs_dockersupport.d/"
LOCAL_APTREPOS_D="/etc/aptrepos_obs_dockersupport.d/"
DATA_DIR=

zypper() {
    local cmd
    # try to find the command
    local globalopts
    typeset -a globalopts
    while test -n "$1"; do
        case $1 in
        -R|--root|--installroot)
	    globalopts[${#globalopts[@]}]="$1"
	    globalopts[${#globalopts[@]}]="$2"
	    shift 2
	    ;;
        -*)
	    globalopts[${#globalopts[@]}]="$1"
	    shift
	    ;;
	*)  
	    cmd=$1
	    shift
	    break
	    ;;
	esac
    done
    case $cmd in
    in|install|rm|remove|up|update|if|info)
	/usr/bin/zypper -D $LOCAL_REPOS_D "${globalopts[@]}" "$cmd" "$@"
	s=$?
	setup_links
	exit $s
	;;
    ar|addrepo)
	exec /usr/bin/zypper "${globalopts[@]}" "$cmd" -C "${@%/*.repo}"
	;;
    ref|refresh)
	echo "skipping zypper refresh"
	exit 0
	;;
    *)
	exec /usr/bin/zypper "${globalopts[@]}" "$cmd" "$@"
	;;
    esac
}

obs_pkg_mgr() {
    case "$1" in
    install|remove)
	shift
	/usr/bin/zypper -D $LOCAL_REPOS_D --no-gpg-checks -n in "$@"
	s=$?
	setup_links
	exit $s
	;;
    add_repo)
	shift
	exec /usr/bin/zypper ar -C "$@"
	;;
    *)
	echo "Usage: obs_pkg_mgr (install|add_repo) args" >&2
	exit 1
	;;
    esac
}

apt_get() {
    local cmd
    # try to find the command
    local globalopts
    typeset -a globalopts
    while test -n "$1"; do
        case $1 in
        -*)
	    globalopts[${#globalopts[@]}]="$1"
	    shift
	    ;;
	*)  
	    cmd=$1
	    shift
	    break
	    ;;
	esac
    done
    case $cmd in
    update)
	exit 0
	;;
    install|upgrade)
	/usr/bin/apt-get -o Dir::Etc::SourceList=$LOCAL_APTREPOS_D/obssource -o Dir::Etc::SourceParts=$LOCAL_APTREPOS_D --allow-unauthenticated "${globalopts[@]}" "$cmd" "$@"
	s=$?
	setup_links
	exit $s
	;;
    *)
	exec /usr/bin/apt-get "${globalopts[@]}" "$cmd" "$@"
	;;
    esac
}

dnf() {
    # try to find command
    local globalopts
    typeset -a globalopts
    while test -n "$1"; do
        case $1 in
        -*)
	    globalopts[${#globalopts[@]}]="$1"
	    shift
	    ;;
	*)  
	    cmd=$1
	    shift
	    break
	    ;;
	esac
    done
    case $cmd in
    in|install|up|update)
	/usr/bin/dnf --setopt=reposdir=$LOCAL_REPOS_D "${globalopts[@]}" "$cmd" "$@"
	s=$?
	setup_links
	exit $s
	;;
    *)
	exec /usr/bin/dnf "${globalopts[@]}" "$cmd" "$@"
	;;
    esac
}

yum() {
    # try to find command
    global globalopts
    typeset -a globalopts
    while test -n "$1"; do
        case $1 in
        -*)
	    globalopts[${#globalopts[@]}]="$1"
	    shift
	    ;;
	*)  
	    cmd=$1
	    shift
	    break
	    ;;
	esac
    done
    case $cmd in
    in|install|up|update)
	/usr/bin/yum --setopt=reposdir=$LOCAL_REPOS_D "${globalopts[@]}" "$cmd" "$@"
	s=$?
	setup_links
	exit $s
	;;
    *)
	exec /usr/bin/yum "${globalopts[@]}" "$cmd" "$@"
	;;
    esac
}

curl() {
    local cmd
    typeset -a cmd
    local oopt
    local oname
    while test -n "$1" ; do
	case "$1" in
	http://* | https://*)
	    url=$1
	    urlsha256=$(echo -n $url | sha256sum -)
	    urlsha256="${urlsha256%% *}"
	    if test -n "$DATA_DIR" ; then
		cmd[${#cmd[@]}]="file:$DATA_DIR/build-webcache/$urlsha256"
	    else
		cmd[${#cmd[@]}]="localhost:80/build-webcache/$urlsha256"
	    fi
	    oname="${url%%\?*}"
	    oname="${url##*/}"
	    shift
	    ;;
	-O)
	    oopt=true
	    ;;
	*)
	    cmd[${#cmd[@]}]="$1"
	    shift
	    ;;
	esac
    done
    if test -n "$oopt" -a -n "$oname" ; then
	cmd[${#cmd[@]}]="-o"
	cmd[${#cmd[@]}]="$oname"
    fi
    exec /usr/bin/curl "${cmd[@]}"
}

upload_with_perl='
use Socket;
$/ = undef;
my $data = <STDIN>;
my ($size, $ans) = length($data);
socket(S, PF_INET, SOCK_STREAM, getprotobyname("tcp")) || die;
connect(S, sockaddr_in(80, inet_aton("127.0.0.1"))) || die("connect: $!\n");
select(S);
$| = 1;
print S "PUT $ARGV[0] HTTP/1.1\r\nContent-Length: ".length($data)."\r\n\r\n$data";
read(S, $ans, 1024);
die($ans) unless $ans =~ / 200 /;
'

upload_packages() {
    local n=$1
    local ans
    if test -x /usr/bin/rpm -o -x /bin/rpm ; then
	rpm -qa --qf '%{NAME}|%{EPOCH}|%{VERSION}|%{RELEASE}|%{ARCH}|%{DISTURL}|%{LICENSE}\n' > /tmp/packages
	if test -n "$DATA_DIR" ; then
	    cp /tmp/packages "$DATA_DIR/UPLOAD/$n"
	elif test -x /usr/bin/curl ; then
	    /usr/bin/curl "http://localhost:80/$n" -T /tmp/packages > /dev/null
	elif test -x /usr/bin/perl ; then
	    /usr/bin/perl -e "$upload_with_perl" "/$n" < /tmp/packages
        else
	    (echo -n -e "PUT /$n HTTP/1.1\r\nContent-Length: $(wc -c < /tmp/packages)\r\n\r\n" | cat - /tmp/packages && read -t 600 ans ; case "$ans" in *\ 200\ *) ;; *) echo "$ans" >&2 ;; esac) <>/dev/tcp/localhost/80 1>&0
	fi
	rm -f /tmp/packages
    fi
}

setup_links() {
    test -e /usr/bin/zypper -a ! -e /usr/local/sbin/zypper && ln -s obs-docker-support /usr/local/sbin/zypper
    test -e /usr/bin/yum -a ! -e /usr/local/sbin/yum && ln -s obs-docker-support /usr/local/sbin/yum
    test -e /usr/bin/dnf -a ! -e /usr/local/sbin/dnf && ln -s obs-docker-support /usr/local/sbin/dnf
    test -e /usr/bin/apt-get -a ! -e /usr/local/sbin/apt-get && ln -s obs-docker-support /usr/local/sbin/apt-get
    test -e /usr/bin/curl -a ! -e /usr/local/sbin/curl && ln -s obs-docker-support /usr/local/sbin/curl
}

remove_links() {
    rm -f /usr/local/sbin/zypper
    rm -f /usr/local/sbin/yum
    rm -f /usr/local/sbin/dnf
    rm -f /usr/local/sbin/apt-get
    rm -f /usr/local/sbin/curl
}

obs_docker_support() {
    case "$1" in
    --install|-i)
	data_url=http://localhost:80
	test -n "$DATA_DIR" && data_url="file:$DATA_DIR"
	setup_links
	ln -s obs-docker-support /usr/local/sbin/obs_pkg_mgr
	if test -e /usr/bin/zypper -o -e /usr/bin/yum -o -e /usr/bin/dnf ; then
	    mkdir -p "$LOCAL_REPOS_D"
	    cat >$LOCAL_REPOS_D/obs_repository.repo <<EOF
[obs_repository]
name=obs_repository
enabled=1
autorefresh=0
baseurl=$data_url
type=rpm-md
gpgcheck=0
EOF
	    test -x /usr/bin/zypper && /usr/bin/zypper -D $LOCAL_REPOS_D ref
	fi
	if test -e /usr/bin/apt-get ; then
	    mkdir -p "$LOCAL_APTREPOS_D"
	    echo "deb $data_url ./" > $LOCAL_APTREPOS_D/obssource
	    test -e /var/lib/apt && mv /var/lib/apt /var/lib/apt.obssave
	    /usr/bin/apt-get -o Dir::Etc::SourceList=$LOCAL_APTREPOS_D/obssource -o Dir::Etc::SourceParts=$LOCAL_APTREPOS_D update
	fi
	upload_packages basepackages
    ;;
    --uninstall|-u)
	rm -rf "$LOCAL_REPOS_D"
	rm -rf "$LOCAL_APTREPOS_D"
	remove_links
	rm -f /usr/local/sbin/obs_pkg_mgr
	if test -e /var/lib/apt.obssave ; then
	    rm -rf /var/lib/apt
	    mv /var/lib/apt.obssave /var/lib/apt
	fi
	upload_packages packages
	rm -f /usr/local/sbin/obs-docker-support
    ;;
    esac
}

if test `id -u` != "0"; then
    echo <<EOF
obs-docker-support: not executed as root user!

This can happen if your base container (see FROM line) is setting USER already, then builds in dependent container run as that user/group.
EOF
    exit 1
fi

case ${0##*/} in
obs-docker-support)
    obs_docker_support "$@"
    ;;
obs_pkg_mgr)
    obs_pkg_mgr "$@"
    ;;
zypper)
    zypper "$@"
    ;;
apt-get)
    apt_get "$@"
    ;;
curl)
    curl "$@"
    ;;
*)
    echo "obs-docker-support: unsupported mode ${0##*/}" >&2
    exit 1
esac