Re: Slackware lxc template in Slackware 14.2

Didier Spaier via slackware <[email protected]> Sat, 8 Apr 2017 00:22:42 +0200
Newsgroups gmane.linux.slackware
Message-ID <[email protected]>
Le 08/04/2017 à 00:00, Eleksir via slackware a écrit :
> Hello folks.
> 
> For sometime i'm setting up some pretty well amount of LXC containers and
> stock slackware containers are unable to use slackpkg and namely wget:
> 
> Downloading
> http://ftp.slackware.com/pub/slackware/slackware-current/GPG-KEY...
> wget: error while loading shared libraries: libunistring.so.0: cannot open
> shared object file: No such file or directory
> Updating the package lists...
>     Downloading...
>             Downloading
> http://ftp.slackware.com/pub/slackware/slackware-current/ChangeLog.txt...
> wget: error while loading shared libraries: libunistring.so.0: cannot open
> shared object file: No such file or directory
> grep: /tmp/slackpkg.2ztlEa/ChangeLog.txt: No such file or directory
> 
> Error downloading from
> http://ftp.slackware.com/pub/slackware/slackware-current/.
> Please, check your mirror and try again.
> 
> 
> 
> Well, it's getting me nuts. 2 things: Slackware-Current instead of stable
> (it is on stable host OS!) by default and unusable wget!
> 
> Actually, i can download libunistring-0.9.3-i486-1.txz from mirror and put
> it to container using host os, then lxc-attach to container and installpkg
> this package but i think that it should work out of the box, am i wrong?


Works here. Also I have modified the template to allow running unprivileged
containers, see the attached patch (instructions for use on top of it)
and this post:

http://www.linuxquestions.org/questions/slackware-14/%5Brequest-for-comments%5D-do-we-still-need-cgmanager-4175599676/#post5681501

Cheers,
Didier

_______________________________________________
slackware mailing list
[email protected]
https://mailman.lug.org.uk/mailman/listinfo/slackware
lxc_slackware_privileged_or_not_v3.1.txt (text/plain, 21 KB)
--- lxc-slackware	2017-03-05 16:19:54.000000000 +0100
+++ lxc-slackware.new2	2017-03-11 01:13:28.711745985 +0100
@@ -9,6 +9,11 @@
 # Template for slackware by Matteo Bernardini <[email protected]>
 # some parts are taken from the debian one (used as model)
 
+# Modified by Didier Spaier <didier~at~slint~dot~fr> to allow building
+# unprivileged containers through user namespaces mapping, see
+# user_namespaces(7). Some parts are taken from the busybox template.
+# Credit Chris Willing for unprivileged containers' settings.
+
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
@@ -23,7 +28,104 @@
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
-cache=${cache:-/var/cache/lxc/slackware}
+# To build an unprivileged Slackware container as regular user
+# ============================================================
+# In the folling examples the permissions are set per user.
+# In case of several users needing to create containers, it may be
+# preferable that they be set per group, see 'man cgconfig.conf' and
+# 'man cgrules.conf'. 'didier' is the username in the examples below.
+
+# 1) Feed /etc/{subuid,subgid} with a line of mapping like:
+#     didier:100000:65537
+# You can use these commands as root to do that:
+#     /usr/sbin/usermod --add-subuids 100000-165536 didier
+#     /usr/sbin/usermod --add-subgids 100000-165536 didier
+# Of course substitute your username to 'didier'.
+
+# 2) Create the directory ~/.config/lxc, then write the file
+#     ~/.config/lxc/default.conf with this content (three lines):
+#     lxc.id_map = u 0 100000 65536
+#     lxc.id_map = g 0 100000 65536
+#     lxc.devttydir =
+
+# 3) Create the container as didier:
+#     lxc-create -n myslack -t slackware
+
+# 4) Make sure /etc/rc.d/{rc.cgconfig,rc.cgred} be executable
+
+# 5) Run as root (at boot time in /etc/rc.d/rc.local for instance)
+#     /etc/rc.d/rc.cgconfig start && /etc/rc.d/rc.cgred start
+
+# 6) As didier run:
+#     lxc-start -n myslack
+
+# 7) Then still as didier run one of these commands:
+#     lxc-console -n myslack
+#     lxc-attach -n myslack
+
+
+# Other required settings
+# =======================
+# You will need to have in /etc/cgconfig.conf at least what follows
+# (Of course uncomment the lines below):
+
+##  This is the content of /etc/cgconfig.conf used to start unprivileged
+##  lxc containers on Slackware as regular user
+##  Substitute your username to 'didier'  
+#  group containers {
+#     perm {
+#         task {
+#             uid = didier;
+#             gid = users;
+#         }
+#     admin {
+#           uid = didier;
+#           gid = users;
+#       }
+#   }
+#   cpuset { cgroup.clone_children = 1;
+#   cpuset.mems = 0;
+#   cpuset.cpus = 0-3; }
+#   cpu {}
+#   cpuacct {}
+#   blkio {}
+#   memory { memory.use_hierarchy = 1; }
+#   devices {}
+#   freezer {}
+#   net_cls {}
+#   perf_event {}
+#   net_prio {}
+#   pids {}
+# }
+
+## You also need a specific content in /etc/cgrules.conf:
+
+##  This is the content of /etc/cgcrules.conf used to start unprivileged
+##  lxc containers on Slackware as regular user.
+##  Substitute your username to 'didier'
+##  And make sure the destination (here 'containers/') is the group name
+##  used in /etc/cgconfig.conf
+#   didier        *      containers/
+
+# The real thing begins here.
+
+LXC_MAPPED_UID=
+LXC_MAPPED_GID=
+
+# Make sure the usual locations are in PATH
+export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
+
+# If we are in an user namespace, am_in_userns returns yes.
+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
 
 # Use the primary Slackware site by default, but please consider changing
 # this to a closer mirror site.
