[lxc-devel] [PATCH] lxc-cirros: support creating+running unprivileged

Stéphane Graber stgraber at ubuntu.com
Mon Nov 24 21:31:38 UTC 2014


On Fri, Oct 31, 2014 at 02:42:31AM +0000, Serge Hallyn wrote:
> Support creation and use of lxc-cirros by unprivileged users.
> 
> If we detect we are an unprivileged user, then insist that we
> be in a userns with a id mapping.
> 
> If we are in a userns, then don't extract /dev when extracting
> the rootfs.
> 
> If we are not root, then save the tarball to ~/.cache/lxc/cirros
> instead of /var/cache/lxc/cirros.
> 
> If we are not roo, then include entries to auto-mount proc and sys,
> as well as bind-mount devices.
> 
> Cc: smoser at ubuntu.com
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>

Acked-by: Stéphane Graber <stgraber at ubuntu.com>

> ---
>  templates/lxc-cirros.in | 62 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 37 insertions(+), 25 deletions(-)
> 
> diff --git a/templates/lxc-cirros.in b/templates/lxc-cirros.in
> index 24b9210..c8a8b36 100644
> --- a/templates/lxc-cirros.in
> +++ b/templates/lxc-cirros.in
> @@ -22,27 +22,21 @@
>  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>  
>  # Detect use under userns (unsupported)
> -for arg in "$@"; do
> -    [ "$arg" = "--" ] && break
> -    if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
> -        echo "This template can't be used for unprivileged containers." 1>&2
> -        echo "You may want to try the \"download\" template instead." 1>&2
> -        exit 1
> -    fi
> -done
> -
>  # Make sure the usual locations are in PATH
>  export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
>  
>  VERBOSITY=0
>  DOWNLOAD_URL="http://download.cirros-cloud.net/"
> -CACHE_D="@LOCALSTATEDIR@/cache/lxc/cirros"
>  
>  UNAME_M=$(uname -m)
>  ARCHES=( i386 x86_64 amd64 arm )
>  STREAMS=( released devel )
>  SOURCES=( nocloud none )
>  BUILD="standard"
> +LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@"
> +
> +LXC_MAPPED_GID=
> +LXC_MAPPED_UID=
>  
>  DEF_VERSION="released"
>  DEF_SOURCE="nocloud"
> @@ -53,6 +47,23 @@ case "${UNAME_M}" in
>      *) DEF_ARCH="i386";;
>  esac
>  
> +am_in_userns() {
> +    [ -e /proc/self/uid_map ] || { echo no; return; }
> +    [ "$(wc -l /proc/self/uid_map | awk '{ print $1 }')" -eq 1 ] || { echo yes; return; }
> +    line=$(awk '{ print $1 " " $2 " " $3 }' /proc/self/uid_map)
> +    [ "$line" = "0 0 4294967295" ] && { echo no; return; }
> +    echo yes
> +}
> +
> +in_userns=0
> +[ $(am_in_userns) = "yes" ] && in_userns=1
> +
> +if [ $(id -u) -eq 0 ]; then
> +    CACHE_D="@LOCALSTATEDIR@/cache/lxc/cirros"
> +else
> +    CACHE_D="$HOME/.cache/lxc/cirros"
> +fi
> +
>  error() { echo "$@" 1>&2; }
>  inargs() {
>      local needle="$1" x=""
> @@ -151,6 +162,12 @@ lxc.cgroup.devices.allow = c 10:228 rwm
>  # kvm
>  lxc.cgroup.devices.allow = c 10:232 rwm
>  EOF
> +
> +    if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then
> +        echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.userns.conf" >> $path/config
> +        echo "lxc.mount.auto = cgroup:mixed proc:mixed sys:ro" >> $path/config
> +    fi
> +
>  }
>  
>  insert_ds_nocloud() {
> @@ -187,8 +204,13 @@ extract_rootfs() {
>      mkdir -p "${rootfs_d}" ||
>          { error "failed to make rootfs dir ${rootfs_d}"; return 1; }
>  
> -    tar -C "${rootfs_d}" -Sxzf "${tarball}" ||
> -        { error "failed to populate ${rootfs_d}"; return 1; }
> +    if [ $in_userns -eq 1 ]; then
> +        tar -C "${rootfs_d}" --anchored --exclude="dev/*" -Sxzf "${tarball}" ||
> +            { error "failed to populate ${rootfs_d}"; return 1; }
> +    else
> +        tar -C "${rootfs_d}" -Sxzf "${tarball}" ||
> +            { error "failed to populate ${rootfs_d}"; return 1; }
> +    fi
>      return 0
>  }
>  
> @@ -218,7 +240,7 @@ download_tarball() {
>  
>  create_main() {
>      local short_opts="a:hn:p:S:uvV"
> -    local long_opts="arch:,auth-key:,name:,path:,tarball:,userdata:,verbose,version:,rootfs:"
> +    local long_opts="arch:,auth-key:,name:,path:,tarball:,userdata:,verbose,version:,rootfs:,mapped-uid:,mapped-gid:"
>      local getopt_out=""
>      getopt_out=$(getopt --name "${0##*/}" \
>          --options "${short_opts}" --long "${long_opts}" -- "$@") &&
> @@ -244,6 +266,8 @@ create_main() {
>                 --tarball) tarball="$next"; shift;;
>                 --source) dsource="$next"; shift;;
>                 --rootfs) rootfs_d="$next"; shift;;
> +            --mapped-uid) LXC_MAPPED_UID=$next; shift;;
> +            --mapped-gid) LXC_MAPPED_GID=$next; shift;;
>              --) shift; break;;
>          esac
>          shift;
> @@ -300,18 +324,6 @@ create_main() {
>  
>      extract_rootfs "${tarball}" "${rootfs_d}" || return
>  
> -    # cirros 0.3.1 was broken for /dev/random and /dev/urandom
> -    if [ -b "$rootfs_d/dev/random" ]; then
> -        rm -f "$rootfs_d/dev/random" &&
> -            mknod --mode=666 "$rootfs_d/dev/random" c 1 8 ||
> -           { error "failed to fix /dev/random"; return 1; }
> -    fi
> -    if [ -b "$rootfs_d/dev/urandom" ]; then
> -        rm -f "$rootfs_d/dev/urandom" &&
> -        mknod --mode=666 "$rootfs_d/dev/urandom" c 1 9 ||
> -           { error "failed to fix /dev/urandom"; return 1; }
> -    fi
> -
>      if [ "$version" = "0.3.2~pre1" ]; then
>          debug 1 "fixing console for lxc and '$version'"
>          sed -i 's,^\(#console.* 115200 \)# /dev/console,\1 console,g' \
> -- 
> 2.1.0
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20141124/b20bc0f3/attachment.sig>


More information about the lxc-devel mailing list