@@ -39,164 +141,166 @@
 
 configure_slackware()
 {
-rootfs=$1
-hostname=$2
-
-echo "Configuring..." ; echo
-
-# The next part contains excerpts taken from SeTconfig (written by
-# Patrick Volkerding) from the slackware setup disk.
-# But before pasting them just set a variable to use them as they are 
-T_PX=$rootfs
-
-( cd $T_PX ; chmod 755 ./ )
-( cd $T_PX ; chmod 755 ./var )
-if [ -d $T_PX/usr/src/linux ]; then
-  chmod 755 $T_PX/usr/src/linux
-fi
-if [ ! -d $T_PX/proc ]; then
-  mkdir $T_PX/proc
-  chown root.root $T_PX/proc
-fi
-if [ ! -d $T_PX/sys ]; then
-  mkdir $T_PX/sys
-  chown root.root $T_PX/sys
-fi
-chmod 1777 $T_PX/tmp
-if [ ! -d $T_PX/var/spool/mail ]; then
-  mkdir -p $T_PX/var/spool/mail
-  chmod 755 $T_PX/var/spool
-  chown root.mail $T_PX/var/spool/mail
-  chmod 1777 $T_PX/var/spool/mail
-fi
-
-echo "#!/bin/sh" > $T_PX/etc/rc.d/rc.keymap
-echo "# Load the keyboard map.  More maps are in /usr/share/kbd/keymaps." \
-  >> $T_PX/etc/rc.d/rc.keymap
-echo "if [ -x /usr/bin/loadkeys ]; then" >> $T_PX/etc/rc.d/rc.keymap
-echo " /usr/bin/loadkeys us" >> $T_PX/etc/rc.d/rc.keymap
-echo "fi" >> $T_PX/etc/rc.d/rc.keymap
-chmod 755 $T_PX/etc/rc.d/rc.keymap
-
-# Network configuration is left to the user, that have to edit
-# /etc/rc.d/rc.inet1.conf and /etc/resolv.conf of the container
-# just set the hostname
-cat <<EOF > $rootfs/etc/HOSTNAME
+    rootfs=$1
+    hostname=$2
+    
+    echo "Configuring..." ; echo
+    
+    # The next part contains excerpts taken from SeTconfig (written by
+    # Patrick Volkerding) from the slackware setup disk.
+    # But before pasting them just set a variable to use them as they are 
+    T_PX=$rootfs
+    
+    ( cd $T_PX ; chmod 755 ./ )
+    ( cd $T_PX ; chmod 755 ./var )
+    if [ -d $T_PX/usr/src/linux ]; then
+      chmod 755 $T_PX/usr/src/linux
+    fi
+    if [ ! -d $T_PX/proc ]; then
+      mkdir $T_PX/proc
+      chown root.root $T_PX/proc
+    fi
+    if [ ! -d $T_PX/sys ]; then
+      mkdir $T_PX/sys
+      chown root.root $T_PX/sys
+    fi
+    chmod 1777 $T_PX/tmp
+    if [ ! -d $T_PX/var/spool/mail ]; then
+          mkdir -p $T_PX/var/spool/mail
+      chmod 755 $T_PX/var/spool
+      chown root.mail $T_PX/var/spool/mail
+      chmod 1777 $T_PX/var/spool/mail
+    fi
+    
+    echo "#!/bin/sh" > $T_PX/etc/rc.d/rc.keymap
+    echo "# Load the keyboard map.  More maps are in /usr/share/kbd/keymaps." \
+      >> $T_PX/etc/rc.d/rc.keymap
+    echo "if [ -x /usr/bin/loadkeys ]; then" >> $T_PX/etc/rc.d/rc.keymap
+    echo " /usr/bin/loadkeys us" >> $T_PX/etc/rc.d/rc.keymap
+    echo "fi" >> $T_PX/etc/rc.d/rc.keymap
+    chmod 755 $T_PX/etc/rc.d/rc.keymap
+    
+    # Network configuration is left to the user, that have to edit
+    # /etc/rc.d/rc.inet1.conf and /etc/resolv.conf of the container
+    # just set the hostname
+    cat <<EOF > $rootfs/etc/HOSTNAME
 $hostname.example.net
 EOF
-cp $rootfs/etc/HOSTNAME $rootfs/etc/hostname
-
-# make needed devices, from Chris Willing's MAKEDEV.sh
-# http://www.vislab.uq.edu.au/howto/lxc/MAKEDEV.sh
-DEV=$rootfs/dev
-mkdir -p ${DEV}
-mknod -m 666 ${DEV}/null c 1 3
-mknod -m 666 ${DEV}/zero c 1 5
-mknod -m 666 ${DEV}/random c 1 8
-mknod -m 666 ${DEV}/urandom c 1 9
-mkdir -m 755 ${DEV}/pts
-mkdir -m 1777 ${DEV}/shm
-mknod -m 666 ${DEV}/tty c 5 0
-mknod -m 600 ${DEV}/console c 5 1
-mknod -m 666 ${DEV}/tty0 c 4 0
-mknod -m 666 ${DEV}/tty1 c 4 1
-mknod -m 666 ${DEV}/tty2 c 4 2
-mknod -m 666 ${DEV}/tty3 c 4 3
-mknod -m 666 ${DEV}/tty4 c 4 4
-mknod -m 666 ${DEV}/tty5 c 4 5
-mknod -m 666 ${DEV}/full c 1 7
-mknod -m 600 ${DEV}/initctl p
-mknod -m 660 ${DEV}/loop0 b 7 0
-mknod -m 660 ${DEV}/loop1 b 7 1
-ln -s pts/ptmx ${DEV}/ptmx
-ln -s /proc/self/fd ${DEV}/fd
-
-echo "Adding an etc/fstab that must be modified later with the"
-echo "full path of the container's rootfs if you decide to move it."
-cat >$rootfs/etc/fstab <<EOF
-lxcpts $rootfs/dev/pts devpts defaults,newinstance 0 0
+    cp $rootfs/etc/HOSTNAME $rootfs/etc/hostname
+    
+    # make needed devices, from Chris Willing's MAKEDEV.sh
+    # http://www.vislab.uq.edu.au/howto/lxc/MAKEDEV.sh
+    DEV=$rootfs/dev
+    if [ $in_userns -ne 1 ]; then
+        mkdir -p ${DEV}
+        mknod -m 666 ${DEV}/null c 1 3
+        mknod -m 666 ${DEV}/zero c 1 5
+        mknod -m 666 ${DEV}/random c 1 8
+        mknod -m 666 ${DEV}/urandom c 1 9
+        mkdir -m 755 ${DEV}/pts
+        mkdir -m 1777 ${DEV}/shm
+        mknod -m 666 ${DEV}/tty c 5 0
+        mknod -m 600 ${DEV}/console c 5 1
+        mknod -m 666 ${DEV}/tty0 c 4 0
+        mknod -m 666 ${DEV}/tty1 c 4 1
+        mknod -m 666 ${DEV}/tty2 c 4 2
+        mknod -m 666 ${DEV}/tty3 c 4 3
+        mknod -m 666 ${DEV}/tty4 c 4 4
+        mknod -m 666 ${DEV}/tty5 c 4 5
+        mknod -m 666 ${DEV}/full c 1 7
+        mknod -m 600 ${DEV}/initctl p
+        mknod -m 660 ${DEV}/loop0 b 7 0
+        mknod -m 660 ${DEV}/loop1 b 7 1
+    fi
+    ln -s pts/ptmx ${DEV}/ptmx
+    ln -s /proc/self/fd ${DEV}/fd
+    
+    echo "Adding an etc/fstab that must be modified later with the"
+    echo "full path of the container's rootfs if you decide to move it."
+    cat >$rootfs/etc/fstab <<EOF
+devpts $rootfs/dev/pts devpts defaults,newinstance 0 0
 none $rootfs/proc    proc   defaults 0 0
 none $rootfs/sys     sysfs  defaults 0 0
 none /dev/shm tmpfs defaults 0 0
 none /run tmpfs defaults,mode=0755 0 0
 EOF
-
-# Back up the existing init scripts and install the lxc versions:
-( cd $rootfs/etc/rc.d
-  cp -a /usr/share/lxc/scripts/slackware/* .
-  chmod 755 *.lxc
-  for file in *.lxc ; do
-    cp -a $(basename $file .lxc) $(basename $file .lxc).orig
-    cp -a $file $(basename $file .lxc)
-  done
-)
-
-# restart rc.inet1 to have routing for the loop device
-echo "/etc/rc.d/rc.inet1 restart" >> $rootfs/etc/rc.d/rc.local
-
-# reduce the number of local consoles: two should be enough
-sed -i '/^c3\|^c4\|^c5\|^c6/s/^/# /' $rootfs/etc/inittab
-
-# In a container, use shutdown for powerfail conditions.  LXC sends the SIGPWR
-# signal to init to shut down the container with lxc-stop and without this the
-# container will be force stopped after a one minute timeout.
-sed -i "s,pf::powerfail:/sbin/genpowerfail start,pf::powerfail:/sbin/shutdown -h now,g" $rootfs/etc/inittab
-sed -i "s,pg::powerokwait:/sbin/genpowerfail stop,pg::powerokwait:/sbin/shutdown -c,g" $rootfs/etc/inittab
-
-# set a default combination for the luggage
-echo "root:root" | chroot $rootfs chpasswd
-echo "Root default password is 'root', please change it!"
-
-# borrow the time configuration from the local machine
-cp -a /etc/localtime $rootfs/etc/localtime
-
-return 0
+    
+    # Back up the existing init scripts and install the lxc versions:
+    ( cd $rootfs/etc/rc.d
+      cp -a /usr/share/lxc/scripts/slackware/* .
+      chmod 755 *.lxc
+      for file in *.lxc ; do
+          cp -a $(basename $file .lxc) $(basename $file .lxc).orig
+          cp -a $file $(basename $file .lxc)
+      done
+    )
+    
+    # restart rc.inet1 to have routing for the loop device
+    echo "/etc/rc.d/rc.inet1 restart" >> $rootfs/etc/rc.d/rc.local
+    
+    # reduce the number of local consoles: two should be enough
+    sed -i '/^c3\|^c4\|^c5\|^c6/s/^/# /' $rootfs/etc/inittab
+    
+    # In a container, use shutdown for powerfail conditions.  LXC sends the SIGPWR
+    # signal to init to shut down the container with lxc-stop and without this the
+    # container will be force stopped after a one minute timeout.
+    sed -i "s,pf::powerfail:/sbin/genpowerfail start,pf::powerfail:/sbin/shutdown -h now,g" $rootfs/etc/inittab
+    sed -i "s,pg::powerokwait:/sbin/genpowerfail stop,pg::powerokwait:/sbin/shutdown -c,g" $rootfs/etc/inittab
+    
+    # set a default combination for the luggage
+    echo "root:root" | chroot $rootfs chpasswd
+    echo "Root default password is 'root', please change it!"
+    
+    # borrow the time configuration from the local machine
+    cp -a /etc/localtime $rootfs/etc/localtime
+    
+    return 0
 }
 
 copy_slackware()
 {
-rootfs=$1
-
-# make a local copy of the installed filesystem
-echo -n "Copying rootfs to $rootfs..."
-mkdir -p $rootfs
-cp -a $cache/rootfs-$release-$arch/* $rootfs/ || exit 1
-
-# fix fstab with the actual path
-sed -i "s|$cache/rootfs-$release-$arch|$rootfs|" $rootfs/etc/fstab
-
-return 0
+    rootfs=$1
+    
+    # make a local copy of the installed filesystem
+    echo -n "Copying rootfs to $rootfs..."
+        mkdir -p $rootfs
+    cp -a $cache/rootfs-$release-$arch/* $rootfs/ || exit 1
+    
+    # fix fstab with the actual path
+    sed -i "s|$cache/rootfs-$release-$arch|$rootfs|" $rootfs/etc/fstab
+    
+    return 0
 }
 
 install_slackware()
 {
-rootfs=$1
-mkdir -p /var/lock/subsys/
-(
-flock -n -x 200
-if [ $? -ne 0 ]; then
-	echo "Cache repository is busy."
-	return 1
-fi
-
-if [ "$arch" == "x86_64" ]; then
-        PKGMAIN=slackware64
-elif [ "$arch" == "arm" ]; then
-        PKGMAIN=slackwarearm
-else
-	PKGMAIN=slackware
-fi
-
-export CONF=$cache/slackpkg-conf
-export ROOT=$cache/rootfs-$release-$arch
-
-mkdir -p $cache/cache-$release-$arch $cache/rootfs-$release-$arch \
-  $cache/slackpkg-$release-$arch $CONF/templates
-
-echo "$MIRROR/$PKGMAIN-$release/" > $CONF/mirrors
-touch $CONF/blacklist
-
-cat <<EOF > $CONF/slackpkg.conf
+    rootfs=$1
+        mkdir -p /var/lock/subsys-$LOGNAME/
+    (
+        flock -n -x 200
+        if [ $? -ne 0 ]; then
+        	echo "Cache repository is busy."
+        	return 1
+        fi
+        
+        if [ "$arch" == "x86_64" ]; then
+                PKGMAIN=slackware64
+        elif [ "$arch" == "arm" ]; then
+                PKGMAIN=slackwarearm
+        else
+        	PKGMAIN=slackware
+        fi
+        
+        export CONF=$cache/slackpkg-conf
+        export ROOT=$cache/rootfs-$release-$arch
+        
+        mkdir -p $cache/cache-$release-$arch $cache/rootfs-$release-$arch \
+            $cache/slackpkg-$release-$arch $CONF/templates
+        
+        echo "$MIRROR/$PKGMAIN-$release/" > $CONF/mirrors
+        touch $CONF/blacklist
+        
+    cat <<EOF > $CONF/slackpkg.conf
 # v2.8
 ARCH=$arch
 TEMP=$cache/cache-$release-$arch
@@ -216,11 +320,12 @@
 USE_INCLUDES=on
 SPINNING=off
 EOF
-
-# thanks to Vincent Batts for this list of packages
-# (that I modified a little :P)
-# http://connie.slackware.com/~vbatts/minimal/
-cat <<EOF > $CONF/templates/minimal-lxc.template
+    
+    # thanks to Vincent Batts for this list of packages
+    # (that I modified a little :P)
+    # http://connie.slackware.com/~vbatts/minimal/
+    # Added kmod and less - Didier
+    cat <<EOF > $CONF/templates/minimal-lxc.template
 aaa_base
 aaa_elflibs
 aaa_terminfo
@@ -243,6 +348,8 @@
 grep
 gzip
 iputils
+kmod
+less
 logrotate
 mpfr
 net-tools
@@ -267,40 +374,41 @@
 xz
 EOF
 
-TEMPLATE=${TEMPLATE:-minimal-lxc}
-if [ ! "$TEMPLATE" = "minimal-lxc" ]; then
-  if [ -f /etc/slackpkg/templates/$TEMPLATE.template ]; then
-    cat /etc/slackpkg/templates/$TEMPLATE.template \
-      > $CONF/templates/$TEMPLATE.template
-  else
-    TEMPLATE="minimal-lxc"
-  fi
-fi
-
-# clean previous installs
-rm -fR $ROOT/*
-
-slackpkg -default_answer=n update 
-slackpkg install-template $TEMPLATE
-
-# add a slackpkg default mirror
-echo "$MIRROR/$PKGMAIN-$release/" >> $ROOT/etc/slackpkg/mirrors
-
-# blacklist the devs package (we have to use our premade devices).
-# do the same with the kernel packages (we use the host's one),
-# but leave available headers and sources
-echo "devs" >> $ROOT/etc/slackpkg/blacklist
-sed -i \
-  -e "s|^#kernel-|kernel-|" \
-  -e "s|^kernel-headers|#kernel-headers|" \
-  -e "s|^kernel-source|#kernel-source|" \
-  $ROOT/etc/slackpkg/blacklist
-
-return 0
-
-) 200>/var/lock/subsys/lxc
+        TEMPLATE=${TEMPLATE:-minimal-lxc}
+        if [ ! "$TEMPLATE" = "minimal-lxc" ]; then
+          if [ -f /etc/slackpkg/templates/$TEMPLATE.template ]; then
+            cat /etc/slackpkg/templates/$TEMPLATE.template \
+              > $CONF/templates/$TEMPLATE.template
+          else
+            TEMPLATE="minimal-lxc"
+          fi
+        fi
+        
+        # clean previous installs
+        rm -fR $ROOT/*
+        mkdir -p $cache/.gnupg
+        export GNUPGHOME="$cache/.gnupg"
+        slackpkg -default_answer=n update
+        slackpkg install-template $TEMPLATE
+        
+        # add a slackpkg default mirror
+        echo "$MIRROR/$PKGMAIN-$release/" >> $ROOT/etc/slackpkg/mirrors
+        
+        # blacklist the devs package (we have to use our premade devices).
+        # do the same with the kernel packages (we use the host's one),
+        # but leave available headers and sources
+        echo "devs" >> $ROOT/etc/slackpkg/blacklist
+        sed -i \
+          -e "s|^#kernel-|kernel-|" \
+          -e "s|^kernel-headers|#kernel-headers|" \
+          -e "s|^kernel-source|#kernel-source|" \
+          $ROOT/etc/slackpkg/blacklist
+        
+        return 0
+        
+    ) 200>/var/lock/subsys-$LOGNAME/lxc
 
-return $?
+    return $?
 }
 
 copy_configuration()
@@ -343,7 +451,6 @@
 # you can try also this alternative to the line above, whatever suits you better.
 # lxc.cap.drop=sys_admin
 EOF
-
 if [ $? -ne 0 ]; then
 	echo "Failed to add configuration."
 	return 1
@@ -352,6 +459,23 @@
 return 0
 }
 
+copy_configuration_in_userns()
+{
+    path=$1
+    rootfs=$2
+    name=$3
+
+    grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config
+	cat <<EOF >> $path/config
+lxc.autodev = 1
+lxc.utsname = $name
+lxc.tty = 4
+lxc.pts = 1024
+lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed
+lxc.devttydir =
+EOF
+}
+
 clean()
 {
 if [ ! -e $cache ]; then
@@ -370,18 +494,56 @@
 rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
 exit 0
 
-) 200>/var/lock/subsys/lxc
+) 200>/var/lock/subsys-$LOGNAME/lxc
 }
 
+
+remap_userns()
+{
+    path=$1
+
+    if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then
+        chown $LXC_MAPPED_UID $path/config >/dev/null 2>&1
+        chown -R root $path/rootfs >/dev/null 2>&1
+    fi
+
+    if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then
+        chgrp $LXC_MAPPED_GID $path/config >/dev/null 2>&1
+        chgrp -R root $path/rootfs >/dev/null 2>&1
+    fi
+}
+
+
 usage()
 {
 cat <<EOF
-$1 -h|--help -p|--path=<path> --clean
+
+Usage (template $0):
+
+[MIRROR=<mirror>] lxc-create -n <name>  -t slackware [OPTIONS] -- [options]
+
+<mirror> can be a local or remote mirror, like in /etc/slackpkg/mirror
+	Default: http://ftp.slackware.com/pub/slackware	
+<name> is the name you give to the container. Mandatory.
+OPTIONS: general options of lxc-create, see lxc-create -h
+options (of this Slackware template):
+	-p|--path: path to the container. Default:
+		~/.local/share/lxc/<name> (unprivileged container)
+		/var/lib/lxc/<name>       (privileged container)
+	--rootfs: root file system of the container. Default:
+		~/.local/share/lxc/<name>/rootfs (unprivileged container)
+		/var/lib/lxc/<name>/rootfs       (privileged container)
+	-a|--arch: kernel architecture.
+		Default: arch of the running kernel
+	-n|--name: the container's internal hostname.
+		Default: the container's <name> given as argument of lxc-create
+	-c|--clean: clean the cache.
+
 EOF
 return 0
 }
 
-options=$(getopt -o hp:n:a:r:c -l help,rootfs:,path:,name:,arch:,release:,clean --  "$@")
+options=$(getopt -o hp:n:a:r:c -l help,rootfs:,path:,name:,arch:,release:,clean:,mapped-uid:,mapped-gid: --  "$@")
 if [ $? -ne 0 ]; then
 	usage $(basename $0)
 	exit 1
@@ -393,11 +555,13 @@
 case "$1" in
         -h|--help)      usage $0 && exit 0;;
         -p|--path)      path=$2; shift 2;;
-	--rootfs)       rootfs=$2; shift 2;;
-	-a|--arch)      arch=$2; shift 2;; 
-	-r|--release)   release=$2; shift 2;;
-	-n|--name)      name=$2; shift 2;;
-	-c|--clean)     clean=$2; shift 2;;
+		--rootfs)       rootfs=$2; shift 2;;
+		-a|--arch)      arch=$2; shift 2;; 
+		-r|--release)   release=$2; shift 2;;
+		-n|--name)      name=$2; shift 2;;
+		-c|--clean)     clean=$2; shift 2;;
+        --mapped-uid)   LXC_MAPPED_UID=$2; shift 2;;
+        --mapped-gid)   LXC_MAPPED_GID=$2; shift 2;;
         --)             shift 1; break ;;
         *)              break ;;
 esac
@@ -408,6 +572,7 @@
 	exit 0
 fi
 
+
 type installpkg
 if [ $? -ne 0 ]; then
 	echo "'installpkg' command is missing."
@@ -433,11 +598,6 @@
 # If no release version was specified, use current
 release=${release:-current}
 
-if [ -z "$name" ]; then
-	# no name given? set a default one
-	name=slackwarecontainer
-fi
-
 # detect rootfs
 config="$path/config"
 if [ -z "$rootfs" ]; then
@@ -451,6 +611,13 @@
 echo
 
 set -e
+if [ $in_userns -eq 1 ]; then
+	COPY_CONFIGURATION=copy_configuration_in_userns
+    cache=${cache:-~/.cache/lxc/slackware}
+else
+	COPY_CONFIGURATION=copy_configuration
+	cache=${cache:-/var/cache/lxc/slackware}
+fi
 
 install_slackware $rootfs
 if [ $? -ne 0 ]; then
@@ -475,14 +642,19 @@
 	exit 1
 fi
 
-echo
-
-copy_configuration $path $rootfs $name
+$COPY_CONFIGURATION $path $rootfs $name
 if [ $? -ne 0 ]; then
 	echo "Failed to write configuration file."
 	exit 1
 fi
 
+remap_userns $path
+if [ $? -ne 0 ]; then
+    echo "failed to remap files to user"
+    exit 1
+fi
+
+
 if [ ! -z $clean ]; then
 	clean || exit 1
 	exit 0