lxc-2.0.0/0000755061062106075000000000000012701247243007312 500000000000000lxc-2.0.0/configure.ac0000644061062106075000000006767612701247216011546 00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. m4_define([lxc_version_major], 2) m4_define([lxc_version_minor], 0) m4_define([lxc_version_micro], 0) m4_define([lxc_version_beta], []) m4_define([lxc_version_abi], 1.2.0) m4_define([lxc_version_base], [lxc_version_major.lxc_version_minor.lxc_version_micro]) m4_define([lxc_version], [ifelse(lxc_version_beta, [], [lxc_version_base], [lxc_version_base.lxc_version_beta])]) AC_INIT([lxc], [lxc_version]) # We need pkg-config PKG_PROG_PKG_CONFIG AC_SUBST(LXC_VERSION_BASE, lxc_version_base) AC_SUBST(LXC_VERSION_BETA, lxc_version_beta) AC_SUBST([LXC_VERSION_MAJOR], [lxc_version_major]) AC_SUBST([LXC_VERSION_MINOR], [lxc_version_minor]) AC_SUBST([LXC_VERSION_MICRO], [lxc_version_micro]) AC_SUBST([LXC_VERSION_ABI], [lxc_version_abi]) AC_SUBST([LXC_VERSION], [lxc_version]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_HEADERS([src/config.h]) AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects]) AC_CANONICAL_HOST AM_PROG_CC_C_O AC_GNU_SOURCE # Detect the distribution. This is used for the default configuration and # for some distro-specific build options. AC_MSG_CHECKING([host distribution]) AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO], [Specify the Linux distribution to target: One of redhat, oracle, centos, fedora, suse, gentoo, debian, arch, slackware, plamo, paldo, openmandriva, pardus, sparclinux, altlinux.])) if type lsb_release >/dev/null 2>&1 && test "z$with_distro" = "z"; then with_distro=`lsb_release -is` fi if test "z$with_distro" = "z"; then AC_CHECK_FILE(/etc/redhat-release,with_distro="redhat") AC_CHECK_FILE(/etc/oracle-release,with_distro="oracle") AC_CHECK_FILE(/etc/sparclinux-release,with_distro="sparclinux") AC_CHECK_FILE(/etc/centos-release,with_distro="centos") AC_CHECK_FILE(/etc/fedora-release,with_distro="fedora") AC_CHECK_FILE(/etc/SuSE-release,with_distro="suse") AC_CHECK_FILE(/etc/gentoo-release,with_distro="gentoo") AC_CHECK_FILE(/etc/debian_version,with_distro="debian") AC_CHECK_FILE(/etc/arch-release,with_distro="arch") AC_CHECK_FILE(/etc/slackware-version,with_distro="slackware") AC_CHECK_FILE(/etc/plamo-version,with_distro="plamo") AC_CHECK_FILE(/etc/frugalware-release,with_distro="frugalware") AC_CHECK_FILE(/etc/mandrakelinux-release, with_distro="openmandriva") AC_CHECK_FILE(/etc/mandriva-release,with_distro="openmandriva") AC_CHECK_FILE(/etc/pardus-release,with_distro="pardus") AC_CHECK_FILE(/etc/altlinux-release,with_distro="altlinux") fi with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]'` if test "z$with_distro" = "zforsparc"; then with_distro="sparclinux" fi if test "z$with_distro" = "z"; then with_distro="unknown" fi case $with_distro in ubuntu|raspbian) distroconf=default.conf.lxcbr distrosysconf="$sysconfdir/default" ;; redhat|centos|fedora|oracle|oracleserver|sparclinux|altlinux|suse|opensuse*|plamo) distroconf=default.conf.lxcbr distrosysconf="$sysconfdir/sysconfig" ;; *) distroconf=default.conf.unknown distrosysconf="$sysconfdir/default" ;; esac AC_MSG_RESULT([$with_distro]) AM_CONDITIONAL([HAVE_DEBIAN], [test x"$with_distro" = "xdebian" -o x"$with_distro" = "xubuntu" -o x"$with_distro" = "xraspbian"]) AM_CONDITIONAL([DISTRO_UBUNTU], [test "x$with_distro" = "xubuntu"]) AC_CONFIG_LINKS([config/etc/default.conf:config/etc/${distroconf}]) # Check for init system type AC_MSG_CHECKING([for init system type]) AC_ARG_WITH([init-script], [AC_HELP_STRING([--with-init-script@<:@=TYPE@<:@,TYPE,...@:>@@:>@], [Type(s) of init script to install: sysvinit, systemd, upstart, distro @<:@default=distro@:>@])],[],[with_init_script=distro]) case "$with_init_script" in distro) case $with_distro in fedora|altlinux|opensuse*) init_script=systemd ;; redhat|centos|oracle|oracleserver|sparclinux|plamo) init_script=sysvinit ;; debian|raspbian) init_script=upstart,systemd ;; ubuntu) init_script=upstart,systemd ;; *) echo -n "Linux distribution init system unknown." init_script= ;; esac ;; *) init_script=$with_init_script ;; esac # Check valid init systems were given, run in subshell so we don't mess up IFS (IFS="," ; for init_sys in $init_script; do case "$init_sys" in none|sysvinit|systemd|upstart) ;; *) exit 1 ;; esac done) || AC_MSG_ERROR([Unknown init system type in $init_script]) AM_CONDITIONAL([INIT_SCRIPT_SYSV], [echo "$init_script" |grep -q "sysvinit"]) AM_CONDITIONAL([INIT_SCRIPT_SYSTEMD], [echo "$init_script" |grep -q "systemd"]) AM_CONDITIONAL([INIT_SCRIPT_UPSTART], [echo "$init_script" |grep -q "upstart"]) AC_MSG_RESULT($init_script) # systemd unit dir AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) if test -z "$with_systemdsystemunitdir"; then with_systemdsystemunitdir=/lib/systemd/system fi if test "x$with_systemdsystemunitdir" != "xno"; then AC_SUBST([SYSTEMD_UNIT_DIR], [$with_systemdsystemunitdir]) fi # Allow enabling deprecated executables AC_ARG_ENABLE([deprecated], [AC_HELP_STRING([--enable-deprecated], [enable deprecated executables [default=no]])], [], [enable_deprecated=false]) AM_CONDITIONAL([ENABLE_DEPRECATED], [test "x$enable_deprecated" = "xyes"]) # Allow disabling rpath AC_ARG_ENABLE([rpath], [AC_HELP_STRING([--enable-rpath], [set rpath in executables [default=no]])], [], [enable_rpath=no]) AM_CONDITIONAL([ENABLE_RPATH], [test "x$enable_rpath" = "xyes"]) # Documentation (manpages) AC_ARG_ENABLE([doc], [AC_HELP_STRING([--enable-doc], [make man pages [default=auto]])], [], [enable_doc=auto]) if test "x$enable_doc" = "xyes" -o "x$enable_doc" = "xauto"; then db2xman="" dbparsers="docbook2x-man db2x_docbook2man docbook2man docbook-to-man" AC_MSG_CHECKING(for docbook2x-man) for name in ${dbparsers}; do if "$name" --help >/dev/null 2>&1; then db2xman="$name" break; fi done if test -n "${db2xman}"; then AC_MSG_RESULT([${db2xman}]) enable_doc="yes" else AC_MSG_RESULT([no]) if test "x$enable_doc" = "xyes"; then AC_MSG_ERROR([docbook2x-man is required, but could not be found]) fi enable_doc="no" fi AC_SUBST(db2xman) fi AM_CONDITIONAL([ENABLE_DOCBOOK], [test "x$db2xman" != "x"]) AM_CONDITIONAL([USE_DOCBOOK2X], [test "x$db2xman" != "xdocbook2man"]) if test "x$db2xman" = "xdocbook2man"; then docdtd="\"-//Davenport//DTD DocBook V3.0//EN\"" else docdtd="\"-//OASIS//DTD DocBook XML\" \"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd\"" fi AC_SUBST(docdtd) # Documentation (API) AC_ARG_ENABLE([api-docs], [AC_HELP_STRING([--enable-api-docs], [make API documentation [default=auto]])], [], [enable_api_docs=auto]) if test "x$enable_api_docs" = "xyes" -o "x$enable_api_docs" = "xauto"; then AC_CHECK_PROGS([HAVE_DOXYGEN],[doxygen]) AC_SUBST([HAVE_DOXYGEN]) if test "x$HAVE_DOXYGEN" != "x"; then enable_api_docs="yes" else if test "x$enable_api_docs" = "xyes"; then AC_MSG_ERROR([doxygen is required, but could not be found]) fi enable_api_docs="no" fi fi AM_CONDITIONAL([ENABLE_API_DOCS], [test "x$HAVE_DOXYGEN" != "x"]) # Apparmor AC_ARG_ENABLE([apparmor], [AC_HELP_STRING([--enable-apparmor], [enable apparmor support [default=auto]])], [], [enable_apparmor=auto]) if test "$enable_apparmor" = "auto" ; then AC_CHECK_LIB([apparmor],[aa_change_profile],[enable_apparmor=yes], [enable_apparmor=no]) fi AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"]) AC_CHECK_LIB([gnutls], [gnutls_hash_fast], [enable_gnutls=yes], [enable_gnutls=no]) AM_COND_IF([ENABLE_APPARMOR], [AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])]) AC_SUBST([APPARMOR_LIBS], [-lapparmor])]) # SELinux AC_ARG_ENABLE([selinux], [AC_HELP_STRING([--enable-selinux], [enable SELinux support [default=auto]])], [], [enable_selinux=auto]) if test "x$enable_selinux" = xauto; then AC_CHECK_LIB([selinux],[setexeccon_raw],[enable_selinux=yes],[enable_selinux=no]) fi AM_CONDITIONAL([ENABLE_SELINUX], [test "x$enable_selinux" = "xyes"]) AM_COND_IF([ENABLE_SELINUX], [AC_CHECK_HEADER([selinux/selinux.h],[],[AC_MSG_ERROR([You must install the SELinux development package in order to compile lxc])]) AC_CHECK_LIB([selinux], [setexeccon_raw],[true],[AC_MSG_ERROR([You must install the SELinux development package in order to compile lxc])]) AC_SUBST([SELINUX_LIBS], [-lselinux])]) # Seccomp syscall filter AC_ARG_ENABLE([seccomp], [AC_HELP_STRING([--enable-seccomp], [enable seccomp support [default=auto]])], [], [enable_seccomp=auto]) if test "x$enable_seccomp" = "xauto" ; then AC_CHECK_LIB([seccomp],[seccomp_init],[enable_seccomp=yes],[enable_seccomp=no]) fi AM_CONDITIONAL([ENABLE_SECCOMP], [test "x$enable_seccomp" = "xyes"]) AM_COND_IF([ENABLE_SECCOMP], [PKG_CHECK_MODULES([SECCOMP],[libseccomp],[],[ AC_CHECK_HEADER([seccomp.h],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) AC_CHECK_LIB([seccomp], [seccomp_init],[],[AC_MSG_ERROR([You must install the seccomp development package in order to compile lxc])]) AC_SUBST([SECCOMP_LIBS], [-lseccomp]) ]) ]) # cgmanager AC_ARG_ENABLE([cgmanager], [AC_HELP_STRING([--enable-cgmanager], [enable cgmanager support [default=auto]])], [], [enable_cgmanager=auto]) if test "x$enable_cgmanager" = "xauto" ; then AC_CHECK_LIB([cgmanager],[cgmanager_create],[enable_cgmanager=yes],[enable_cgmanager=no],[-lnih -lnih-dbus -ldbus-1]) fi AM_CONDITIONAL([ENABLE_CGMANAGER], [test "x$enable_cgmanager" = "xyes"]) AM_COND_IF([ENABLE_CGMANAGER], [PKG_CHECK_MODULES([CGMANAGER], [libcgmanager]) PKG_CHECK_MODULES([NIH], [libnih >= 1.0.2]) PKG_CHECK_MODULES([NIH_DBUS], [libnih-dbus >= 1.0.0]) PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.2.16]) ]) AC_MSG_CHECKING(for get_pid_cgroup_abs_sync) save_LIBS=$LIBS AC_SEARCH_LIBS([cgmanager_get_pid_cgroup_abs_sync], [cgmanager], [have_abs_cgroups=yes], [have_abs_cgroups=no], [-lnih -lnih-dbus -ldbus-1]) LIBS=$save_LIBS if test "x$have_abs_cgroups" = "xyes"; then AC_DEFINE([HAVE_CGMANAGER_GET_PID_CGROUP_ABS_SYNC], 1, [Have cgmanager_get_pid_cgroup_abs_sync]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AC_MSG_CHECKING(for cgmanager_list_controllers) save_LIBS=$LIBS AC_SEARCH_LIBS([cgmanager_list_controllers_sync], [cgmanager], [have_list_controllers=yes], [have_list_controllers=no], [-lnih -lnih-dbus -ldbus-1]) LIBS=$save_LIBS if test "x$have_list_controllers" = "xyes"; then AC_DEFINE([HAVE_CGMANAGER_LIST_CONTROLLERS], 1, [Have cgmanager_list_controllers]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi # Check for static libcap, make sure the function checked for differs from the # the one checked below so the cache doesn't give a wrong answer OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -static" AC_CHECK_LIB([cap],[cap_init],[have_static_libcap=yes],[have_static_libcap=no]) AM_CONDITIONAL([HAVE_STATIC_LIBCAP], [test "x$have_static_libcap" = "xyes"]) if test "x$have_static_libcap" = "xyes"; then AC_DEFINE([HAVE_STATIC_LIBCAP], 1, [Have static libcap]) fi CFLAGS="$OLD_CFLAGS" # Linux capabilities AC_ARG_ENABLE([capabilities], [AC_HELP_STRING([--enable-capabilities], [enable kernel capabilities support [default=auto]])], [], [enable_capabilities=auto]) if test "x$enable_capabilities" = "xauto"; then AC_CHECK_LIB([cap],[cap_set_proc],[enable_capabilities=yes],[enable_capabilities=no]) fi AM_CONDITIONAL([ENABLE_CAP], [test "x$enable_capabilities" = "xyes"]) AM_COND_IF([ENABLE_CAP], [AC_CHECK_LIB(cap,cap_set_proc,[true],[AC_MSG_ERROR([You are missing libcap support.])]) AC_SUBST([CAP_LIBS], [-lcap])]) # HAVE_SCMP_FILTER_CTX=1 will tell us we have libseccomp api >= 1.0.0 OLD_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $SECCOMP_CFLAGS" AC_CHECK_TYPES([scmp_filter_ctx], [], [], [[#include ]]) AC_CHECK_DECLS([seccomp_syscall_resolve_name_arch], [], [], [[#include ]]) CFLAGS="$OLD_CFLAGS" # Configuration examples AC_ARG_ENABLE([examples], [AC_HELP_STRING([--enable-examples], [install examples [default=yes]])], [], [enable_examples=yes]) AM_CONDITIONAL([ENABLE_EXAMPLES], [test "x$enable_examples" = "xyes"]) # Python3 module and scripts AC_ARG_ENABLE([python], [AC_HELP_STRING([--enable-python], [enable python binding [default=auto]])], [], [enable_python=auto]) if test "x$enable_python" = "xauto"; then PKG_CHECK_MODULES([PYTHONDEV], [python3 >= 3.2],[enable_python=yes],[enable_python=no]) if test "$CC" = "clang"; then enable_python=no fi fi if test "x$enable_python" = "xyes" && test "$CC" = "clang"; then AC_MSG_ERROR([Python3 is incompatible with the clang compiler]) fi AM_CONDITIONAL([ENABLE_PYTHON], [test "x$enable_python" = "xyes"]) AM_COND_IF([ENABLE_PYTHON], [AM_PATH_PYTHON([3.2], [], [AC_MSG_ERROR([You must install python3])]) PKG_CHECK_MODULES([PYTHONDEV], [python3 >= 3.2],[],[AC_MSG_ERROR([You must install python3-dev])]) AC_DEFINE_UNQUOTED([ENABLE_PYTHON], 1, [Python3 is available])]) # Enable dumping stack traces AC_ARG_ENABLE([mutex-debugging], [AC_HELP_STRING([--enable-mutex-debugging], [Makes mutexes to report error and provide stack trace [default=no]])], [], [enable_mutex_debugging=no]) AM_CONDITIONAL([MUTEX_DEBUGGING], [test "x$enable_mutex_debugging" = "xyes"]) AM_COND_IF([MUTEX_DEBUGGING], AC_DEFINE_UNQUOTED([MUTEX_DEBUGGING], 1, [Enabling mutex debugging])) # Not in older autoconf versions # AS_VAR_COPY(DEST, SOURCE) # ------------------------- # Set the polymorphic shell variable DEST to the contents of the polymorphic # shell variable SOURCE. m4_ifdef([AS_VAR_COPY], [], [AC_DEFUN([AS_VAR_COPY], [AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])]) ]) dnl PKG_CHECK_VAR was introduced with pkg-config 0.28 m4_ifdef([PKG_CHECK_VAR], [], [AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])# PKG_CHECK_VAR ]) # Lua module and scripts AC_ARG_ENABLE([lua], [AC_HELP_STRING([--enable-lua], [enable lua binding [default=auto]])], [], [enable_lua=auto]) AC_ARG_WITH([lua-pc], [AS_HELP_STRING( [--with-lua-pc=PKG], [Specify pkg-config package name for lua] )], [], [with_lua_pc=no]) if test "x$enable_lua" = "xyes" -a "x$with_lua_pc" != "xno"; then # exit with error if not found PKG_CHECK_MODULES([LUA], [$with_lua_pc], [LUAPKGCONFIG=$with_lua_pc]) fi if test "x$enable_lua" = "xauto" -a "x$with_lua_pc" != "xno"; then PKG_CHECK_MODULES([LUA], [$with_lua_pc], [LUAPKGCONFIG=$with_lua_pc enable_lua=yes], [enable_lua=no]) fi if test "x$enable_lua" != "xno"; then PKG_CHECK_MODULES([LUA], [lua], [LUAPKGCONFIG=lua], [PKG_CHECK_MODULES([LUA], [lua5.2], [LUAPKGCONFIG=lua5.2], [PKG_CHECK_MODULES([LUA], [lua5.1], [LUAPKGCONFIG=lua5.1], [AS_IF([test "x$enable_lua" = "xyes"], [AC_MSG_ERROR([Lua not found. Please use --with-lua-pc=PKG])], [enable_lua=no])] )] )]) AS_IF([test "x$LUAPKGCONFIG" != "x"], [enable_lua=yes]) fi AM_CONDITIONAL([ENABLE_LUA], [test "x$enable_lua" = "xyes"]) AM_COND_IF([ENABLE_LUA], [AC_MSG_CHECKING([Lua version]) PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [V],, [PKG_CHECK_VAR([LUA_VERSION], [$LUAPKGCONFIG], [major_version])]) AC_MSG_RESULT([$LUA_VERSION]) AC_SUBST([LUA_LIBDIR], [$libdir/lua/$LUA_VERSION]) AC_SUBST([LUA_SHAREDIR], [$datadir/lua/$LUA_VERSION]) ]) # Optional bash integration AC_ARG_ENABLE([bash], [AC_HELP_STRING([--enable-bash], [build bash integration [default=yes]])], [], [enable_bash=yes]) AM_CONDITIONAL([ENABLE_BASH], [test "x$enable_bash" = "xyes"]) # Optional test binaries AC_ARG_ENABLE([tests], [AC_HELP_STRING([--enable-tests], [build test/example binaries [default=no]])], [], [enable_tests=no]) AM_CONDITIONAL([ENABLE_TESTS], [test "x$enable_tests" = "xyes"]) # Allow overriding the default runtime dir (/run) AC_ARG_WITH([runtime-path], [AC_HELP_STRING( [--with-runtime-path=dir], [runtime directory (default: /run)] )], [], [with_runtime_path=['/run']]) # LXC container path, where the containers are actually stored # This is overridden by an entry in the file called LXCCONF # (i.e. /etc/lxc/lxc.conf) AC_ARG_WITH([config-path], [AC_HELP_STRING( [--with-config-path=dir], [lxc configuration repository path] )], [], [with_config_path=['${localstatedir}/lib/lxc']]) # The path of the global lxc configuration file. AC_ARG_WITH([global-conf], [AC_HELP_STRING( [--with-global-conf=dir], [global lxc configuration file] )], [], [with_global_conf=['${sysconfdir}/lxc/lxc.conf']]) # The path of the userns network configuration file AC_ARG_WITH([usernic-conf], [AC_HELP_STRING( [--with-usernic-conf], [user network interface configuration file] )], [], [with_usernic_conf=['${sysconfdir}/lxc/lxc-usernet']]) # The path of the runtime usernic database AC_ARG_WITH([usernic-db], [AC_HELP_STRING( [--with-usernic-db], [lxc user nic database] )], [], [with_usernic_db=['${with_runtime_path}/lxc/nics']]) # Rootfs path, where the container mount structure is assembled AC_ARG_WITH([rootfs-path], [AC_HELP_STRING( [--with-rootfs-path=dir], [lxc rootfs mount point] )], [], [with_rootfs_path=['${libdir}/lxc/rootfs']]) # cgroup pattern specification AC_ARG_WITH([cgroup-pattern], [AC_HELP_STRING( [--with-cgroup-pattern=pattern], [pattern for container cgroups] )], [], [with_cgroup_pattern=['/lxc/%n']]) # Container log path. By default, use $lxcpath. AC_MSG_CHECKING([Whether to place logfiles in container config path]) AC_ARG_ENABLE([configpath-log], [AC_HELP_STRING([--enable-configpath-log], [use logfiles in config path [default=no]])], [], [enable_configpath_log=no]) AC_MSG_RESULT([$enable_configpath_log]) AM_CONDITIONAL([USE_CONFIGPATH_LOGS], [test "$enable_configpath_log" = "yes"]) if test "$enable_configpath_log" = "yes"; then default_log_path="${with_config_path}" else default_log_path="${localstatedir}/log/lxc" fi AC_ARG_WITH([log-path], [AC_HELP_STRING( [--with-log-path=dir], [per container log path] )], [], [with_log_path=['${default_log_path}']]) # Expand some useful variables AS_AC_EXPAND(PREFIX, "$prefix") AS_AC_EXPAND(LIBDIR, "$libdir") AS_AC_EXPAND(BINDIR, "$bindir") AS_AC_EXPAND(SBINDIR, "$sbindir") AS_AC_EXPAND(LIBEXECDIR, "$libexecdir") AS_AC_EXPAND(INCLUDEDIR, "$includedir") AS_AC_EXPAND(SYSCONFDIR, "$sysconfdir") AS_AC_EXPAND(LXC_DEFAULT_CONFIG, "$sysconfdir/lxc/default.conf") AS_AC_EXPAND(DATADIR, "$datadir") AS_AC_EXPAND(LOCALSTATEDIR, "$localstatedir") AS_AC_EXPAND(DOCDIR, "$docdir") AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date)") AS_AC_EXPAND(LXCPATH, "$with_config_path") AS_AC_EXPAND(LXC_GLOBAL_CONF, "$with_global_conf") AS_AC_EXPAND(LXC_USERNIC_CONF, "$with_usernic_conf") AS_AC_EXPAND(LXC_USERNIC_DB, "$with_usernic_db") AS_AC_EXPAND(LXC_DISTRO_SYSCONF, "$distrosysconf") AS_AC_EXPAND(LXCROOTFSMOUNT, "$with_rootfs_path") AS_AC_EXPAND(LXCTEMPLATEDIR, "$datadir/lxc/templates") AS_AC_EXPAND(LXCTEMPLATECONFIG, "$datadir/lxc/config") AS_AC_EXPAND(LXCHOOKDIR, "$datadir/lxc/hooks") AS_AC_EXPAND(LXCBINHOOKDIR, "$libexecdir/lxc/hooks") AS_AC_EXPAND(LXCINITDIR, "$libexecdir") AS_AC_EXPAND(LOGPATH, "$with_log_path") AS_AC_EXPAND(RUNTIME_PATH, "$with_runtime_path") AC_SUBST(DEFAULT_CGROUP_PATTERN, ["$with_cgroup_pattern"]) # We need the install path so criu knows where to reference the hook scripts. AC_DEFINE_UNQUOTED([DATADIR], "$DATADIR", ["Prefix for shared files."]) # Check for some standard kernel headers AC_CHECK_HEADERS([linux/unistd.h linux/netlink.h linux/genetlink.h], [], AC_MSG_ERROR([Please install the Linux kernel headers.]), [#include ]) # Check for alternate C libraries AC_MSG_CHECKING(for bionic libc) AC_COMPILE_IFELSE([AC_LANG_PROGRAM( [[#ifndef __ANDROID__ error: Not bionic! #endif]])], [is_bionic=yes], [is_bionic=no]) if test "x$is_bionic" = "xyes"; then AC_DEFINE([IS_BIONIC], 1, [bionic libc]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi AM_CONDITIONAL([IS_BIONIC], [test "x$is_bionic" = "xyes"]) # Some systems lack PR_CAPBSET_DROP definition => HAVE_DECL_PR_CAPBSET_DROP AC_CHECK_DECLS([PR_CAPBSET_DROP], [], [], [#include ]) # Check for some headers AC_CHECK_HEADERS([sys/signalfd.h pty.h ifaddrs.h sys/capability.h sys/personality.h utmpx.h sys/timerfd.h]) # Check for some syscalls functions AC_CHECK_FUNCS([setns pivot_root sethostname unshare rand_r confstr faccessat]) # Check for some functions AC_CHECK_LIB(pthread, main) AC_CHECK_FUNCS(pthread_atfork) AC_CHECK_FUNCS(statvfs) AC_CHECK_LIB(util, openpty) AC_CHECK_FUNCS([openpty hasmntopt setmntent endmntent utmpxname]) AC_CHECK_FUNCS([getline], AM_CONDITIONAL(HAVE_GETLINE, true) AC_DEFINE(HAVE_GETLINE,1,[Have getline]), AM_CONDITIONAL(HAVE_GETLINE, false)) AC_CHECK_FUNCS([getsubopt], AM_CONDITIONAL(HAVE_GETSUBOPT, true) AC_DEFINE(HAVE_GETSUBOPT,1,[Have getsubopt]), AM_CONDITIONAL(HAVE_GETSUBOPT, false)) AC_CHECK_FUNCS([fgetln], AM_CONDITIONAL(HAVE_FGETLN, true) AC_DEFINE(HAVE_FGETLN,1,[Have fgetln]), AM_CONDITIONAL(HAVE_FGETLN, false)) # Check for some libraries AC_SEARCH_LIBS(sem_open, [rt pthread]) AC_SEARCH_LIBS(clock_gettime, [rt]) # Check for some standard binaries AC_PROG_GCC_TRADITIONAL AC_PROG_SED # See if we support thread-local storage. LXC_CHECK_TLS if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -Wall -Werror" fi # Files requiring some variable expansion AC_CONFIG_FILES([ Makefile lxc.pc lxc.spec config/Makefile config/apparmor/Makefile config/selinux/Makefile config/bash/Makefile config/bash/lxc config/init/Makefile config/init/common/Makefile config/init/common/lxc-containers config/init/common/lxc-net config/init/systemd/Makefile config/init/systemd/lxc.service config/init/systemd/lxc@.service config/init/systemd/lxc-net.service config/init/sysvinit/Makefile config/init/sysvinit/lxc-containers config/init/sysvinit/lxc-net config/init/upstart/lxc.conf config/init/upstart/lxc-net.conf config/init/upstart/Makefile config/etc/Makefile config/templates/Makefile config/templates/alpine.common.conf config/templates/alpine.userns.conf config/templates/archlinux.common.conf config/templates/archlinux.userns.conf config/templates/centos.common.conf config/templates/centos.userns.conf config/templates/common.conf config/templates/common.conf.d/Makefile config/templates/debian.common.conf config/templates/debian.userns.conf config/templates/fedora.common.conf config/templates/fedora.userns.conf config/templates/gentoo.common.conf config/templates/gentoo.moresecure.conf config/templates/gentoo.userns.conf config/templates/nesting.conf config/templates/opensuse.common.conf config/templates/opensuse.userns.conf config/templates/oracle.common.conf config/templates/oracle.userns.conf config/templates/plamo.common.conf config/templates/plamo.userns.conf config/templates/slackware.common.conf config/templates/slackware.userns.conf config/templates/ubuntu-cloud.common.conf config/templates/ubuntu-cloud.lucid.conf config/templates/ubuntu-cloud.userns.conf config/templates/ubuntu.common.conf config/templates/ubuntu.lucid.conf config/templates/ubuntu.userns.conf config/templates/openwrt.common.conf config/templates/sparclinux.common.conf config/templates/sparclinux.userns.conf config/templates/userns.conf config/yum/Makefile config/sysconfig/Makefile config/sysconfig/lxc doc/Makefile doc/api/Makefile doc/lxc-attach.sgml doc/lxc-autostart.sgml doc/lxc-cgroup.sgml doc/lxc-checkconfig.sgml doc/lxc-checkpoint.sgml doc/lxc-clone.sgml doc/lxc-config.sgml doc/lxc-console.sgml doc/lxc-copy.sgml doc/lxc-create.sgml doc/lxc-destroy.sgml doc/lxc-device.sgml doc/lxc-execute.sgml doc/lxc-freeze.sgml doc/lxc-info.sgml doc/lxc-ls.sgml doc/lxc-monitor.sgml doc/lxc-snapshot.sgml doc/lxc-start-ephemeral.sgml doc/lxc-start.sgml doc/lxc-stop.sgml doc/lxc-top.sgml doc/lxc-unfreeze.sgml doc/lxc-unshare.sgml doc/lxc-user-nic.sgml doc/lxc-usernsexec.sgml doc/lxc-wait.sgml doc/lxc.conf.sgml doc/lxc.container.conf.sgml doc/lxc.system.conf.sgml doc/lxc-usernet.sgml doc/lxc.sgml doc/common_options.sgml doc/see_also.sgml doc/rootfs/Makefile doc/examples/Makefile doc/examples/lxc-macvlan.conf doc/examples/lxc-vlan.conf doc/examples/lxc-no-netns.conf doc/examples/lxc-empty-netns.conf doc/examples/lxc-phys.conf doc/examples/lxc-veth.conf doc/examples/lxc-complex.conf doc/ja/Makefile doc/ja/lxc-attach.sgml doc/ja/lxc-autostart.sgml doc/ja/lxc-cgroup.sgml doc/ja/lxc-checkconfig.sgml doc/ja/lxc-checkpoint.sgml doc/ja/lxc-clone.sgml doc/ja/lxc-config.sgml doc/ja/lxc-console.sgml doc/ja/lxc-copy.sgml doc/ja/lxc-create.sgml doc/ja/lxc-destroy.sgml doc/ja/lxc-device.sgml doc/ja/lxc-execute.sgml doc/ja/lxc-freeze.sgml doc/ja/lxc-info.sgml doc/ja/lxc-ls.sgml doc/ja/lxc-monitor.sgml doc/ja/lxc-snapshot.sgml doc/ja/lxc-start-ephemeral.sgml doc/ja/lxc-start.sgml doc/ja/lxc-stop.sgml doc/ja/lxc-top.sgml doc/ja/lxc-unfreeze.sgml doc/ja/lxc-unshare.sgml doc/ja/lxc-user-nic.sgml doc/ja/lxc-usernsexec.sgml doc/ja/lxc-wait.sgml doc/ja/lxc.conf.sgml doc/ja/lxc.container.conf.sgml doc/ja/lxc.system.conf.sgml doc/ja/lxc-usernet.sgml doc/ja/lxc.sgml doc/ja/common_options.sgml doc/ja/see_also.sgml doc/ko/Makefile doc/ko/lxc-attach.sgml doc/ko/lxc-autostart.sgml doc/ko/lxc-cgroup.sgml doc/ko/lxc-checkconfig.sgml doc/ko/lxc-checkpoint.sgml doc/ko/lxc-clone.sgml doc/ko/lxc-config.sgml doc/ko/lxc-console.sgml doc/ko/lxc-copy.sgml doc/ko/lxc-create.sgml doc/ko/lxc-destroy.sgml doc/ko/lxc-device.sgml doc/ko/lxc-execute.sgml doc/ko/lxc-freeze.sgml doc/ko/lxc-info.sgml doc/ko/lxc-ls.sgml doc/ko/lxc-monitor.sgml doc/ko/lxc-snapshot.sgml doc/ko/lxc-start-ephemeral.sgml doc/ko/lxc-start.sgml doc/ko/lxc-stop.sgml doc/ko/lxc-top.sgml doc/ko/lxc-unfreeze.sgml doc/ko/lxc-unshare.sgml doc/ko/lxc-user-nic.sgml doc/ko/lxc-usernsexec.sgml doc/ko/lxc-wait.sgml doc/ko/lxc.conf.sgml doc/ko/lxc.container.conf.sgml doc/ko/lxc.system.conf.sgml doc/ko/lxc-usernet.sgml doc/ko/lxc.sgml doc/ko/common_options.sgml doc/ko/see_also.sgml hooks/Makefile templates/Makefile templates/lxc-alpine templates/lxc-altlinux templates/lxc-archlinux templates/lxc-busybox templates/lxc-centos templates/lxc-cirros templates/lxc-debian templates/lxc-download templates/lxc-fedora templates/lxc-gentoo templates/lxc-openmandriva templates/lxc-opensuse templates/lxc-oracle templates/lxc-plamo templates/lxc-slackware templates/lxc-sshd templates/lxc-ubuntu templates/lxc-ubuntu-cloud templates/lxc-sparclinux src/Makefile src/lxc/Makefile src/lxc/lxc-checkconfig src/lxc/lxc-start-ephemeral src/lxc/lxc.functions src/lxc/version.h src/python-lxc/Makefile src/python-lxc/setup.py src/lua-lxc/Makefile src/tests/Makefile src/tests/lxc-test-usernic ]) AC_CONFIG_COMMANDS([default],[[]],[[]]) AC_OUTPUT # Configuration overview cat << EOF ---------------------------- Environment: - compiler: $CC - distribution: $with_distro - init script type(s): $init_script - rpath: $enable_rpath - GnuTLS: $enable_gnutls - Bash integration: $enable_bash Security features: - Apparmor: $enable_apparmor - Linux capabilities: $enable_capabilities - seccomp: $enable_seccomp - SELinux: $enable_selinux - cgmanager: $enable_cgmanager Bindings: - lua: $enable_lua - python3: $enable_python Documentation: - examples: $enable_examples - API documentation: $enable_api_docs - user documentation: $enable_doc Debugging: - tests: $enable_tests - mutex debugging: $enable_mutex_debugging Paths: - Logs in configpath: $enable_configpath_log EOF if test "x$ac_cv_func_pthread_atfork" = "xno" ; then cat << EOF WARNING: Threading not supported on your platform You are compiling LXC for bionic target which lacks certain threading related functionality used by LXC API (like pthread_atfork). Please note that, because of the missing functionality, multithreaded usage of LXC API cause some problems. EOF fi lxc-2.0.0/NEWS0000644061062106075000000000000012701247216007717 00000000000000lxc-2.0.0/COPYING0000644061062106075000000006364212701247216010300 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! lxc-2.0.0/AUTHORS0000644061062106075000000000002112701247216010273 00000000000000IBM Corporation. lxc-2.0.0/templates/0000755061062106075000000000000012701247243011310 500000000000000lxc-2.0.0/templates/lxc-archlinux.in0000644061062106075000000002551312701247216014347 00000000000000#!/bin/bash # # template script for generating Arch Linux container for LXC # # # lxc: linux Container library # Authors: # Alexander Vladimirov # John Lane # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 # defaults arch=$(uname -m) default_path="@LXCPATH@" default_locale="en-US.UTF-8" default_timezone="UTC" pacman_config="/etc/pacman.conf" common_config="@LXCTEMPLATECONFIG@/common.conf" shared_config="@LXCTEMPLATECONFIG@/archlinux.common.conf" # by default, install 'base' except the kernel pkg_blacklist="linux" base_packages=() for pkg in $(pacman -Sqg base); do [ "${pkg_blacklist#*$pkg}" = "$pkg_blacklist" ] && base_packages+=($pkg) done declare -a additional_packages # split comma-separated string into an array # ${1} - string to split # ${2} - separator (default is ",") # ${result} - result value on success split_string() { local ifs=${IFS} IFS="${2:-,}" read -a result < <(echo "${1}") IFS=${ifs} return 0 } [ -f /etc/arch-release ] && is_arch=true # Arch-specific preconfiguration for container configure_arch() { # on ArchLinux, read defaults from host systemd configuration if [ "${is_arch}" ]; then cp -p /etc/locale.conf /etc/locale.gen "${rootfs_path}/etc/" else echo "LANG=${default_locale}" > "${rootfs_path}/etc/locale.conf" if [ -e "${rootfs_path}/etc/locale.gen" ]; then sed -i 's@^#\(en_US\.UTF-8\)@\1@' "${rootfs_path}/etc/locale.gen" if [ ! "${default_locale}" = "en_US.UTF-8" ]; then echo "${default_locale} ${default_locale##*.}" >> \ "${rootfs_path}/etc/locale.gen" fi fi fi # hostname and nameservers echo "${name}" > "${rootfs_path}/etc/hostname" while read r; do [ "${r#nameserver}" = "$r" ] || echo "$r" done < /etc/resolv.conf > "${rootfs_path}/etc/resolv.conf" # chroot and configure system arch-chroot "${rootfs_path}" /bin/bash -s << EOF mkdir /run/lock locale-gen ln -s /usr/share/zoneinfo/${default_timezone} /etc/localtime # set default boot target ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target # override getty@.service for container ttys sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \ -e 's/After=dev-%i.device/After=/' \ < /lib/systemd/system/getty\@.service \ > /etc/systemd/system/getty\@.service # fix systemd-sysctl service sed -e 's/^ConditionPathIsReadWrite=\/proc\/sys\/$/ConditionPathIsReadWrite=\/proc\/sys\/net\//' \ -e 's/^ExecStart=\/usr\/lib\/systemd\/systemd-sysctl$/ExecStart=\/usr\/lib\/systemd\/systemd-sysctl --prefix net/' \ -i /usr/lib/systemd/system/systemd-sysctl.service # initialize pacman keyring pacman-key --init pacman-key --populate archlinux EOF # enable getty on active ttys local nttys=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.tty" | head -n1 | cut -d= -f2 | tr -d "[:blank:]") local devttydir=$(cat "${config_path}/config" ${shared_config} ${common_config} | grep "^lxc.devttydir" | head -n1 | cut -d= -f2 | tr -d "[:blank:]") local devtty="" # bind getty instances to /dev//tty* if lxc.devttydir is set [ -n "${devttydir}" ] && devtty="${devttydir}-" if [ ${nttys:-0} -gt 1 ]; then ( cd "${rootfs_path}/etc/systemd/system/getty.target.wants" for i in $(seq 1 $nttys); do ln -sf "../getty@.service" "getty@${devtty}tty${i}.service"; done ) fi # update securetty to allow console login if devttydir is set if [ -n "${devttydir}" ]; then for i in $(seq 1 ${nttys:-1}); do echo "${devttydir}/tty${i}" >> "${rootfs_path}/etc/securetty" done fi [ -n "${devttydir}" ] && echo "${devttydir}/console" >> "${rootfs_path}/etc/securetty" # Arch default configuration allows only tty1-6 for login [ ${nttys:-0} -gt 6 ] && echo \ "You may want to modify container's /etc/securetty \ file to allow root logins on tty7 and higher" return 0 } # write container configuration files copy_configuration() { mkdir -p "${config_path}" local config="${config_path}/config" echo "lxc.utsname = ${name}" >> "${config}" grep -q "^lxc.arch" "${config}" 2>/dev/null \ || echo "lxc.arch = ${arch}" >> "${config}" grep -q "^lxc.rootfs" "${config}" 2>/dev/null \ || echo "lxc.rootfs = ${rootfs_path}" >> "${config}" [ -e "${shared_config}" ] \ && echo "lxc.include = ${shared_config}" >> "${config}" if [ $? -ne 0 ]; then echo "Failed to configure container" return 1 fi return 0 } # install packages within container chroot install_arch() { [ "${arch}" != "$(uname -m)" ] && different_arch=true if [ "${different_arch}" = "true" ]; then container_pacman_config=$(mktemp) container_mirrorlist=$(mktemp) sed -e "s:Architecture =.*:Architecture = ${arch}:g" \ -e "s:/etc/pacman.d/mirrorlist:${container_mirrorlist}:g" \ "${pacman_config}" > "${container_pacman_config}" sed -e "s:\(x86_64\|\$arch\):${arch}:g" \ /etc/pacman.d/mirrorlist > "${container_mirrorlist}" pacman_config="${container_pacman_config}" fi if ! pacstrap -dcGC "${pacman_config}" "${rootfs_path}" \ ${base_packages[@]}; then echo "Failed to install container packages" return 1 fi if [ "${different_arch}" = "true" ]; then sed -i -e "s:Architecture =.*:Architecture = ${arch}:g" \ "${rootfs_path}"/etc/pacman.conf cp "${container_mirrorlist}" "${rootfs_path}"/etc/pacman.d/mirrorlist rm "${container_pacman_config}" "${container_mirrorlist}" fi [ -d "${rootfs_path}/lib/modules" ] && ldconfig -r "${rootfs_path}" return 0 } usage() { cat < [-p|--path=] [-a|--arch=] [-r|--root_password=] [-P|--packages=] [-e|--enable_units=unit1,unit2...] [-d|--disable_units=unit1,unit2...] [-c|--config=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: -p,--path path to where the container rootfs will be created (${default_path}) --rootfs path for actual container rootfs, (${default_path}/rootfs) -P,--packages preinstall additional packages, comma-separated list -e,--enable_units enable systemd services, comma-separated list -d,--disable_units disable systemd services, comma-separated list -c,--config use specified pacman config when installing container packages -a,--arch use specified architecture instead of host's architecture -r,--root_password set container root password -h,--help print this help EOF return 0 } options=$(getopt -o hp:P:e:d:n:c:a:r: -l help,rootfs:,path:,packages:,enable_units:,disable_units:,name:,config:,arch:,root_password: -- "${@}") if [ ${?} -ne 0 ]; then usage $(basename ${0}) exit 1 fi eval set -- "${options}" while true do case "${1}" in -h|--help) usage ${0} && exit 0;; -p|--path) path=${2}; shift 2;; -n|--name) name=${2}; shift 2;; --rootfs) rootfs_path=${2}; shift 2;; -P|--packages) additional_packages=${2}; shift 2;; -e|--enable_units) enable_units=${2}; shift 2;; -d|--disable_units) disable_units=${2}; shift 2;; -c|--config) pacman_config=${2}; shift 2;; -a|--arch) arch=${2}; shift 2;; -r|--root_password) root_passwd=${2}; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ -z "${name}" ]; then echo "missing required 'name' parameter" exit 1 fi type pacman >/dev/null 2>&1 if [ ${?} -ne 0 ]; then echo "'pacman' command is missing, refer to wiki.archlinux.org for information about installing pacman" exit 1 fi if [ -z "${path}" ]; then path="${default_path}/${name}" fi if [ "${EUID}" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -z "$rootfs_path" ]; then rootfs_path="${path}/rootfs" fi config_path="${path}" revert() { echo "Interrupted, cleaning up" lxc-destroy -n "${name}" rm -rf "${path}/${name}" rm -rf "${default_path}/${name}" exit 1 } trap revert SIGHUP SIGINT SIGTERM copy_configuration if [ ${?} -ne 0 ]; then echo "failed to write configuration file" rm -rf "${config_path}" exit 1 fi if [ ${#additional_packages[@]} -gt 0 ]; then split_string ${additional_packages} base_packages+=(${result[@]}) fi mkdir -p "${rootfs_path}" install_arch if [ ${?} -ne 0 ]; then echo "failed to install Arch Linux" rm -rf "${config_path}" "${path}" exit 1 fi configure_arch if [ ${?} -ne 0 ]; then echo "failed to configure Arch Linux for a container" rm -rf "${config_path}" "${path}" exit 1 fi if [ ${#enable_units[@]} -gt 0 ]; then split_string ${enable_units} for unit in ${result[@]}; do [ "${unit##*.}" = "service" ] || unit="${unit}.service" ln -s "/usr/lib/systemd/system/${unit}" \ "${rootfs_path}/etc/systemd/system/multi-user.target.wants/" done fi if [ ${#disable_units[@]} -gt 0 ]; then split_string ${disable_units} for unit in ${result[@]}; do [ "${unit##*.}" = "service" ] || unit="${unit}.service" ln -s /dev/null "${rootfs_path}/etc/systemd/system/${unit}" done fi if [ -n "${root_passwd}" ]; then echo "root:${root_passwd}" | chroot "${rootfs_path}" chpasswd fi cat << EOF Arch Linux container ${name} is successfully created! The configuration is stored in ${config_path}/config. Please refer to https://wiki.archlinux.org for information about configuring Arch Linux. EOF lxc-2.0.0/templates/lxc-sshd.in0000644061062106075000000001530612701247216013312 00000000000000#!/bin/bash # # lxc: linux Container library # Authors: # Daniel Lezcano # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 install_sshd() { rootfs=$1 tree="\ $rootfs/var/run/sshd \ $rootfs/var/empty/sshd \ $rootfs/var/lib/empty/sshd \ $rootfs/etc/init.d \ $rootfs/etc/rc.d \ $rootfs/etc/ssh \ $rootfs/etc/sysconfig/network-scripts \ $rootfs/dev/shm \ $rootfs/run/shm \ $rootfs/proc \ $rootfs/sys \ $rootfs/bin \ $rootfs/sbin \ $rootfs/usr \ $rootfs/tmp \ $rootfs/home \ $rootfs/root \ $rootfs/lib \ $rootfs/lib64" mkdir -p $tree if [ $? -ne 0 ]; then return 1 fi return 0 } configure_sshd() { rootfs=$1 cat < $rootfs/etc/passwd root:x:0:0:root:/root:/bin/bash sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin EOF cat < $rootfs/etc/group root:x:0:root sshd:x:74: EOF ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key # by default setup root password with no password cat < $rootfs/etc/ssh/sshd_config Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin yes StrictModes yes RSAAuthentication yes PubkeyAuthentication yes IgnoreRhosts yes RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords yes ChallengeResponseAuthentication no EOF if [ -n "$auth_key" -a -f "$auth_key" ]; then u_path="/root/.ssh" root_u_path="$rootfs/$u_path" mkdir -p $root_u_path cp $auth_key "$root_u_path/authorized_keys" chown -R 0:0 "$rootfs/$u_path" chmod 700 "$rootfs/$u_path" echo "Inserted SSH public key from $auth_key into $rootfs/$u_path" fi return 0 } copy_configuration() { path=$1 rootfs=$2 name=$3 init_path=$(realpath --relative-to=/ $(readlink -f /sbin/init)) grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name lxc.pts = 1024 lxc.cap.drop = sys_module mac_admin mac_override sys_time # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined lxc.mount.entry = /dev dev none ro,bind 0 0 lxc.mount.entry = /lib lib none ro,bind 0 0 lxc.mount.entry = /bin bin none ro,bind 0 0 lxc.mount.entry = /usr usr none ro,bind 0 0 lxc.mount.entry = /sbin sbin none ro,bind 0 0 lxc.mount.entry = tmpfs var/run/sshd tmpfs mode=0644 0 0 lxc.mount.entry = @LXCTEMPLATEDIR@/lxc-sshd $init_path none ro,bind 0 0 lxc.mount.entry = /etc/init.d etc/init.d none ro,bind 0 0 lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed EOF # Oracle Linux and Fedora need the following two bind mounted if [ -d /etc/sysconfig/network-scripts ]; then cat <> $path/config lxc.mount.entry = /etc/sysconfig/network-scripts etc/sysconfig/network-scripts none ro,bind 0 0 EOF fi if [ -d /etc/rc.d ]; then cat <> $path/config lxc.mount.entry = /etc/rc.d etc/rc.d none ro,bind 0 0 EOF fi # if no .ipv4 section in config, then have the container run dhcp grep -q "^lxc.network.ipv4" $path/config || touch $rootfs/run-dhcp if [ "$(uname -m)" = "x86_64" ]; then cat <> $path/config lxc.mount.entry = /lib64 lib64 none ro,bind 0 0 EOF fi } usage() { cat < [--rootfs=] EOF return 0 } check_for_cmd() { cmd_path=`type $1` if [ $? -ne 0 ]; then echo "The command '$1' $cmd_path is not accessible on the system" exit 1 fi # we use cut instead of awk because awk is alternatives symlink on ubuntu # and /etc/alternatives isn't bind mounted cmd_path=`echo $cmd_path |cut -d ' ' -f 3` } options=$(getopt -o hp:n:S: -l help,rootfs:,path:,name:,auth-key: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; -S|--auth-key) auth_key=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ $0 = "/sbin/init" ]; then PATH="$PATH:/bin:/sbin:/usr/sbin" check_for_cmd @SBINDIR@/init.lxc check_for_cmd sshd sshd_path=$cmd_path # run dhcp? if [ -f /run-dhcp ]; then check_for_cmd dhclient check_for_cmd ifconfig touch /etc/fstab rm -f /dhclient.conf cat > /dhclient.conf << EOF send host-name = gethostname(); EOF ifconfig eth0 up dhclient eth0 -cf /dhclient.conf echo "Container IP address:" ifconfig eth0 |grep inet fi exec @SBINDIR@/init.lxc -- $sshd_path exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi # detect rootfs config="$path/config" if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi install_sshd $rootfs if [ $? -ne 0 ]; then echo "failed to install sshd's rootfs" exit 1 fi configure_sshd $rootfs if [ $? -ne 0 ]; then echo "failed to configure sshd template" exit 1 fi copy_configuration $path $rootfs $name if [ $? -ne 0 ]; then echo "failed to write configuration file" exit 1 fi lxc-2.0.0/templates/lxc-ubuntu.in0000644061062106075000000006176712701247216013707 00000000000000#!/bin/bash # # template script for generating ubuntu container for LXC # # This script consolidates and extends the existing lxc ubuntu scripts # # Copyright © 2011 Serge Hallyn # Copyright © 2010 Wilhelm Meier # Author: Wilhelm Meier # # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 set -e LOCALSTATEDIR="@LOCALSTATEDIR@" LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" # Allows the lxc-cache directory to be set by environment variable LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"} if [ -r /etc/default/lxc ]; then . /etc/default/lxc fi # Check if given path is in a btrfs partition is_btrfs() { [ -e $1 -a $(stat -f -c '%T' $1) = "btrfs" ] } # Check if given path is the root of a btrfs subvolume is_btrfs_subvolume() { [ -d $1 -a $(stat -f -c '%T' $1) = "btrfs" -a $(stat -c '%i' $1) -eq 256 ] } try_mksubvolume() { path=$1 [ -d $path ] && return 0 mkdir -p $(dirname $path) if which btrfs >/dev/null 2>&1 && is_btrfs $(dirname $path); then btrfs subvolume create $path else mkdir -p $path fi } try_rmsubvolume() { path=$1 [ -d $path ] || return 0 if which btrfs >/dev/null 2>&1 && is_btrfs_subvolume $path; then btrfs subvolume delete $path else rm -rf $path fi } configure_ubuntu() { rootfs=$1 hostname=$2 release=$3 user=$4 password=$5 # configure the network using the dhcp cat < $rootfs/etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp EOF # set the hostname cat < $rootfs/etc/hostname $hostname EOF # set minimal hosts cat < $rootfs/etc/hosts 127.0.0.1 localhost 127.0.1.1 $hostname # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOF if [ ! -f $rootfs/etc/init/container-detect.conf ]; then # suppress log level output for udev sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf # remove jobs for consoles 5 and 6 since we only create 4 consoles in # this template rm -f $rootfs/etc/init/tty{5,6}.conf fi if [ -z "$bindhome" ]; then chroot $rootfs useradd --create-home -s /bin/bash $user echo "$user:$password" | chroot $rootfs chpasswd fi # make sure we have the current locale defined in the container if [ -z "$LANG" ] || echo $LANG | grep -E -q "^C(\..+)*$"; then chroot $rootfs locale-gen en_US.UTF-8 || true chroot $rootfs update-locale LANG=en_US.UTF-8 || true else chroot $rootfs locale-gen $LANG || true chroot $rootfs update-locale LANG=$LANG || true fi # generate new SSH keys if [ -x $rootfs/var/lib/dpkg/info/openssh-server.postinst ]; then cat > $rootfs/usr/sbin/policy-rc.d << EOF #!/bin/sh exit 101 EOF chmod +x $rootfs/usr/sbin/policy-rc.d rm -f $rootfs/etc/ssh/ssh_host_*key* mv $rootfs/etc/init/ssh.conf $rootfs/etc/init/ssh.conf.disabled DPKG_MAINTSCRIPT_PACKAGE=openssh DPKG_MAINTSCRIPT_NAME=postinst chroot $rootfs /var/lib/dpkg/info/openssh-server.postinst configure mv $rootfs/etc/init/ssh.conf.disabled $rootfs/etc/init/ssh.conf sed -i "s/root@$(hostname)/root@$hostname/g" $rootfs/etc/ssh/ssh_host_*.pub rm -f $rootfs/usr/sbin/policy-rc.d fi return 0 } # finish setting up the user in the container by injecting ssh key and # adding sudo group membership. # passed-in user is either 'ubuntu' or the user to bind in from host. finalize_user() { user=$1 sudo_version=$(chroot $rootfs dpkg-query -W -f='${Version}' sudo) if chroot $rootfs dpkg --compare-versions $sudo_version gt "1.8.3p1-1"; then groups="sudo" else groups="sudo admin" fi for group in $groups; do chroot $rootfs groupadd --system $group >/dev/null 2>&1 || true chroot $rootfs adduser ${user} $group >/dev/null 2>&1 || true done if [ -n "$auth_key" -a -f "$auth_key" ]; then u_path="/home/${user}/.ssh" root_u_path="$rootfs/$u_path" mkdir -p $root_u_path cp $auth_key "$root_u_path/authorized_keys" chroot $rootfs chown -R ${user}: "$u_path" echo "Inserted SSH public key from $auth_key into /home/${user}/.ssh/authorized_keys" fi return 0 } # A function to try and autodetect squid-deb-proxy servers on the local network # if either the squid-deb-proxy-client package is installed on the host or # a parent container set the 50squid-deb-proxy-client file. squid_deb_proxy_autodetect() { local apt_discover=/usr/share/squid-deb-proxy-client/apt-avahi-discover local proxy_file=/etc/apt/apt.conf.d/50squid-deb-proxy-client squid_proxy_line= # That's a global :/ # Maybe the host is aware of a squid-deb-proxy? if [ -f $apt_discover ]; then echo -n "Discovering squid-deb-proxy..." squid_proxy_line=$($apt_discover) if [ -n "$squid_proxy_line" ]; then echo "found squid-deb-proxy: $squid_proxy_line" else echo "no squid-deb-proxy found" fi fi # Are we in a nested container, and the parent already knows of a proxy? if [ -f $proxy_file ]; then # Extract the squid URL from the file (whatever is between "") squid_proxy_line=`cat $proxy_file | sed "s/.*\"\(.*\)\".*/\1/"` fi } # # Choose proxies for container # http_proxy will be used by debootstrap on the host. # APT_PROXY will be used to set /etc/apt/apt.conf.d/70proxy in the container. # choose_container_proxy() { local rootfs=$1 local arch=$2 if [ -z "$HTTP_PROXY" ]; then HTTP_PROXY="none" fi case "$HTTP_PROXY" in none) squid_deb_proxy_autodetect if [ -n "$squid_proxy_line" ]; then APT_PROXY=$squid_proxy_line export http_proxy=$squid_proxy_line else APT_PROXY= fi ;; apt) RES=`apt-config shell APT_PROXY Acquire::http::Proxy` eval $RES [ -z "$APT_PROXY" ] || export http_proxy=$APT_PROXY ;; *) APT_PROXY=$HTTP_PROXY export http_proxy=$HTTP_PROXY ;; esac } write_sourceslist() { # $1 => path to the partial cache or the rootfs # $2 => architecture we want to add # $3 => whether to use the multi-arch syntax or not if [ -n "$APT_PROXY" ]; then mkdir -p $1/etc/apt/apt.conf.d cat > $1/etc/apt/apt.conf.d/70proxy << EOF Acquire::http::Proxy "$APT_PROXY" ; EOF fi case $2 in amd64|i386) MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu} ;; *) MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} ;; esac if [ -n "$3" ]; then cat >> "$1/etc/apt/sources.list" << EOF deb [arch=$2] $MIRROR ${release} main restricted universe multiverse deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse EOF else cat >> "$1/etc/apt/sources.list" << EOF deb $MIRROR ${release} main restricted universe multiverse deb $MIRROR ${release}-updates main restricted universe multiverse deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse EOF fi } install_packages() { local rootfs="$1" shift local packages="$*" if [ -z $update ] then chroot $rootfs apt-get update update=true fi if [ -n "${packages}" ] then chroot $rootfs apt-get install --force-yes -y --no-install-recommends ${packages} fi } cleanup() { try_rmsubvolume $cache/partial-$arch try_rmsubvolume $cache/rootfs-$arch } suggest_flush() { echo "Container upgrade failed. The container cache may be out of date," echo "in which case flushing the cache (see -F in the help output) may help." } download_ubuntu() { cache=$1 arch=$2 release=$3 case $2 in amd64|i386) MIRROR=${MIRROR:-http://archive.ubuntu.com/ubuntu} SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.ubuntu.com/ubuntu} ;; *) MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports} SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports} ;; esac packages_template=${packages_template:-"ssh,vim"} debootstrap_parameters= # Try to guess a list of langpacks to install langpacks="language-pack-en" if which dpkg >/dev/null 2>&1; then langpacks=`(echo $langpacks && dpkg -l | grep -E "^ii language-pack-[a-z]* " | cut -d ' ' -f3) | sort -u` fi packages_template="${packages_template},$(echo $langpacks | sed 's/ /,/g')" if [ -n "$variant" ]; then debootstrap_parameters="$debootstrap_parameters --variant=$variant" fi if [ "$variant" = 'minbase' ]; then packages_template="${packages_template},sudo,ifupdown,isc-dhcp-client" fi echo "Installing packages in template: ${packages_template}" trap cleanup EXIT SIGHUP SIGINT SIGTERM # check the mini ubuntu was not already downloaded try_mksubvolume "$cache/partial-$arch" if [ $? -ne 0 ]; then echo "Failed to create '$cache/partial-$arch' directory" return 1 fi choose_container_proxy $cache/partial-$arch/ $arch # download a mini ubuntu into a cache echo "Downloading ubuntu $release minimal ..." if [ -n "$(which qemu-debootstrap)" ]; then qemu-debootstrap --verbose $debootstrap_parameters --components=main,universe --arch=$arch --include=${packages_template} $release $cache/partial-$arch $MIRROR else debootstrap --verbose $debootstrap_parameters --components=main,universe --arch=$arch --include=${packages_template} $release $cache/partial-$arch $MIRROR fi if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi # Serge isn't sure whether we should avoid doing this when # $release == `distro-info -d` echo "Installing updates" > $cache/partial-$arch/etc/apt/sources.list write_sourceslist $cache/partial-$arch/ $arch chroot "$1/partial-${arch}" apt-get update if [ $? -ne 0 ]; then echo "Failed to update the apt cache" return 1 fi cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF #!/bin/sh exit 101 EOF chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y || { suggest_flush; false; } rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d chroot "$1/partial-${arch}" apt-get clean mv "$1/partial-$arch" "$1/rootfs-$arch" trap EXIT trap SIGINT trap SIGTERM trap SIGHUP echo "Download complete" return 0 } copy_ubuntu() { cache=$1 arch=$2 rootfs=$3 # make a local copy of the miniubuntu echo "Copying rootfs to $rootfs ..." try_mksubvolume $rootfs if which btrfs >/dev/null 2>&1 && is_btrfs_subvolume $cache/rootfs-$arch && is_btrfs_subvolume $rootfs; then realrootfs=$(dirname $config)/rootfs [ "$rootfs" = "$realrootfs" ] || umount $rootfs || return 1 btrfs subvolume delete $realrootfs || return 1 btrfs subvolume snapshot $cache/rootfs-$arch $realrootfs || return 1 [ "$rootfs" = "$realrootfs" ] || mount --bind $realrootfs $rootfs || return 1 else rsync -Ha $cache/rootfs-$arch/ $rootfs/ || return 1 fi return 0 } install_ubuntu() { rootfs=$1 release=$2 flushcache=$3 cache="$4/$release" mkdir -p $LOCALSTATEDIR/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi if [ $flushcache -eq 1 ]; then echo "Flushing cache..." try_rmsubvolume $cache/partial-$arch try_rmsubvolume $cache/rootfs-$arch fi echo "Checking cache download in $cache/rootfs-$arch ... " if [ ! -e "$cache/rootfs-$arch" ]; then download_ubuntu $cache $arch $release if [ $? -ne 0 ]; then echo "Failed to download 'ubuntu $release base'" return 1 fi fi echo "Copy $cache/rootfs-$arch to $rootfs ... " copy_ubuntu $cache $arch $rootfs if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>$LOCALSTATEDIR/lock/subsys/lxc-ubuntu$release return $? } copy_configuration() { path=$1 rootfs=$2 name=$3 arch=$4 release=$5 if [ $arch = "i386" ]; then arch="i686" fi # if there is exactly one veth network entry, make sure it has an # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` if [ $nics -eq 1 ]; then grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config fi # Generate the configuration file ## Relocate all the network config entries sed -i -e "/lxc.network/{w ${path}/config-network" -e "d}" $path/config ## Relocate any other config entries sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config ## Add all the includes echo "" >> $path/config echo "# Common configuration" >> $path/config if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu.common.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.common.conf" >> $path/config fi if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu.${release}.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu.${release}.conf" >> $path/config fi ## Add the container-specific config echo "" >> $path/config echo "# Container specific configuration" >> $path/config [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name lxc.arch = $arch EOF ## Re-add the previously removed network config echo "" >> $path/config echo "# Network configuration" >> $path/config cat $path/config-network >> $path/config rm $path/config-network if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } post_process() { rootfs=$1 release=$2 packages=$3 # Disable service startup cat > $rootfs/usr/sbin/policy-rc.d << EOF #!/bin/sh exit 101 EOF chmod +x $rootfs/usr/sbin/policy-rc.d # If the container isn't running a native architecture, setup multiarch if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg) if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then chroot $rootfs dpkg --add-architecture ${hostarch} else mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch fi # Save existing value of MIRROR and SECURITY_MIRROR DEFAULT_MIRROR=$MIRROR DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR # Write a new sources.list containing both native and multiarch entries > ${rootfs}/etc/apt/sources.list write_sourceslist $rootfs $arch "native" MIRROR=$DEFAULT_MIRROR SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR write_sourceslist $rootfs $hostarch "multiarch" # Finally update the lists and install upstart using the host architecture HOST_PACKAGES="upstart:${hostarch} mountall:${hostarch} isc-dhcp-client:${hostarch}" chroot $rootfs apt-get update if chroot $rootfs dpkg -l iproute2 | grep -q ^ii; then HOST_PACKAGES="$HOST_PACKAGES iproute2:${hostarch}" else HOST_PACKAGES="$HOST_PACKAGES iproute:${hostarch}" fi install_packages $rootfs $HOST_PACKAGES fi # Install Packages in container if [ -n "$packages" ] then local packages="`echo $packages | sed 's/,/ /g'`" echo "Installing packages: ${packages}" install_packages $rootfs $packages fi # Set initial timezone as on host if [ -f /etc/timezone ]; then cat /etc/timezone > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata elif [ -f /etc/sysconfig/clock ]; then . /etc/sysconfig/clock echo $ZONE > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata else echo "Timezone in container is not configured. Adjust it manually." fi # rmdir /dev/shm for containers that have /run/shm # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did # get bind mounted to the host's /run/shm. So try to rmdir # it, and in case that fails move it out of the way. # NOTE: This can only be removed once 12.04 goes out of support if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak ln -s /run/shm $rootfs/dev/shm fi # Re-enable service startup rm $rootfs/usr/sbin/policy-rc.d } do_bindhome() { rootfs=$1 user=$2 # copy /etc/passwd, /etc/shadow, and /etc/group entries into container pwd=`getent passwd $user` || { echo "Failed to copy password entry for $user"; false; } echo $pwd >> $rootfs/etc/passwd # make sure user's shell exists in the container shell=`echo $pwd | cut -d: -f 7` if [ ! -x $rootfs/$shell ]; then echo "shell $shell for user $user was not found in the container." pkg=`dpkg -S $(readlink -m $shell) | cut -d ':' -f1` echo "Installing $pkg" install_packages $rootfs $pkg fi shad=`getent shadow $user` echo "$shad" >> $rootfs/etc/shadow # bind-mount the user's path into the container's /home h=`getent passwd $user | cut -d: -f 6` mkdir -p $rootfs/$h # use relative path in container h2=${h#/} while [ ${h2:0:1} = "/" ]; do h2=${h2#/} done echo "lxc.mount.entry = $h $h2 none bind 0 0" >> $path/config # Make sure the group exists in container grp=`echo $pwd | cut -d: -f 4` # group number for $user grpe=`getent group $grp` || return 0 # if host doesn't define grp, ignore in container chroot $rootfs getent group "$grpe" || echo "$grpe" >> $rootfs/etc/group } usage() { cat <] [-d|--debug] [-F | --flush-cache] [-r|--release ] [-v|--variant] [ -S | --auth-key ] [--rootfs ] [--packages ] [-u|--user ] [--password ] [--mirror ] [--security-mirror ] release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS variant: debootstrap variant to use (see debootstrap(8)) bindhome: bind 's home into the container The ubuntu user will not be created, and will have sudo access. arch: the container architecture (e.g. amd64): defaults to host arch auth-key: SSH Public key file to inject into container packages: list of packages to add comma separated mirror,security-mirror: mirror for download and /etc/apt/sources.list EOF return 0 } options=$(getopt -o a:b:hp:r:v:n:FS:du: -l arch:,bindhome:,help,path:,release:,variant:,name:,flush-cache,auth-key:,debug,rootfs:,packages:,user:,password:,mirror:,security-mirror: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems if [ -f /etc/lsb-release ]; then . /etc/lsb-release if [ "$DISTRIB_ID" = "Ubuntu" ]; then release=$DISTRIB_CODENAME fi fi bindhome= # Code taken from debootstrap if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/dpkg --print-architecture` elif which udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/udpkg --print-architecture` else arch=$(uname -m) if [ "$arch" = "i686" ]; then arch="i386" elif [ "$arch" = "x86_64" ]; then arch="amd64" elif [ "$arch" = "armv7l" ]; then arch="armhf" elif [ "$arch" = "aarch64" ]; then arch="arm64" elif [ "$arch" = "ppc64le" ]; then arch="ppc64el" fi fi debug=0 hostarch=$arch flushcache=0 packages="" user="ubuntu" password="ubuntu" while true do case "$1" in -h|--help) usage $0 && exit 0;; --rootfs) rootfs=$2; shift 2;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; -u|--user) user=$2; shift 2;; --password) password=$2; shift 2;; -F|--flush-cache) flushcache=1; shift 1;; -r|--release) release=$2; shift 2;; -v|--variant) variant=$2; shift 2;; --packages) packages=$2; shift 2;; -b|--bindhome) bindhome=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -S|--auth-key) auth_key=$2; shift 2;; -d|--debug) debug=1; shift 1;; --mirror) MIRROR=$2; shift 2;; --security-mirror) SECURITY_MIRROR=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ $debug -eq 1 ]; then set -x fi if [ -n "$bindhome" ]; then pwd=`getent passwd $bindhome` if [ $? -ne 0 ]; then echo "Error: no password entry found for $bindhome" exit 1 fi fi if [ "$arch" = "i686" ]; then arch=i386 fi if [ $hostarch = "i386" -a $arch = "amd64" ]; then echo "can't create $arch container on $hostarch" exit 1 fi if [ $hostarch = "armhf" -o $hostarch = "armel" -o $hostarch = "arm64" ] && \ [ $arch != "armhf" -a $arch != "armel" -a $arch != "arm64" ]; then echo "can't create $arch container on $hostarch" exit 1 fi if [ $arch = "arm64" ] && [ $hostarch != "arm64" ]; then echo "can't create $arch container on $hostarch" exit 1 fi if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then echo "can't create $arch container on $hostarch" exit 1 fi which debootstrap >/dev/null 2>&1 || { echo "'debootstrap' command is missing" >&2; false; } if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi # detect rootfs config="$path/config" # if $rootfs exists here, it was passed in with --rootfs if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi install_ubuntu $rootfs $release $flushcache $LXC_CACHE_PATH if [ $? -ne 0 ]; then echo "failed to install ubuntu $release" exit 1 fi configure_ubuntu $rootfs $name $release $user $password if [ $? -ne 0 ]; then echo "failed to configure ubuntu $release for a container" exit 1 fi copy_configuration $path $rootfs $name $arch $release if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi post_process $rootfs $release $trim_container $packages if [ -n "$bindhome" ]; then do_bindhome $rootfs $bindhome finalize_user $bindhome else finalize_user $user fi echo "" echo "##" if [ -n "$bindhome" ]; then echo "# Log in as user $bindhome" else echo "# The default user is '$user' with password '$password'!" echo "# Use the 'sudo' command to run tasks as root in the container." fi echo "##" echo "" lxc-2.0.0/templates/Makefile.am0000644061062106075000000000052712701247216013270 00000000000000templatesdir=@LXCTEMPLATEDIR@ templates_SCRIPTS = \ lxc-alpine \ lxc-altlinux \ lxc-archlinux \ lxc-busybox \ lxc-centos \ lxc-cirros \ lxc-debian \ lxc-download \ lxc-fedora \ lxc-gentoo \ lxc-openmandriva \ lxc-opensuse \ lxc-oracle \ lxc-plamo \ lxc-slackware \ lxc-sshd \ lxc-ubuntu \ lxc-ubuntu-cloud \ lxc-sparclinux lxc-2.0.0/templates/lxc-gentoo.in0000644061062106075000000006737712701247216013663 00000000000000#!/bin/bash # # LXC template for gentoo # # Author: Guillaume Zitta # # Widely inspired from lxc-gentoo script at https://github.com/globalcitizen/lxc-gentoo # # this version is reworked with : # - out of the lxc-create compat # - vanilla gentoo config # - ready to use cache # # 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 # Ensure strict root's umask doesen't render the VM unusable umask 022 LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" ################################################################################ # Various helper functions ################################################################################ # param: $1: the name of the lock # param: $2: the timeout for the lock # The rest contain the command to execute and its parameters execute_exclusively() { mkdir -p @LOCALSTATEDIR@/lock/subsys/ local lock_name="$1" local timeout="$2" shift 2 { printf "Attempting to obtain an exclusive lock (timeout: %s sec) named \"%s\"...\n" "${timeout}" "$lock_name" flock -x -w "${timeout}" 50 if [[ $? -ne 0 ]]; then printf " => unable to obtain lock, aborting.\n" return 2 else printf " => done.\n" fi printf " => Executing \"%s\"\n" "$*" "$@" retval=$? } 50> "@LOCALSTATEDIR@/lock/subsys/lxc-gentoo-${lock_name}" return $retval } # a die function is always a good idea die() { printf "\n[the last exit code leading to this death was: %s ]\n" "$?" local retval="$1" shift 1 printf "$@" exit "$retval" } # gentoo arch/variant detection set_default_arch() { printf "### set_default_arch: default arch/variant autodetect...\n" arch=$(uname -m) if [[ $arch =~ i.86 ]]; then arch="x86" variant="x86" elif [[ $arch == "x86_64" ]]; then arch="amd64" variant="amd64" elif [[ $arch =~ arm.* ]]; then arch="arm" variant="armv7a" else #who knows, it may work... printf " => warn: unexpected arch:${arch} let me knows if it works :)\n" variant="${arch}" fi printf " => Got: arch=%s variant=%s\n" "${arch}" "${variant}" } store_user_message() { user_message="${user_message}=> $@\n" } ################################################################################ # CACHE Preparation ################################################################################ # during setup cachedir is $cacheroot/partial-$arch-$variant # at the end, it will be $cacheroot/rootfs-$arch-$variant cache_setup(){ partialfs="${cacheroot}/partial-${arch}-${variant}" #if cache exists and flush not needed, return [[ -d "${cachefs}" && -z "${flush_cache}" ]] && return 0 printf "###### cache_setup(): doing cache preparation\n" local retval=1 #clean from failed previous run rm -rf "${partialfs}" mkdir -p "${partialfs}" #let's go cache_precheck && \ cache_stage3 && \ cache_portage && \ cache_inittab && \ cache_net && \ cache_dev && \ cache_openrc && \ cache_locale && \ rm -rf "${cachefs}" && \ mv "${partialfs}" "${cachefs}" && \ printf "###### cache_setup: Cache should be ready\n" return $? } cache_precheck() { printf "### cache_precheck(): doing some pre-start checks ...\n" # never hurts to have a fail-safe. [[ -n "${cacheroot//\/}" ]] \ || die 8 "\$cacheroot (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cacheroot}" } #get latest stage3 tarball cache_stage3() { printf "### cache_stage3(): stage3 cache deployment...\n" if [ -z "${tarball}" ]; then #variables init local stage3_baseurl="${mirror}/releases/${arch}/autobuilds" # get latest-stage3....txt file for subpath local stage3_pointer="${stage3_baseurl}/latest-stage3-${variant}.txt" printf "Determining path to latest Gentoo %s (%s) stage3 archive...\n" "${arch}" "${variant}" printf " => downloading and processing %s\n" "${stage3_pointer}" local stage3_latest_tarball=$(wget -q -O - "${stage3_pointer}" | tail -n1 | cut -d' ' -f1) \ || die 6 "Error: unable to fetch\n" printf " => Got: %s\n" "${stage3_latest_tarball}" printf "Downloading/untarring the actual stage3 tarball...\n" wget -O - "${stage3_baseurl}/${stage3_latest_tarball}" \ | tar -xjpf - --numeric-owner -C "${partialfs}" \ || die 6 "Error: unable to fetch or untar\n" printf " => extracted to: %s\n" "${partialfs}" else printf "Extracting the stage3 tarball...\n" tar -xpf "${tarball}" --numeric-owner -C "${partialfs}" \ || die 6 "unable to untar ${tarball} to ${partialfs}" fi #check if it chroots printf "chroot test..." chroot ${partialfs} /bin/true || die 1 "Error: chroot %s /bin/true, failed" "${partialfs}" printf " OK\n" printf " => stage3 cache extracted in : %s\n" "${partialfs}" return 0 } cache_portage() { printf "### cache_portage: caching portage tree tarball...\n" [[ -z "${flush_cache}" && -f "${portage_cache}" ]] && return 0 rm -f ${portage_cache} printf "Downloading Gentoo portage (software build database) snapshot...\n" execute_exclusively portage 60 wget -O "${portage_cache}" "${mirror}/snapshots/portage-latest.tar.bz2" \ || die 6 "Error: unable to fetch\n" printf " => done.\n" } # custom inittab cache_inittab() { printf "### cache_inittab: tuning inittab...\n" INITTAB="${partialfs}/etc/inittab" [[ -w "$INITTAB" ]] || die 1 "Error: $INITTAB is not writeable" # create console echo "# Lxc main console" >> "$INITTAB" echo "1:12345:respawn:/sbin/agetty -a root --noclear 115200 console linux" >> "$INITTAB" # finally we add a pf line to enable clean shutdown on SIGPWR (issue 60) echo "# clean container shutdown on SIGPWR" >> "$INITTAB" echo "pf:12345:powerwait:/sbin/halt" >> "$INITTAB" # we also blank out /etc/issue here in order to prevent delays spawning login # caused by attempts to determine domainname on disconnected containers sed -i 's/[\][Oo]//g' "${partialfs}/etc/issue" } cache_net() { printf "### cache_net: doing some useful net tuning...\n" # useful for chroot # /etc/resolv.conf grep -i 'search ' /etc/resolv.conf > "${partialfs}/etc/resolv.conf" grep -i 'nameserver ' /etc/resolv.conf >> "${partialfs}/etc/resolv.conf" # fix boot-time interface config wipe under aggressive cap drop # (openrc 0.9.8.4 ~sep 2012 - https://bugs.gentoo.org/show_bug.cgi?id=436266) # initial warkaround was: sed -i -e 's/^#rc_nostop=""/rc_nostop="net.eth0 net.lo"/' "${partialfs}/etc/rc.conf" # but this one does not depends on interfaces names echo 'rc_keyword="-stop"' >> "${partialfs}/etc/conf.d/net" } cache_dev() { printf "### cache_dev(): /dev tuning...\n" #Wait for https://bugs.gentoo.org/show_bug.cgi?id=496054 mkdir "${partialfs}/dev/pts" mkdir "${partialfs}/dev/shm" mkdir "${partialfs}/dev/mqueue" mkdir -m 755 "${partialfs}/dev/net" mknod -m 666 "${partialfs}/dev/net/tun" c 10 200 return 0 } # fix openrc system cache_openrc() { printf "### cache_openrc(): doing openrc tuning\n" #Wait for https://bugs.gentoo.org/show_bug.cgi?id=496054 chroot "${partialfs}" sed s/-lxc//g -i "/etc/init.d/devfs" return 0 } cache_locale() { printf "### cache_locale(): initiating minimale locale en_US.UTF-8 \n" echo "en_US.UTF-8 UTF-8" >> "${partialfs}/etc/locale.gen" chroot "${partialfs}" locale-gen return 0 } ################################################################################ # CONTAINER Preparation ################################################################################ container_setup() { printf "##### container_setup(): starting container setup\n" #in most cases lxc-create should have provided a copy of default lxc.conf #let's tag where template starts, or just create the files echo '### lxc-gentoo template stuff starts here' >> "$path/config" #Determine rootfs #If backingstore was specified, lxc.rootfs should be present or --rootfs did the rootfs var creation if [ -z "${rootfs}" ]; then rootfs=`awk -F= '$1 ~ /^lxc.rootfs/ { print $2 }' "$path/config" 2>/dev/null` if [ -z "${rootfs}" ]; then #OK it's default rootfs="${path}/rootfs" fi fi store_user_message "rootfs of container is : ${rootfs}" store_user_message "config of container is : ${path}/config" container_precheck && \ container_rootfs && \ container_consoles && \ container_tz && \ container_portage && \ container_net && \ container_hostname && \ container_auth && \ container_sshd && \ container_conf if [ $? -ne 0 ]; then die 1 "container_setup(): one step didn't complete, sorry\n" fi printf "###### container_setup(): container should be ready to start!\n" printf "\n\n" printf "You could now use you container with: lxc-start -n %s\n" "${name}" printf "little things you should know about your container:\n" printf "${user_message}" return 0 } container_precheck() { printf "### container_precheck(): doing some pre-start checks ...\n" # never hurts to have a fail-safe. [[ -n "${name//\/}" ]] \ || die 8 "\$name (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${name}" [[ -n "${rootfs//\/}" ]] \ || die 8 "\$rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${rootfs}" [[ -n "${cachefs//\/}" ]] \ || die 8 "\$cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPARATORS, THIS IS *VERY* BAD!\n" "${cachefs}" # check if the rootfs already exists [[ -d "${rootfs}/etc" ]] && die 18 "Error: \$rootfs (%s) already exists!" "${rootfs}" # check cache [[ ! -d "${cachefs}/etc" ]] && die 1 "Error: \$cachefs (%s) not found!" "${cachefs}" return 0 } container_rootfs() { printf "#### container_rootfs(): copying rootfs %s from cache %s ...\n" "${rootfs}" "${cachefs}" tar -c -f - --numeric-owner -C "${cachefs}" . \ | tar -x -p -f - --numeric-owner -C "${rootfs}" \ || die 1 "Error: cache copy to rootfs failed" printf "chroot test..." chroot "${rootfs}" /bin/true || die 1 "Error: 'chroot %s /bin/true' failed" printf " OK\n" printf " => done\n" return 0 } container_consoles() { printf "#### container_consoles(): setting container consoles ...\n" # disable unwanted ttys if [[ ${tty} < 6 ]]; then local mindis=$(( ${tty} + 1 )) sed -i "s/^c[${mindis}-6]/#&/" "${rootfs}/etc/inittab" fi printf " => main console + ${tty} ttys\n" if [[ -z "${autologin}" ]]; then sed 's/agetty -a root/agetty/' -i "${rootfs}/etc/inittab" elif [[ "${user}" != "root" ]]; then sed "s/agetty -a root/agetty -a ${user}/" -i "${rootfs}/etc/inittab" printf " => Autologin on main console for %s enabled\n" "${user}" [[ -z "${forced_password}" ]] && unset password store_user_message "${user} has autologin on main console" else printf " => Autologin on main console for root enabled\n" [[ -z "${forced_password}" ]] && unset password store_user_message "${user} has autologin on main console" fi printf " => done\n" } container_tz() { printf "#### container_tz(): setting container timezone ...\n" #let's try to copy it from host if [ -L "/etc/localtime" ]; then #host has a symlink #let see if we can reproduct symlink target=$(readlink /etc/localtime) if [[ "$target" != "" ]]; then if [ -f "${rootfs}/${target}" ]; then #same target exists in container chroot "${rootfs}" ln -sf "${target}" "/etc/localtime" printf " => host symlink reproducted in container : %s\n" "${target}" store_user_message "timezone copyed from host" return 0 fi fi fi if [ -e /etc/localtime ]; then # duplicate host timezone cat /etc/localtime > "${rootfs}/etc/localtime" printf " => host localtime copyed to container\n" store_user_message "timezone was staticly copyed from host" else # otherwise set up UTC chroot "${rootfs}" ln -sf /usr/share/zoneinfo/UTC /etc/localtime printf " => fallback: fixed to UTC\n" store_user_message "timezone was fixed to UTC" fi } container_portage() { printf "#### container_portage(): setting container portage... \n" #default entry for conf portage_mount="#container set with private portage tree, no mount here" printf "Warnings are normal here, don't worry\n" #container repos detection if chroot ${rootfs} portageq get_repo_path / gentoo > /dev/null ; then portage_container="$(chroot ${rootfs} portageq get_repo_path / gentoo)" else die 1 "Failed to figure out container portage tree location with portageq get_repo_path / gentoo\n" fi if [[ -n "${private_portage}" ]]; then container_private_portage return 0 fi if [ -z "${portage_dir}" ]; then #gentoo host detection printf "trying to guess portage_dir from host...\n" portage_dir="$(portageq get_repo_path / gentoo 2>/dev/null)" if [ ! -d "${portage_dir}/profiles" ]; then printf " => host portage detection failed (not gentoo host), fallback to private portage tree\n" container_private_portage return 0 fi else if [ ! -d "${portage_dir}/profiles" ]; then die 1 "specified portage_dir (%s) does not contains profiles, is it a portage tree ?\n" "${portage_dir}" fi fi printf "trying to guess portage distfiles dir from host ...\n" portage_distfiles_dir="$(portageq distdir 2>/dev/null)" if [ ! -d "${portage_distfiles_dir}" ]; then portage_distfiles_dir="${portage_dir}/distfiles" fi # if we are here, we have shared portage_dir #ensure dir exists chroot "${rootfs}" mkdir ${portage_container} portage_mount="#container set with shared portage lxc.mount.entry=${portage_dir} ${portage_container/\//} none ro,bind 0 0 lxc.mount.entry=${portage_distfiles_dir} ${portage_container/\//}/distfiles none rw,bind 0 0 #If you use eix, you should uncomment this #lxc.mount.entry=/var/cache/eix var/cache/eix none ro,bind 0 0" store_user_message "container has a shared portage from host's ${portage_dir} to ${portage_container/\//}" #Let's propose binary packages cat <<- EOF >> "${rootfs}/etc/portage/make.conf" # enable this to store built binary packages #FEATURES="\$FEATURES buildpkg" # enable this to use built binary packages #EMERGE_DEFAULT_OPTS="\${EMERGE_DEFAULT_OPTS} --usepkg" # enable and *tune* this kind of entry to slot binaries, specialy if you use multiples archs and variants #PKGDIR="\${PKGDIR}/amd64 #or PKGDIR="\${PKGDIR}/hardened" EOF printf " => portage stuff done, see /etc/portage/make.conf for additional tricks\n" } container_private_portage() { #called from container_portage() do not call directly from container_setup printf "# untaring private portage to %s from %s ... \n" "${rootfs}/${portage_container}" "${portage_cache}" mkdir -p "${rootfs}/${portage_container}" execute_exclusively portage 60 \ tar -xp --strip-components 1 -C "${rootfs}/${portage_container}" \ -f "${portage_cache}" --numeric-owner \ || die 2 "Error: unable to extract the portage tree.\n" store_user_message "container has its own portage tree at ${portage_container}" printf "=> done\n" } #helper func for container_genconf_net() nic_write() { #display with gentoo's confd.net format echo "config_${nic_name}=\"${nic_conf}\"" #add to managed list [[ "${nic_conf}" == "dhcp" ]] && nic_managed="${nic_managed} ${nic_name}" [[ "${nic_conf}" == "null" ]] && nic_unmanaged="${nic_unmanaged} ${nic_name}" [[ -z "${nic_hwaddr}" && ${nic_type} == "veth" ]] && nic_wo_hwaddr="${nic_wo_hwaddr} ${nic_name}" nic_writed=1 } #Analyse lxc.conf and print conf.d/net content container_conf_net() { local file=${1} [[ -z "${nic_last}" ]] && nic_last=-1 [[ -z "${nic_named}" ]] && nic_named=0 OLDIFS=$IFS IFS=" " #let's do some drity bash things to parse lxc network conf for line in $( sed -r "s/[ ]*=[ ]*/_real_ugly_sep_42_/" "${file}" ); do key=$(echo "${line}" | sed 's/_real_ugly_sep_42_.*$//') value=$(echo "${line}" | sed 's/^.*_real_ugly_sep_42_//') #new nic ! if [[ "${key}" == "lxc.network.type" ]]; then #we don't know what to do with it. [[ "${value}" == "empty" ]] && continue #write conf from previous loops [[ "${nic_writed}" == "0" ]] && nic_write #init defaults let nic_last=nic_last+1 nic_writed=0 #if 1 named between 2 not named: last is eth1 #=> Number is ID munis number of named NIC before nic_name="eth$(( ${nic_last} - ${nic_named} ))" nic_conf="dhcp" nic_type="${value}" fi if [[ "${key}" == "lxc.network.hwaddr" ]]; then nic_hwaddr=1 fi if [[ "${key}" =~ ^lxc.network.ipv(4|6) ]]; then #tell openrc to not manage this NIC as LXC set there address nic_conf="null" fi if [[ "${key}" =~ ^lxc.network.name ]]; then nic_name="${value}" let nic_named=nic_named+1 fi if [[ "${key}" == "lxc.include" ]]; then #recursive into include container_conf_net "${value}" fi done #write conf from previous loops [[ "${nic_writed}" == "0" ]] && nic_write IFS=$OLDIFS } container_net() { printf "container_net(): setting container network conf... \n" #Analyse network configuration in config container_conf_net "$path/config" >> "${rootfs}/etc/conf.d/net" # found how much nic finally have nic_count=$(( ${nic_last} + 1 )) # unless openrc manage a nic, we now have to force openrc to automatic # provision of the 'net' dep. If we do not, network dependent services # will fail to load if [[ -z "${nic_managed}" ]]; then #tell openrc that lxc already did the work echo 'rc_provide="net"' >> "${rootfs}/etc/rc.conf" fi #No NIC ? if [[ ${nic_count} == 0 ]]; then #If no Nic, no need to continue bridge=$(brctl show | awk 'NR==2 {print $1}') if [[ "${bridge}" != "" ]]; then store_user_message "No network interface for this container It's a pitty, you have bridge, ${bridge}. If it is for Lxc, use it next time by adding this to your default.conf : lxc.network.type = veth lxc.network.link = ${bridge} lxc.network.flags = up lxc.network.hwaddr = fe:xx:xx:xx:xx:xx" return 0 else store_user_message "No network interface for this container" return 0 fi fi #For each openrc managed nic, activate sys_nic_index=1 for nic in ${nic_managed} do chroot "${rootfs}" ln -s net.lo "/etc/init.d/net.${nic}" chroot "${rootfs}" rc-update add net.${nic} default #fake sysfs for openrc, in case settings does not provide it mkdir -p "${rootfs}/sys/class/net/${nic}" echo ${sys_nic_index} > "${rootfs}/sys/class/net/${nic}/ifindex" echo up > "${rootfs}/sys/class/net/${nic}/operstate" let sys_nic_index=sys_nic_index+1 done #Warn about dynamic hwaddr if [[ -n "${nic_wo_hwaddr}" ]]; then store_user_message "Warning, these veth NIC don't have fixed hwaddr : ${nic_wo_hwaddr} see http://lists.linuxcontainers.org/pipermail/lxc-devel/2013-December/006736.html and man lxc.conf" fi printf " => network conf done.\n" } # custom hostname container_hostname() { printf "#### container_hostname(): setting hostname... \n" printf "hostname=\"%s\"\n" "${name}" > "${rootfs}/etc/conf.d/hostname" printf " => done.\n" } container_auth() { printf "#### container_auth(): setting authentification... \n" if [[ "${user}" != "root" ]]; then printf " non root user requested, creating... \n" chroot "${rootfs}" useradd --create-home -s /bin/bash "${user}" || die 1 "failed to create user ${user}" printf " => user %s created\n" "${user}" fi store_user_message "Connection user is ${user}" #Home of user auth_home=$(chroot "${rootfs}" getent passwd "${user}" | cut -d : -f 6) if [[ -r "${auth_key}" ]]; then printf " deploying auth_key %s for user %s ...\n" "${auth_key}" "${user}" mkdir -p "${rootfs}/${auth_home}/.ssh" cat "${auth_key}" >> "${rootfs}/${auth_home}/.ssh/authorized_keys" chroot "${rootfs}" chown "${user}:" "${auth_home}/.ssh/authorized_keys" printf " => inserted public key in %s/.ssh/authorized_keys\n" "${auth_home}" [[ -z "${forced_password}" ]] && unset password store_user_message "${user} has the ssh key you gave us" fi if [[ -n "${password}" ]]; then printf " setting password for %s ...\n" "${user}" echo "${user}:${password}" | chroot "${rootfs}" chpasswd || die 1 "failed to change password" printf " => done. if you didn't specify , default is 'toor'\n" if [[ -n "${forced_password}" ]]; then store_user_message "${user} has the password you give for him" else store_user_message "${user} has the default password 'toor', please change it ASAP" fi fi printf " => done.\n" } container_sshd() { printf "#### container_sshd(): enabling sshd... \n" chroot "${rootfs}" rc-update add sshd || die 1 "failed to enable sshd\n" printf " => done.\n" } ################################################################################ # lxc configuration files ################################################################################ container_conf() { printf "container_configuration(): making lxc configuration file... \n" #at this point if there conf_file="${path}/config" # if there is exactly one veth network entry, make sure it has an # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' ${conf_file} | wc -l` if [ $nics -eq 1 ]; then grep -q "^lxc.network.hwaddr" ${conf_file} || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" ${conf_file} fi if grep -q "^lxc.rootfs" "${conf_file}" ; then #lxc-create already provided one conf_rootfs_line="" else conf_rootfs_line="lxc.rootfs = $(readlink -f "${rootfs}")" fi if [[ "${arch}" == "x86" || "${arch}" == "amd64" ]]; then local conf_arch_line="lxc.arch = ${arch}" else local conf_arch_line="# lxc.arch = ${arch}" fi cat <<- EOF >> "${conf_file}" # sets container architecture # If desired architecture != amd64 or x86, then we leave it unset as # LXC does not oficially support anything other than x86 or amd64. ${conf_arch_line} # set the hostname lxc.utsname = ${name} lxc.tty = ${tty} ${conf_rootfs_line} ${portage_mount} ${conf_sysfs} ${conf_mounts} lxc.include = ${LXC_TEMPLATE_CONFIG}/gentoo.${settings}.conf EOF printf " => done.\n" } usage() { cat <] [-v|--variant ] [-P|--private-portage] [--portage-dir ] [-t|--tarball ] [-F|--flush-cache] [-c|--cache-only] [-u|--user ] [-w|--password ] [--autologin] [-S|--auth-key ] [-s|--settings ] [-m|--mirror ] [--tty ] arch: the container architecture (e.g. amd64): defaults to host arch (currently: '${arch}') If you choose one that needs emulation tested: amd64, x86 You could try any other gentoo arch, why not... variant: gentoo's Architecture variant as of dec 2013 : (currently: '${variant}') for amd64 arch: amd64 (default), amd64-hardened+nomultilib, amd64-hardened, amd64-nomultilib, x32 for x86 arch: i686 (default), i486, i686-hardened for arm arch: armv7a (default), armv7a_hardfp, armv6j, armv6j_hardfp, armv5tel, armv4tl private-portage: by default, /usr/portage is mount-binded with host one if exists (currently: '${private_portage}') this force container to have his own copy portage-dir: portage dir used for shared portage by default the host on if any (currently: '${portage_dir}') tarball: force usage of local stage3 archive (currently: '${arch}') If empty, latest will be downloaded flush-cache: do like there is no previous cache cache-only: just ensure cache is present if cache exists and "flush-cache" not specified, does nothing user: user used in auth oriented options (currently: '${user}') password: password for user (currently: '${password}') if default, usage of auth-key will disable password setting autologin: enable autologin for user (currently: '${autologin}') This unset default password setting auth-key: SSH Public key file to inject into container for user (currently: '${auth_key}') This unset default password setting settings: choose common configuration (currently: '${settings}') see ${LXC_TEMPLATE_CONFIG}/gentoo.*.conf Available settings: $(ls -1 ${LXC_TEMPLATE_CONFIG}/gentoo.*.conf | xargs basename -a -s .conf | sed 's/^gentoo.//') mirror: gentoo mirror for download (currently: '${mirror}') tty: number of tty (6 max) (currently: '${tty}') EOF exit 0 } #some overridable defaults set_default_arch mirror="http://distfiles.gentoo.org" user="root" password="toor" tty=1 settings="common" options=$(getopt -o hp:n:a:FcPv:t:S:u:w:s:m: -l help,rootfs:,path:,name:,arch:,flush-cache,cache-only,private-portage,variant:,portage-dir:,tarball:,auth-key:,user:,autologin,password:,settings:,mirror:,tty: -- "$@") eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; --rootfs) rootfs=$2; shift 2;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -F|--flush-cache) flush_cache=1; shift 1;; -c|--cache-only) cache_only=1; shift 1;; -P|--private-portage) private_portage=1; shift 1;; -v|--variant) variant=$2; shift 2;; --portage-dir) portage_dir=$2; shift 2;; -t|--tarball) tarball=$2; shift 2;; -S|--auth-key) auth_key=$2; shift 2;; -u|--user) user=$2; shift 2;; -w|--password) forced_password=1; password=$2; shift 2;; -s|--settings) settings=$2; shift 2;; -m|--mirror) mirror=$2; shift 2;; --container-cache) containercache=$2; shift 2;; --tty) [[ $2 -lt 6 ]] && tty=$2; shift 2;; --autologin) autologin=1; shift 1;; --) shift 1; break ;; *) break ;; esac done # Allow the cache path to be set by environment variable cacheroot="${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/gentoo" portage_cache="${cacheroot}/portage.tbz" cachefs="${cacheroot}/rootfs-${arch}-${variant}" alias wget="wget --timeout=8 --read-timeout=15 -c -t10 -nd" do_all() { cache_setup if [ -z "${cache_only}" ]; then container_setup fi } execute_exclusively "cache-${arch}-${variant}" 60 do_all lxc-2.0.0/templates/lxc-openmandriva.in0000644061062106075000000003311712701247216015034 00000000000000#!/bin/bash # # template script for generating openmandriva container for LXC # # # lxc: linux Container library # Authors: # Alexander Khryukin # Vokhmin Alexey V # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 #Configurations #distro=cooker hostarch=$(uname -m) # Allow the cache base to be set by environment variable cache_base="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/openmandriva/$arch}" default_path=@LXCPATH@ default_profile=default root_password=root lxc_network_type=veth lxc_network_link=br0 # is this openmandriva? [ -f /etc/mandriva-release ] && is_openmandriva=true configure_openmandriva() { mkdir -p ${rootfs_path}/etc/sysconfig/network-scripts/ # configure the network using the dhcp cat < ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ONBOOT=yes BOOTPROTO=dhcp NM_CONTROLLED=no HOSTNAME=${utsname} EOF # set the hostname cat < ${rootfs_path}/etc/sysconfig/network NETWORKING=yes HOSTNAME=${utsname} EOF echo "${utsname}" > ${rootfs_path}/etc/hostname # set minimal hosts cat < $rootfs_path/etc/hosts 127.0.0.1 localhost.localdomain localhost $utsname ::1 localhost6.localdomain6 localhost6 EOF } populate_dev() { echo -n "Create devices in /dev/" dev_path="${rootfs_path}/dev" rm -rf $dev_path mkdir -p $dev_path mknod -m 666 ${dev_path}/null c 1 3 mknod -m 666 ${dev_path}/zero c 1 5 mknod -m 666 ${dev_path}/random c 1 8 mknod -m 666 ${dev_path}/urandom c 1 9 mkdir -m 755 ${dev_path}/pts mkdir -m 1777 ${dev_path}/shm mknod -m 666 ${dev_path}/tty c 5 0 mknod -m 666 ${dev_path}/tty0 c 4 0 mknod -m 666 ${dev_path}/tty1 c 4 1 mknod -m 666 ${dev_path}/tty2 c 4 2 mknod -m 666 ${dev_path}/tty3 c 4 3 mknod -m 666 ${dev_path}/tty4 c 4 4 mknod -m 600 ${dev_path}/console c 5 1 mknod -m 666 ${dev_path}/full c 1 7 mknod -m 600 ${dev_path}/initctl p mknod -m 666 ${dev_path}/ptmx c 5 2 mkdir -m 755 ${dev_path}/net mknod -m 666 ${dev_path}/net/tun c 10 200 } set_guest_root_password() { [ -z "$root_password" ] && return # pass is empty, abort echo " - setting guest root password.." echo "root passwd is: $root_password" echo "root:$root_password" | chroot "$rootfs_path" chpasswd echo "done." } create_chroot_openmandriva() { # check the mini openmandriva was not already downloaded INSTALL_ROOT=$cache/cache mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then echo "Failed to create '$INSTALL_ROOT' directory" return 1 fi # package list to install PKG_LIST="basesystem-minimal locales locales-en initscripts urpmi cronie dhcp-client kbd" # download a mini openmandriva into a cache echo "Downloading openmandriva minimal ..." URPMI="/usr/sbin/urpmi.addmedia --urpmi-root $INSTALL_ROOT main http://abf.rosalinux.ru/downloads/$release/repository/$arch/main/release" echo $URPMI URPMI_BASE="/usr/sbin/urpmi --no-suggests --no-verify-rpm --ignorearch --root $INSTALL_ROOT --urpmi-root $INSTALL_ROOT --auto $PKG_LIST" $URPMI $URPMI_BASE # We're splitting the old loop into two loops plus a directory retrival. # First loop... Try and retrive a mirror list with retries and a slight # delay between attempts... if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv "$INSTALL_ROOT" "$cache/rootfs" echo "Download complete." return 0 } copy_openmandriva() { echo -n "Copying rootfs to $rootfs_path ..." mkdir -p $rootfs_path rsync -Ha $cache/rootfs/ $rootfs_path/ return 0 } update_openmandriva() { echo "automated update in progress..." urpmi --root $cache/rootfs --urpmi-root $cache/rootfs --auto --auto-update --ignorearch } configure_openmandriva_systemd() { chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/proc-sys-fs-binfmt_misc.automount chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd.service chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd-control.socket chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/systemd-udevd-kernel.socket # remove numlock service # KDGKBLED: Inappropriate ioctl for device rm -f ${rootfs_path}/etc/systemd/system/getty@.service.d/enable-numlock.conf unlink ${rootfs_path}/etc/systemd/system/default.target chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target sed -i 's!ConditionPathExists=/dev/tty0!ConditionPathExists=|/dev/tty0\nConditionVirtualization=|lxc!' \ ${rootfs_path}/lib/systemd/system/getty\@.service } install_openmandriva() { mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs ... " if [ ! -e "$cache/rootfs" ]; then echo $cache/rootfs create_chroot_openmandriva if [ $? -ne 0 ]; then echo "Failed to download 'openmandriva basesystem-minimal'" return 1 fi else echo "Cache found. Updating..." update_openmandriva if [ $? -ne 0 ]; then echo "Failed to update 'openmandriva base', continuing with last known good cache" else echo "Update finished" fi fi echo "Copy $cache/rootfs to $rootfs_path ... " copy_openmandriva if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-openmandriva return $? } copy_configuration() { mkdir -p $config_path grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config cat <> $config_path/config lxc.utsname = $name lxc.tty = 4 lxc.pts = 1024 lxc.cap.drop = sys_module mac_admin mac_override sys_time lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined #networking lxc.network.type = $lxc_network_type lxc.network.flags = up lxc.network.link = $lxc_network_link lxc.network.name = eth0 lxc.network.mtu = 1500 EOF if [ ! -z ${ipv4} ]; then cat <> $config_path/config lxc.network.ipv4 = $ipv4 EOF fi if [ ! -z ${gw} ]; then cat <> $config_path/config lxc.network.ipv4.gateway = $gw EOF fi if [ ! -z ${ipv6} ]; then cat <> $config_path/config lxc.network.ipv6 = $ipv6 EOF fi if [ ! -z ${gw6} ]; then cat <> $config_path/config lxc.network.ipv6.gateway = $gw6 EOF fi cat <> $config_path/config #cgroups lxc.cgroup.devices.deny = a # /dev/null and zero lxc.cgroup.devices.allow = c 1:3 rwm lxc.cgroup.devices.allow = c 1:5 rwm # consoles lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:0 rwm lxc.cgroup.devices.allow = c 4:0 rwm lxc.cgroup.devices.allow = c 4:1 rwm # /dev/{,u}random lxc.cgroup.devices.allow = c 1:9 rwm lxc.cgroup.devices.allow = c 1:8 rwm lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc lxc.cgroup.devices.allow = c 10:135 rwm EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } clean() { if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache for OpenMandriva-$release..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-openmandriva } usage() { cat < [-p|--path=] [-c|--clean] [-R|--release=] [-4|--ipv4=] [-6|--ipv6=] [-g|--gw=] [-d|--dns=] [-P|--profile=] [--rootfs=] [-A|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case -c,--clean clean the cache -R,--release openmandriva2013.0/cooker/rosa2012.1 release for the new container. if the host is OpenMandriva, then it will default to the host's release. -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24 -6,--ipv6 specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64 -g,--gw specify the default gw, eg. 192.168.1.1 -G,--gw6 specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596 -d,--dns specify the DNS server, eg. 192.168.1.2 -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache. -A,--arch Define what arch the container will be [i586,x86_64,armv7l,armv7hl] ---rootfs rootfs path -h,--help print this help EOF return 0 } options=$(getopt -o hp:n:P:cR:4:6:g:d:A -l help,rootfs:,path:,name:,profile:,clean:,release:,ipv4:,ipv6:,gw:,dns:,arch: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" release=${release:-"cooker"} if [ -f /etc/lsb-release ]; then . /etc/lsb-release if [ "$DISTRIB_ID" = "OpenMandrivaLinux" ]; then release=openmandriva2013.0 elif [ "$DISTRIB_ID" = "RosaDesktop.Fresh" ]; then release=rosa2012.1 else echo "This is not an OpenMandriva or ROSA release" exit 1 fi fi while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs_path=$2; shift 2;; -n|--name) name=$2; shift 2;; -P|--profile) profile=$2; shift 2;; -c|--clean) clean=1; shift 1;; -R|--release) release=$2; shift 2;; -A|--arch) arch=$2; shift 2;; -4|--ipv4) ipv4=$2; shift 2;; -6|--ipv6) ipv6=$2; shift 2;; -g|--gw) gw=$2; shift 2;; -d|--dns) dns=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done arch=${arch:-$hostarch} if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi if [ -z "${utsname}" ]; then utsname=${name} fi type urpmi >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "'urpmi' command is missing" exit 1 fi if [ -z "$path" ]; then path=$default_path fi if [ -z "$profile" ]; then profile=$default_profile fi if [ $hostarch = "i586" -a $arch = "x86_64" ]; then echo "can't create x86_64 container on i586" exit 1 fi if [ -z "$ipv4" -a -z "$ipv6" ]; then BOOTPROTO="dhcp" else BOOTPROTO="static" fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi # check for 'lxc.rootfs' passed in through default config by lxc-create if [ -z "$rootfs_path" ]; then if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then rootfs_path=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config) else rootfs_path=$path/$name/rootfs fi fi config_path=$default_path/$name cache=$cache_base/$release/$arch/$profile if [ ! -f $config_path/config ]; then echo "A container with that name exists, chose a different name" exit 1 fi install_openmandriva if [ $? -ne 0 ]; then echo "failed to install openmandriva" exit 1 fi configure_openmandriva if [ $? -ne 0 ]; then echo "failed to configure openmandriva for a container" exit 1 fi # If the systemd configuration directory exists - set it up for what we need. if [ -d ${rootfs_path}/etc/systemd/system ] then configure_openmandriva_systemd fi populate_dev if [ $? -ne 0 ]; then echo "failed to populated /dev/ devices" exit 1 fi set_guest_root_password if [ $? -ne 0 ]; then echo "failed to configure password for chroot" exit 1 fi copy_configuration if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi echo "container rootfs and config created" lxc-2.0.0/templates/lxc-download.in0000644061062106075000000004274312701247216014165 00000000000000#!/bin/sh # Client script for LXC container images. # # Copyright © 2014 Stéphane Graber # # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 # USA set -eu LOCALSTATEDIR="@LOCALSTATEDIR@" LXC_HOOK_DIR="@LXCHOOKDIR@" LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" # Defaults DOWNLOAD_ARCH= DOWNLOAD_BUILD= DOWNLOAD_COMPAT_LEVEL=3 DOWNLOAD_DIST= DOWNLOAD_FLUSH_CACHE="false" DOWNLOAD_FORCE_CACHE="false" DOWNLOAD_INTERACTIVE="false" DOWNLOAD_KEYID="0xBAEFF88C22F6E216" DOWNLOAD_KEYSERVER="hkp://pool.sks-keyservers.net" DOWNLOAD_LIST_IMAGES="false" DOWNLOAD_MODE="system" DOWNLOAD_READY_GPG="false" DOWNLOAD_RELEASE= DOWNLOAD_SERVER="images.linuxcontainers.org" DOWNLOAD_SHOW_GPG_WARNING="true" DOWNLOAD_SHOW_HTTP_WARNING="true" DOWNLOAD_TARGET="system" DOWNLOAD_URL= DOWNLOAD_USE_CACHE="false" DOWNLOAD_VALIDATE="true" DOWNLOAD_VARIANT="default" LXC_MAPPED_GID= LXC_MAPPED_UID= LXC_NAME= LXC_PATH= LXC_ROOTFS= # Deal with GPG over http proxy if [ -n "${http_proxy:-}" ]; then DOWNLOAD_KEYSERVER="hkp://p80.pool.sks-keyservers.net:80" fi # Make sure the usual locations are in PATH export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin # Some useful functions cleanup() { if [ -d "$DOWNLOAD_TEMP" ]; then rm -Rf $DOWNLOAD_TEMP fi } wget_wrapper() { for i in $(seq 3); do if wget $@; then return 0 fi done return 1 } download_file() { if ! wget_wrapper -T 30 -q https://${DOWNLOAD_SERVER}/$1 -O $2 >/dev/null 2>&1; then if ! wget_wrapper -T 30 -q http://${DOWNLOAD_SERVER}/$1 -O $2 >/dev/null 2>&1; then if [ "$3" = "noexit" ]; then return 1 else echo "ERROR: Failed to download http://${DOWNLOAD_SERVER}/$1" 1>&2 exit 1 fi elif [ "$DOWNLOAD_SHOW_HTTP_WARNING" = "true" ]; then DOWNLOAD_SHOW_HTTP_WARNING="false" echo "WARNING: Failed to download the file over HTTPs." 1>&2 echo -n " The file was instead download over HTTP. " 1>&2 echo "A server replay attack may be possible!" 1>&2 fi fi } download_sig() { if ! download_file $1 $2 noexit; then if [ "$DOWNLOAD_VALIDATE" = "true" ]; then if [ "$3" = "normal" ]; then echo "ERROR: Failed to download http://${DOWNLOAD_SERVER}/$1" 1>&2 exit 1 else return 1 fi else return 0 fi fi } gpg_setup() { if [ "$DOWNLOAD_VALIDATE" = "false" ]; then return fi if [ "$DOWNLOAD_READY_GPG" = "true" ]; then return fi echo "Setting up the GPG keyring" mkdir -p "$DOWNLOAD_TEMP/gpg" chmod 700 "$DOWNLOAD_TEMP/gpg" export GNUPGHOME="$DOWNLOAD_TEMP/gpg" success= for i in $(seq 3); do if gpg --keyserver $DOWNLOAD_KEYSERVER \ --recv-keys ${DOWNLOAD_KEYID} >/dev/null 2>&1; then success=1 break fi done if [ -z "$success" ]; then echo "ERROR: Unable to fetch GPG key from keyserver." exit 1 fi DOWNLOAD_READY_GPG="true" } gpg_validate() { if [ "$DOWNLOAD_VALIDATE" = "false" ]; then if [ "$DOWNLOAD_SHOW_GPG_WARNING" = "true" ]; then echo "WARNING: Running without gpg validation!" 1>&2 fi DOWNLOAD_SHOW_GPG_WARNING="false" return 0 fi if ! gpg --verify $1 >/dev/zero 2>&1; then echo "ERROR: Invalid signature for $1" 1>&2 exit 1 fi } in_userns() { [ -e /proc/self/uid_map ] || { echo no; return; } while read line; do fields=$(echo $line | awk '{ print $1 " " $2 " " $3 }') [ "$fields" = "0 0 4294967295" ] && { echo no; return; } || true echo $fields | grep -q " 0 1$" && { echo userns-root; return; } || true done < /proc/self/uid_map [ "$(cat /proc/self/uid_map)" = "$(cat /proc/1/uid_map)" ] && \ { echo userns-root; return; } echo yes } relevant_file() { FILE_PATH="${LXC_CACHE_PATH}/$1" if [ -e "${FILE_PATH}-${DOWNLOAD_MODE}" ]; then FILE_PATH="${FILE_PATH}-${DOWNLOAD_MODE}" fi if [ -e "$FILE_PATH.${DOWNLOAD_COMPAT_LEVEL}" ]; then FILE_PATH="${FILE_PATH}.${DOWNLOAD_COMPAT_LEVEL}" fi echo $FILE_PATH } usage() { cat < ]: The name of the distribution [ -r | --release ]: Release name/version [ -a | --arch ]: Architecture of the container Optional arguments: [ --variant ]: Variant of the image (default: "default") [ --server ]: Image server (default: "images.linuxcontainers.org") [ --keyid ]: GPG keyid (default: 0x...) [ --keyserver ]: GPG keyserver to use [ --no-validate ]: Disable GPG validation (not recommended) [ --flush-cache ]: Flush the local copy (if present) [ --force-cache ]: Force the use of the local copy even if expired LXC internal arguments (do not pass manually!): [ --name ]: The container name [ --path ]: The path to the container [ --rootfs ]: The path to the container's rootfs [ --mapped-uid ]: A uid map (user namespaces) [ --mapped-gid ]: A gid map (user namespaces) EOF return 0 } options=$(getopt -o d:r:a:hl -l dist:,release:,arch:,help,list,variant:,\ server:,keyid:,keyserver:,no-validate,flush-cache,force-cache,name:,path:,\ rootfs:,mapped-uid:,mapped-gid: -- "$@") if [ $? -ne 0 ]; then usage exit 1 fi eval set -- "$options" while :; do case "$1" in -h|--help) usage && exit 1;; -l|--list) DOWNLOAD_LIST_IMAGES="true"; shift 1;; -d|--dist) DOWNLOAD_DIST=$2; shift 2;; -r|--release) DOWNLOAD_RELEASE=$2; shift 2;; -a|--arch) DOWNLOAD_ARCH=$2; shift 2;; --variant) DOWNLOAD_VARIANT=$2; shift 2;; --server) DOWNLOAD_SERVER=$2; shift 2;; --keyid) DOWNLOAD_KEYID=$2; shift 2;; --keyserver) DOWNLOAD_KEYSERVER=$2; shift 2;; --no-validate) DOWNLOAD_VALIDATE="false"; shift 1;; --flush-cache) DOWNLOAD_FLUSH_CACHE="true"; shift 1;; --force-cache) DOWNLOAD_FORCE_CACHE="true"; shift 1;; --name) LXC_NAME=$2; shift 2;; --path) LXC_PATH=$2; shift 2;; --rootfs) LXC_ROOTFS=$2; shift 2;; --mapped-uid) LXC_MAPPED_UID=$2; shift 2;; --mapped-gid) LXC_MAPPED_GID=$2; shift 2;; *) break;; esac done # Check for required binaries for bin in tar xz wget; do if ! type $bin >/dev/null 2>&1; then echo "ERROR: Missing required tool: $bin" 1>&2 exit 1 fi done # Check for GPG if [ "$DOWNLOAD_VALIDATE" = "true" ]; then if ! type gpg >/dev/null 2>&1; then echo "ERROR: Missing recommended tool: gpg" 1>&2 echo "You can workaround this by using --no-validate." 1>&2 exit 1 fi fi # Check that we have all variables we need if [ -z "$LXC_NAME" ] || [ -z "$LXC_PATH" ] || [ -z "$LXC_ROOTFS" ]; then if [ "$DOWNLOAD_LIST_IMAGES" != "true" ]; then echo "ERROR: Not running through LXC." 1>&2 exit 1 fi fi USERNS=$(in_userns) if [ "$USERNS" != "no" ]; then if [ "$USERNS" = "yes" ]; then if [ -z "$LXC_MAPPED_UID" ] || [ "$LXC_MAPPED_UID" = "-1" ]; then echo "ERROR: In a user namespace without a map." 1>&2 exit 1 fi DOWNLOAD_MODE="user" DOWNLOAD_TARGET="user" else DOWNLOAD_MODE="user" DOWNLOAD_TARGET="system" fi fi if [ -z "$DOWNLOAD_DIST" ] || [ -z "$DOWNLOAD_RELEASE" ] || \ [ -z "$DOWNLOAD_ARCH" ]; then DOWNLOAD_INTERACTIVE="true" fi # Trap all exit signals trap cleanup EXIT HUP INT TERM if ! type mktemp >/dev/null 2>&1; then DOWNLOAD_TEMP=/tmp/lxc-download.$$ mkdir -p $DOWNLOAD_TEMP else DOWNLOAD_TEMP=$(mktemp -d) fi # Simply list images if [ "$DOWNLOAD_LIST_IMAGES" = "true" ] || \ [ "$DOWNLOAD_INTERACTIVE" = "true" ]; then # Initialize GPG gpg_setup # Grab the index DOWNLOAD_INDEX_PATH=/meta/1.0/index-${DOWNLOAD_MODE} echo "Downloading the image index" if ! download_file ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL} \ ${DOWNLOAD_TEMP}/index noexit || ! download_sig ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL}.asc \ ${DOWNLOAD_TEMP}/index.asc noexit; then download_file ${DOWNLOAD_INDEX_PATH} ${DOWNLOAD_TEMP}/index normal download_sig ${DOWNLOAD_INDEX_PATH}.asc \ ${DOWNLOAD_TEMP}/index.asc normal fi gpg_validate ${DOWNLOAD_TEMP}/index.asc # Parse it echo "" echo "---" printf "DIST\tRELEASE\tARCH\tVARIANT\tBUILD\n" echo "---" while read line; do # Basic CSV parser OLD_IFS=$IFS IFS=";" set -- $line IFS=$OLD_IFS [ -n "$DOWNLOAD_DIST" ] && [ "$1" != "$DOWNLOAD_DIST" ] && continue [ -n "$DOWNLOAD_RELEASE" ] && [ "$2" != "$DOWNLOAD_RELEASE" ] && continue [ -n "$DOWNLOAD_ARCH" ] && [ "$3" != "$DOWNLOAD_ARCH" ] && continue [ -n "$DOWNLOAD_VARIANT" ] && [ "$4" != "$DOWNLOAD_VARIANT" ] && continue [ -z "$5" ] || [ -z "$6" ] && continue printf "$1\t$2\t$3\t$4\t$5\n" done < ${DOWNLOAD_TEMP}/index echo "---" if [ "$DOWNLOAD_LIST_IMAGES" = "true" ]; then exit 1 fi # Interactive mode echo "" if [ -z "$DOWNLOAD_DIST" ]; then echo -n "Distribution: " read DOWNLOAD_DIST fi if [ -z "$DOWNLOAD_RELEASE" ]; then echo -n "Release: " read DOWNLOAD_RELEASE fi if [ -z "$DOWNLOAD_ARCH" ]; then echo -n "Architecture: " read DOWNLOAD_ARCH fi echo "" fi # Setup the cache if [ "$DOWNLOAD_TARGET" = "system" ]; then LXC_CACHE_BASE="$LOCALSTATEDIR/cache/lxc/" else LXC_CACHE_BASE="$HOME/.cache/lxc/" fi # Allow the setting of the LXC_CACHE_PATH with the usage of environment variables. LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LXC_CACHE_BASE"} LXC_CACHE_PATH=$LXC_CACHE_PATH/download/$DOWNLOAD_DIST LXC_CACHE_PATH="$LXC_CACHE_PATH/$DOWNLOAD_RELEASE/$DOWNLOAD_ARCH/" LXC_CACHE_PATH="$LXC_CACHE_PATH/$DOWNLOAD_VARIANT" if [ -d "$LXC_CACHE_PATH" ]; then if [ "$DOWNLOAD_FLUSH_CACHE" = "true" ]; then echo "Flushing the cache..." rm -Rf $LXC_CACHE_PATH elif [ "$DOWNLOAD_FORCE_CACHE" = "true" ]; then DOWNLOAD_USE_CACHE="true" else DOWNLOAD_USE_CACHE="true" if [ -e "$(relevant_file expiry)" ]; then if [ "$(cat $(relevant_file expiry))" -lt $(date +%s) ]; then echo "The cached copy has expired, re-downloading..." DOWNLOAD_USE_CACHE="false" fi fi fi fi # Download what's needed if [ "$DOWNLOAD_USE_CACHE" = "false" ]; then # Initialize GPG gpg_setup # Grab the index DOWNLOAD_INDEX_PATH=/meta/1.0/index-${DOWNLOAD_MODE} echo "Downloading the image index" if ! download_file ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL} \ ${DOWNLOAD_TEMP}/index noexit || ! download_sig ${DOWNLOAD_INDEX_PATH}.${DOWNLOAD_COMPAT_LEVEL}.asc \ ${DOWNLOAD_TEMP}/index.asc noexit; then download_file ${DOWNLOAD_INDEX_PATH} ${DOWNLOAD_TEMP}/index normal download_sig ${DOWNLOAD_INDEX_PATH}.asc \ ${DOWNLOAD_TEMP}/index.asc normal fi gpg_validate ${DOWNLOAD_TEMP}/index.asc # Parse it while read line; do # Basic CSV parser OLD_IFS=$IFS IFS=";" set -- $line IFS=$OLD_IFS if [ "$1" != "$DOWNLOAD_DIST" ] || \ [ "$2" != "$DOWNLOAD_RELEASE" ] || \ [ "$3" != "$DOWNLOAD_ARCH" ] || \ [ "$4" != "$DOWNLOAD_VARIANT" ] || \ [ -z "$6" ]; then continue fi DOWNLOAD_BUILD=$5 DOWNLOAD_URL=$6 break done < ${DOWNLOAD_TEMP}/index if [ -z "$DOWNLOAD_URL" ]; then echo "ERROR: Couldn't find a matching image." 1>&1 exit 1 fi if [ -d "$LXC_CACHE_PATH" ] && [ -f "$LXC_CACHE_PATH/build_id" ] && \ [ "$(cat $LXC_CACHE_PATH/build_id)" = "$DOWNLOAD_BUILD" ]; then echo "The cache is already up to date." echo "Using image from local cache" else # Download the actual files echo "Downloading the rootfs" download_file $DOWNLOAD_URL/rootfs.tar.xz \ ${DOWNLOAD_TEMP}/rootfs.tar.xz normal download_sig $DOWNLOAD_URL/rootfs.tar.xz.asc \ ${DOWNLOAD_TEMP}/rootfs.tar.xz.asc normal gpg_validate ${DOWNLOAD_TEMP}/rootfs.tar.xz.asc echo "Downloading the metadata" download_file $DOWNLOAD_URL/meta.tar.xz \ ${DOWNLOAD_TEMP}/meta.tar.xz normal download_sig $DOWNLOAD_URL/meta.tar.xz.asc \ ${DOWNLOAD_TEMP}/meta.tar.xz.asc normal gpg_validate ${DOWNLOAD_TEMP}/meta.tar.xz.asc if [ -d $LXC_CACHE_PATH ]; then rm -Rf $LXC_CACHE_PATH fi mkdir -p $LXC_CACHE_PATH mv ${DOWNLOAD_TEMP}/rootfs.tar.xz $LXC_CACHE_PATH if ! tar Jxf ${DOWNLOAD_TEMP}/meta.tar.xz -C $LXC_CACHE_PATH; then echo "ERROR: Invalid rootfs tarball." 2>&1 exit 1 fi echo $DOWNLOAD_BUILD > $LXC_CACHE_PATH/build_id if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then chown -R $LXC_MAPPED_UID $LXC_CACHE_BASE >/dev/null 2>&1 || true fi if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then chgrp -R $LXC_MAPPED_GID $LXC_CACHE_BASE >/dev/null 2>&1 || true fi echo "The image cache is now ready" fi else echo "Using image from local cache" fi # Unpack the rootfs echo "Unpacking the rootfs" EXCLUDES="" excludelist=$(relevant_file excludes) if [ -f "${excludelist}" ]; then while read line; do EXCLUDES="$EXCLUDES --exclude=$line" done < $excludelist fi tar --anchored ${EXCLUDES} --numeric-owner -xpJf \ ${LXC_CACHE_PATH}/rootfs.tar.xz -C ${LXC_ROOTFS} mkdir -p ${LXC_ROOTFS}/dev/pts/ # Setup the configuration configfile=$(relevant_file config) fstab=$(relevant_file fstab) if [ ! -e $configfile ]; then echo "ERROR: meta tarball is missing the configuration file" 1>&2 exit 1 fi ## Extract all the network config entries sed -i -e "/lxc.network/{w ${LXC_PATH}/config-network" -e "d}" \ ${LXC_PATH}/config ## Extract any other config entry sed -i -e "/lxc./{w ${LXC_PATH}/config-auto" -e "d}" ${LXC_PATH}/config ## Append the defaults echo "" >> ${LXC_PATH}/config echo "# Distribution configuration" >> ${LXC_PATH}/config cat $configfile >> ${LXC_PATH}/config ## Add the container-specific config echo "" >> ${LXC_PATH}/config echo "# Container specific configuration" >> ${LXC_PATH}/config if [ -e "${LXC_PATH}/config-auto" ]; then cat ${LXC_PATH}/config-auto >> ${LXC_PATH}/config rm ${LXC_PATH}/config-auto fi if [ -e "$fstab" ]; then echo "lxc.mount = ${LXC_PATH}/fstab" >> ${LXC_PATH}/config fi echo "lxc.utsname = ${LXC_NAME}" >> ${LXC_PATH}/config ## Re-add the previously removed network config if [ -e "${LXC_PATH}/config-network" ]; then echo "" >> ${LXC_PATH}/config echo "# Network configuration" >> ${LXC_PATH}/config cat ${LXC_PATH}/config-network >> ${LXC_PATH}/config rm ${LXC_PATH}/config-network fi TEMPLATE_FILES="${LXC_PATH}/config" # Setup the fstab if [ -e $fstab ]; then cp ${fstab} ${LXC_PATH}/fstab TEMPLATE_FILES="$TEMPLATE_FILES ${LXC_PATH}/fstab" fi # Look for extra templates if [ -e "$(relevant_file templates)" ]; then while read line; do fullpath=${LXC_ROOTFS}/$line [ ! -e "$fullpath" ] && continue TEMPLATE_FILES="$TEMPLATE_FILES $fullpath" done < $(relevant_file templates) fi # Replace variables in all templates for file in $TEMPLATE_FILES; do [ ! -f "$file" ] && continue sed -i "s#LXC_NAME#$LXC_NAME#g" $file sed -i "s#LXC_PATH#$LXC_PATH#g" $file sed -i "s#LXC_ROOTFS#$LXC_ROOTFS#g" $file sed -i "s#LXC_TEMPLATE_CONFIG#$LXC_TEMPLATE_CONFIG#g" $file sed -i "s#LXC_HOOK_DIR#$LXC_HOOK_DIR#g" $file done # prevent mingetty from calling vhangup(2) since it fails with userns on Centos / Oracle if [ -f ${LXC_ROOTFS}/etc/init/tty.conf ]; then sed -i 's|mingetty|mingetty --nohangup|' ${LXC_ROOTFS}/etc/init/tty.conf fi if [ -n "$LXC_MAPPED_UID" ] && [ "$LXC_MAPPED_UID" != "-1" ]; then chown $LXC_MAPPED_UID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true fi if [ -n "$LXC_MAPPED_GID" ] && [ "$LXC_MAPPED_GID" != "-1" ]; then chgrp $LXC_MAPPED_GID $LXC_PATH/config $LXC_PATH/fstab >/dev/null 2>&1 || true fi if [ -e "$(relevant_file create-message)" ]; then echo "" echo "---" cat "$(relevant_file create-message)" fi exit 0 lxc-2.0.0/templates/lxc-altlinux.in0000644061062106075000000003266412701247216014217 00000000000000#!/bin/bash # # template script for generating altlinux container for LXC # # # lxc: linux Container library # Authors: # Alexey Shabalin # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 #Configurations arch=$(uname -m) cache_base=@LOCALSTATEDIR@/cache/lxc/altlinux/$arch default_path=@LXCPATH@ default_profile=default profile_dir=/etc/lxc/profiles root_password=rooter lxc_network_type=veth lxc_network_link=virbr0 # is this altlinux? [ -f /etc/altlinux-release ] && is_altlinux=true configure_altlinux() { # disable selinux in altlinux mkdir -p $rootfs_path/selinux echo 0 > $rootfs_path/selinux/enforce mkdir -p ${rootfs_path}/etc/net/ifaces/eth0 cat < ${rootfs_path}/etc/net/ifaces/eth0/options BOOTPROTO=${BOOTPROTO} ONBOOT=yes NM_CONTROLLED=yes TYPE=eth EOF if [ ${BOOTPROTO} != "dhcp" ]; then # ip address cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv4address ${ipv4} EOF cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv4route ${gw} EOF cat < ${rootfs_path}/etc/net/ifaces/eth0/resolv.conf nameserver ${dns} EOF cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv6address ${ipv6} EOF cat < ${rootfs_path}/etc/net/ifaces/eth0/ipv6route ${gw6} EOF fi # set the hostname cat < ${rootfs_path}/etc/sysconfig/network NETWORKING=yes CONFMETHOD=etcnet HOSTNAME=${UTSNAME} RESOLV_MODS=yes EOF # set minimal hosts cat < $rootfs_path/etc/hosts 127.0.0.1 localhost.localdomain localhost $name EOF # Allow to login at virsh console. loginuid.so doen't work in the absence of auditd. # sed -i 's/^.*loginuid.so.*$/\#&/' ${rootfs_path}/etc/pam.d/common-login # Allow root to login at virsh console echo "pts/0" >> ${rootfs_path}/etc/securetty echo "console" >> ${rootfs_path}/etc/securetty # Enable services for service in network syslogd random NetworkManager do chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service on || true # For systemd chroot ${rootfs_path} systemctl -q enable $service &>/dev/null|| true done # Disable services for service in rawdevices fbsetfont do chroot ${rootfs_path} chkconfig $service --list &>/dev/null && chroot ${rootfs_path} chkconfig $service off || true chroot ${rootfs_path} systemctl -q disable $service &>/dev/null || true done subst 's/^\([3-9]\+:[0-9]\+:respawn:\/sbin\/mingetty.*\)/#\1/' ${rootfs_path}/etc/inittab echo "c1:2345:respawn:/sbin/mingetty --noclear console" >> ${rootfs_path}/etc/inittab [ -f "${rootfs_path}/etc/syslog.conf" ] && \ subst 's,\/dev\/tty12,/var/log/syslog/console,' ${rootfs_path}/etc/syslog.conf dev_path="${rootfs_path}/dev" rm -rf ${dev_path} mkdir -p ${dev_path} mknod -m 666 ${dev_path}/null c 1 3 mknod -m 666 ${dev_path}/zero c 1 5 mknod -m 644 ${dev_path}/random c 1 8 mknod -m 644 ${dev_path}/urandom c 1 9 mkdir -m 755 ${dev_path}/pts mkdir -m 1777 ${dev_path}/shm mknod -m 666 ${dev_path}/tty c 5 0 chown root:tty ${dev_path}/tty mknod -m 600 ${dev_path}/tty0 c 4 0 mknod -m 600 ${dev_path}/tty1 c 4 1 mknod -m 600 ${dev_path}/tty2 c 4 2 mknod -m 600 ${dev_path}/tty3 c 4 3 mknod -m 600 ${dev_path}/tty4 c 4 4 mknod -m 600 ${dev_path}/console c 5 1 mknod -m 666 ${dev_path}/full c 1 7 mknod -m 600 ${dev_path}/initctl p mknod -m 666 ${dev_path}/ptmx c 5 2 chown root:tty ${dev_path}/ptmx ln -s /proc/self/fd ${dev_path}/fd ln -s /proc/kcore ${dev_path}/core mkdir -m 755 ${dev_path}/mapper mknod -m 600 ${dev_path}/mapper/control c 10 236 mkdir -m 755 ${dev_path}/net mknod -m 666 ${dev_path}/net/tun c 10 200 echo "setting root passwd to $root_password" echo "root:$root_password" | chroot $rootfs_path chpasswd return 0 } download_altlinux() { # check the mini altlinux was not already downloaded INSTALL_ROOT=$cache/partial mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then echo "Failed to create '$INSTALL_ROOT' directory" return 1 fi # download a mini altlinux into a cache echo "Downloading altlinux minimal ..." APT_GET="apt-get -o RPM::RootDir=$INSTALL_ROOT -y" PKG_LIST="$(grep -hs '^[^#]' "$profile_dir/$profile")" # if no configuration file $profile -- fall back to default list of packages [ -z "$PKG_LIST" ] && PKG_LIST="interactivesystem apt apt-conf-sisyphus etcnet-full openssh-server systemd-sysvinit systemd-units systemd NetworkManager-daemon" mkdir -p $INSTALL_ROOT/var/lib/rpm rpm --root $INSTALL_ROOT --initdb # some scripts want to have /dev/null at least dev_path="$INSTALL_ROOT/dev" if [ ! -c "${dev_path}/null" ]; then mkdir -p "${dev_path}" mknod -m 666 "${dev_path}/null" c 1 3 fi $APT_GET install $PKG_LIST if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv "$INSTALL_ROOT" "$cache/rootfs" echo "Download complete." return 0 } copy_altlinux() { # make a local copy of the minialtlinux echo -n "Copying rootfs to $rootfs_path ..." #cp -a $cache/rootfs-$arch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path rsync -Ha $cache/rootfs/ $rootfs_path/ return 0 } update_altlinux() { chroot $cache/rootfs apt-get update chroot $cache/rootfs apt-get -y dist-upgrade } install_altlinux() { mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs ... " if [ ! -e "$cache/rootfs" ]; then download_altlinux if [ $? -ne 0 ]; then echo "Failed to download 'altlinux base'" return 1 fi else echo "Cache found. Updating..." update_altlinux if [ $? -ne 0 ]; then echo "Failed to update 'altlinux base', continuing with last known good cache" else echo "Update finished" fi fi echo "Copy $cache/rootfs to $rootfs_path ... " copy_altlinux if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux return $? } copy_configuration() { mkdir -p $config_path grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config cat <> $config_path/config lxc.utsname = $name lxc.tty = 4 lxc.pts = 1024 lxc.cap.drop = sys_module mac_admin mac_override sys_time # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined #networking #lxc.network.type = $lxc_network_type #lxc.network.flags = up #lxc.network.link = $lxc_network_link #lxc.network.name = veth0 #lxc.network.mtu = 1500 EOF if [ ! -z ${ipv4} ]; then cat <> $config_path/config lxc.network.ipv4 = $ipv4 EOF fi if [ ! -z ${gw} ]; then cat <> $config_path/config lxc.network.ipv4.gateway = $gw EOF fi if [ ! -z ${ipv6} ]; then cat <> $config_path/config lxc.network.ipv6 = $ipv6 EOF fi if [ ! -z ${gw6} ]; then cat <> $config_path/config lxc.network.ipv6.gateway = $gw6 EOF fi cat <> $config_path/config #cgroups lxc.cgroup.devices.deny = a # /dev/null and zero lxc.cgroup.devices.allow = c 1:3 rwm lxc.cgroup.devices.allow = c 1:5 rwm # consoles lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:0 rwm lxc.cgroup.devices.allow = c 4:0 rwm lxc.cgroup.devices.allow = c 4:1 rwm # /dev/{,u}random lxc.cgroup.devices.allow = c 1:9 rwm lxc.cgroup.devices.allow = c 1:8 rwm lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc lxc.cgroup.devices.allow = c 10:135 rwm lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } clean() { if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache for ALTLinux-$release..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-altlinux } usage() { cat < [-p|--path=] [-c|--clean] [-R|--release=] [-4|--ipv4=] [-6|--ipv6=] [-g|--gw=] [-d|--dns=] [-P|--profile=] [--rootfs=] [-A|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: -p,--path path to where the container rootfs will be created, defaults to @LXCPATH@. The container config will go under @LXCPATH@ in that case -c,--clean clean the cache -R,--release ALTLinux release for the new container. if the host is ALTLinux, then it will defaultto the host's release. -4,--ipv4 specify the ipv4 address to assign to the virtualized interface, eg. 192.168.1.123/24 -6,--ipv6 specify the ipv6 address to assign to the virtualized interface, eg. 2003:db8:1:0:214:1234:fe0b:3596/64 -g,--gw specify the default gw, eg. 192.168.1.1 -G,--gw6 specify the default gw, eg. 2003:db8:1:0:214:1234:fe0b:3596 -d,--dns specify the DNS server, eg. 192.168.1.2 -P,--profile Profile name is the file name in /etc/lxc/profiles contained packages name for install to cache. -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64] ---rootfs rootfs path -h,--help print this help EOF return 0 } options=$(getopt -o hp:n:P:cR:4:6:g:d: -l help,rootfs:,path:,name:,profile:,clean,release:,ipv4:,ipv6:,gw:,dns: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs_path=$2; shift 2;; -n|--name) name=$2; shift 2;; -P|--profile) profile=$2; shift 2;; -c|--clean) clean=1; shift 1;; -R|--release) release=$2; shift 2;; -4|--ipv4) ipv4=$2; shift 2;; -6|--ipv6) ipv6=$2; shift 2;; -g|--gw) gw=$2; shift 2;; -d|--dns) dns=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi type apt-get >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "'apt-get' command is missing" exit 1 fi if [ -z "$path" ]; then path=$default_path fi if [ -z "$profile" ]; then profile=$default_profile fi if [ -z "$release" ]; then if [ "$is_altlinux" ]; then release=$(cat /etc/altlinux-release |awk '/^ALT/ {print $3}') else echo "This is not a ALTLinux host and release missing, use -R|--release to specify release" exit 1 fi fi if [ -z "$ipv4" -a -z "$ipv6" ]; then BOOTPROTO="dhcp" else BOOTPROTO="static" fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi # check for 'lxc.rootfs' passed in through default config by lxc-create if [ -z "$rootfs_path" ]; then if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then rootfs_path=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config) else rootfs_path=$path/rootfs fi fi config_path=$default_path/$name cache=$cache_base/$release/$profile install_altlinux if [ $? -ne 0 ]; then echo "failed to install altlinux" exit 1 fi configure_altlinux if [ $? -ne 0 ]; then echo "failed to configure altlinux for a container" exit 1 fi copy_configuration if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi echo "container rootfs and config created" echo "network configured as $lxc_network_type in the $lxc_network_link" lxc-2.0.0/templates/lxc-sparclinux.in0000644061062106075000000006366012701247216014547 00000000000000#!/bin/sh # # Template script for generating Linux for SPARC for LXC # based on lxc-fedora, lxc-ubuntu # # Copyright © 2011 Wim Coekaerts # Copyright © 2012 Dwight Engen # Copyright � 2015 Wim Coekaerts # # Modified for Oracle Linux 5 # Wim Coekaerts # # Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script # Dwight Engen # # Modified for Linux for SPARC 1.0 # Wim Coekaerts # # 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 # version 2.1 of the License, or (at your option) any later version. # # This library 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 # use virbr0 that is setup by default by libvirtd lxc_network_type=veth lxc_network_link=virbr0 die() { echo "failed: $1" exit 1 } is_btrfs_subvolume() { if which btrfs >/dev/null 2>&1 && \ btrfs subvolume list "$1" >/dev/null 2>&1; then return 0 fi return 1 } can_chcon() { if which chcon >/dev/null 2>&1; then selinuxenabled >/dev/null 2>&1 return $? fi return 1 } # fix up the container_rootfs container_rootfs_patch() { echo "Patching container rootfs $container_rootfs for Linux for SPARC $container_release_major.$container_release_minor" # copy ourself into the container to be used to --patch the rootfs when # yum update on certain packages is done. we do this here instead of in # container_rootfs_configure() in case the patching done in this function # is updated in the future, we can inject the updated version of ourself # into older containers. if [ $container_rootfs != "/" ]; then cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch mkdir -p $container_rootfs/usr/share/yum-plugins cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins mkdir -p $container_rootfs/etc/yum/pluginconf.d cat < $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf [main] enabled=1 packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng EOF fi # "disable" selinux in the guest. The policy in the container isn't # likely to match the hosts (unless host == guest exactly) and the # kernel can only be enforcing one policy. # mkdir -p $container_rootfs/selinux echo 0 > $container_rootfs/selinux/enforce if [ -e $container_rootfs/etc/selinux/config ]; then sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config else mkdir -p $container_rootfs/etc/selinux echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config fi sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd # setting /proc/$$/loginuid doesn't work under user namespace, which # prevents logins from working sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/sshd sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login if [ -f $container_rootfs/usr/sbin/selinuxenabled ]; then mv $container_rootfs/usr/sbin/selinuxenabled $container_rootfs/usr/sbin/selinuxenabled.lxcorig ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled fi # ensure /dev/ptmx refers to the newinstance devpts of the container, or # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512) rm -f $container_rootfs/dev/ptmx ln -s pts/ptmx $container_rootfs/dev/ptmx # silence error in checking for selinux sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit # disable ipv6 rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global # remove module stuff for iptables it just shows errors that are not # relevant in a container if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config fi # disable readahead in the container if [ $container_release_major = "1" -a -e $container_rootfs/etc/sysconfig/readahead ]; then rm -f $container_rootfs/etc/init/readahead-collector.conf rm -f $container_rootfs/etc/init/readahead-disable-services.conf sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead fi # no need to attempt to mount / sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit # disable udev in the container sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit touch $container_rootfs/.nolvm # fix assumptions that plymouth is available sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit rm -f $container_rootfs/etc/init/plymouth-shutdown.conf rm -f $container_rootfs/etc/init/quit-plymouth.conf rm -f $container_rootfs/etc/init/splash-manager.conf # dont try to unmount /dev/lxc devices sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt # don't try to unmount swap sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit # there might be other services that are useless but the below set is a good start # some of these might not exist in the image, so we silence chkconfig complaining # about the service file not being found for service in \ acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \ ip6tables irqbalance iscsi iscsid isdn kdump kudzu \ lm_sensors lvm2-monitor mdmonitor microcode_ctl \ ntpd pcmcia postfix sendmail udev-post xfs ; do chroot $container_rootfs chkconfig 2>/dev/null $service off done for service in rsyslog ; do chroot $container_rootfs chkconfig 2>/dev/null $service on done } container_rootfs_configure() { container_rootfs_patch echo "Configuring container for Linux for SPARC $container_release_major.$container_release_minor" # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest # will report its name and be resolv'able by the hosts dnsmasq cat < $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes HOSTNAME=$name DHCP_HOSTNAME=\`hostname\` NM_CONTROLLED=no TYPE=Ethernet EOF cat < $container_rootfs/etc/sysconfig/network NETWORKING=yes NETWORKING_IPV6=no HOSTNAME=$name EOF # set minimal hosts echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts # this file has to exist for libvirt/Virtual machine monitor to boot the container touch $container_rootfs/etc/mtab # setup console and tty[1-4] for login. note that /dev/console and # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. # lxc will maintain these links and bind mount ptys over /dev/lxc/* # since lxc.devttydir is specified in the config. # allow root login on console, tty[1-4], and pts/0 for libvirt echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty echo "lxc/console" >>$container_rootfs/etc/securetty for i in 1 2 3 4; do echo "lxc/tty$i" >>$container_rootfs/etc/securetty done echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty for i in 0 1 2 3 4; do echo "pts/$i" >>$container_rootfs/etc/securetty done # prevent mingetty from calling vhangup(2) since it fails with userns if [ -f $container_rootfs/etc/init/tty.conf ]; then sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf fi # create maygetty which only spawns a getty on the console when running # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty # as /dev/tty1 cat <$container_rootfs/sbin/maygetty #!/bin/sh if [ "\$container" = "lxc" ]; then exec /sbin/mingetty \$@ fi exec sleep infinity EOF chmod 755 $container_rootfs/sbin/maygetty cat < $container_rootfs/etc/init/console.conf # console - getty # # This service maintains a getty on the console from the point the system is # started until it is shut down again. start on stopped rc RUNLEVEL=[2345] stop on runlevel [!2345] env container respawn exec /sbin/maygetty --nohangup --noclear /dev/console EOF cat < $container_rootfs/etc/init/power-status-changed.conf # power-status-changed - used to cleanly shut down the container # # This task is run whenever init receives SIGPWR # Used to shut down the machine. start on power-status-changed exec init 0 EOF # start with a clean /var/log/messages rm -f $container_rootfs/var/log/messages # set initial timezone as on host if [ -f /etc/sysconfig/clock ]; then . /etc/sysconfig/clock echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock chroot $container_rootfs tzdata-update else echo "Timezone in container is not configured. Adjust it manually." fi # add oracle user, set root password chroot $container_rootfs useradd -m -s /bin/bash oracle echo "oracle:oracle" | chroot $container_rootfs chpasswd echo "root:root" | chroot $container_rootfs chpasswd printf "Added container user:\033[1moracle\033[0m password:\033[1moracle\033[0m\n" printf "Added container user:\033[1mroot\033[0m password:\033[1mroot\033[0m\n" } # create the container's lxc config file container_config_create() { echo "Create configuration file $cfg_dir/config" mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir" echo "# Common configuration" >> $cfg_dir/config if [ -e "@LXCTEMPLATECONFIG@/sparclinux.common.conf" ]; then echo "lxc.include = @LXCTEMPLATECONFIG@/sparclinux.common.conf" >> $cfg_dir/config fi # generate a hwaddr for the container with a high mac address # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303 local hwaddr="fe:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \ head -n 1 |awk '{print $2}' | cut -c1-10 |\ sed 's/\(..\)/\1:/g; s/.$//'`" cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" # Container configuration for Linux for SPARC $container_release_major.$container_release_minor lxc.arch = $arch lxc.utsname = $name EOF grep -q "^lxc.rootfs" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs = $container_rootfs" >> $cfg_dir/config echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config echo "# Networking" >>$cfg_dir/config # see if the network settings were already specified lxc_network_type=`grep '^lxc.network.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'` if [ -z "$lxc_network_type" -a \ \( $host_distribution = "SPARCLinux" -o \ $host_distribution = "Fedora" \) ]; then echo "lxc.network.type = veth" >>$cfg_dir/config echo "lxc.network.flags = up" >>$cfg_dir/config echo "lxc.network.link = virbr0" >>$cfg_dir/config fi cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" lxc.network.name = eth0 lxc.network.mtu = 1500 lxc.network.hwaddr = $hwaddr EOF } container_rootfs_clone() { if is_btrfs_subvolume $template_rootfs; then # lxc-create already made $container_rootfs a btrfs subvolume, but # in this case we want to snapshot the original subvolume so we we # have to delete the one that lxc-create made btrfs subvolume delete $container_rootfs btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template" else echo "Copying rootfs ..." cp -axT $template_rootfs $container_rootfs || die "copy template" fi } container_rootfs_repo_create() { echo "# LXC generated .repo file" >$1 echo "[$2]" >>$1 echo "name=Linux for SPARC $container_release_major.$container_release_minor ($basearch)" >>$1 echo "baseurl=$3/" >>$1 echo "enabled=1" >>$1 echo "skip_if_unavailable=1" >>$1 if [ "$4" != "" ]; then echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1 echo "gpgcheck=1" >>$1 else echo "gpgcheck=0" >>$1 fi } container_rootfs_dev_create() { # create required devices. note that /dev/console will be created by lxc # or libvirt itself to be a symlink to the right pty. # take care to not nuke /dev in case $container_rootfs isn't set dev_path="$container_rootfs/dev" if [ $container_rootfs != "/" -a -d $dev_path ]; then rm -rf $dev_path fi mkdir -p $dev_path if can_chcon; then # ensure symlinks created in /dev have the right context chcon -t device_t $dev_path fi mknod -m 666 $dev_path/null c 1 3 mknod -m 666 $dev_path/zero c 1 5 mknod -m 666 $dev_path/random c 1 8 mknod -m 666 $dev_path/urandom c 1 9 mkdir -m 755 $dev_path/pts mkdir -m 1777 $dev_path/shm mknod -m 666 $dev_path/tty c 5 0 mknod -m 666 $dev_path/tty1 c 4 1 mknod -m 666 $dev_path/tty2 c 4 2 mknod -m 666 $dev_path/tty3 c 4 3 mknod -m 666 $dev_path/tty4 c 4 4 mknod -m 666 $dev_path/full c 1 7 mknod -m 600 $dev_path/initctl p # set selinux labels same as host if can_chcon; then for node in null zero random urandom pts shm \ tty tty0 tty1 tty2 tty3 tty4 full ; do chcon --reference /dev/$node $dev_path/$node 2>/dev/null done fi } container_rootfs_create() { if can_chcon; then chcon --reference / $container_rootfs 2>/dev/null fi cmds="rpm wget yum" for cmd in $cmds; do which $cmd >/dev/null 2>&1 if [ $? -ne 0 ]; then die "The $cmd command is required, please install it" fi done mkdir -p @LOCALSTATEDIR@/lock/subsys ( flock -x 9 if [ $? -ne 0 ]; then die "The template is busy." fi echo "Yum installing release $container_release_major.$container_release_minor for $basearch" if [ -n "$repourl" ]; then yum_url=$repourl else yum_url=http://yum.oracle.com fi if [ -n "$baseurl" ]; then # create .repo pointing at baseurl repo="lxc-install" mkdir -p $container_rootfs/etc/yum.repos.d container_rootfs_repo_create \ $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl else # get public-yum repo file if [ $container_release_major = "1" ]; then repofile=yum-linux-sparc64.repo else die "Unsupported release $container_release_major" fi mkdir -p $container_rootfs/etc/yum.repos.d wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile if [ $? -ne 0 ]; then die "Unable to download repo file $yum_url/$repofile, release unavailable" fi # yum will take $basearch from host, so force the arch we want sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile # replace url if they specified one if [ -n "$repourl" ]; then sed -i "s|baseurl=http://yum.oracle.com/|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile sed -i "s|gpgkey=http://yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile fi # disable all repos, then enable the repo for the version we are installing. if [ $container_release_minor = "latest" ]; then repo="lfs"_$container_release_minor else die "Unsupported release $container_release_major.$container_release_minor" fi sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile fi container_rootfs_dev_create # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt echo "" >$container_rootfs/etc/fstab # create rpm db, download and yum install minimal packages mkdir -p $container_rootfs/var/lib/rpm rpm --root $container_rootfs --initdb yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck" min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils sparclinux-release" # we unshare the mount namespace because yum installing the ol4 # packages causes $rootfs/proc to be mounted on lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs if [ $? -ne 0 ]; then die "Failed to download and install the rootfs, aborting." fi # rsyslog and pam depend on coreutils for some common commands in # their POSTIN scriptlets, but coreutils wasn't installed yet. now # that coreutils is installed, reinstall the packages so their POSTIN # runs right. similarly, libutempter depends on libselinux.so.1 when # it runs /usr/sbin/groupadd, so reinstall it too redo_pkgs="" if [ x"$redo_pkgs" != x ]; then rpm --root $container_rootfs --nodeps -e $redo_pkgs lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs if [ $? -ne 0 ]; then die "Unable to reinstall packages" fi fi # these distributions put the rpm database in a place the guest is # not expecting it, so move it if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm fi # if the native rpm created the db with Hash version 9, we need to # downgrade it to Hash version 8 for use with OL5.x db_version=`file $container_rootfs/var/lib/rpm/Packages | \ grep -o 'version [0-9]*' |awk '{print $2}'` # the host rpm may not be the same as the guest, rebuild the db with # the guest rpm version echo "Rebuilding rpm database" rm -f $container_rootfs/var/lib/rpm/__db* chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-sparclinux-$name if [ $? -ne 0 ]; then exit 1 fi } container_release_get() { if [ -f $1/etc/sparclinux-release ]; then container_release_version=`cat $1/etc/sparclinux-release |awk '/^Linux/ {print $5}'` container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` else echo "Unable to determine container release version" exit 1 fi } usage() { cat < architecture (sparc64) -R|--release= release to download for the new container --rootfs= rootfs path -r|--rpms= additional rpms to install into container -u|--url= replace yum repo url (ie. Oracle public-yum mirror) --baseurl= use package repository (ie. file:///mnt) arch and release must also be specified -t|--templatefs= copy/clone rootfs at path instead of downloading -P|--patch= only patch the rootfs at path for use as a container -h|--help Release is of the format "major.minor", for example "1.0" or "1.latest" This template supports Linux for SPARC release 1.0 EOF return 0 } options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) cfg_dir=$2; shift 2;; --rootfs) container_rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -R|--release) container_release_version=$2; shift 2;; -r|--rpms) user_pkgs=$2; shift 2;; -u|--url) repourl=$2; shift 2;; -t|--templatefs) template_rootfs=$2; shift 2;; --patch) patch_rootfs=$2; shift 2;; --baseurl) baseurl=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done # make sure mandatory args are given and valid if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -n "$baseurl" ]; then if [ "$arch" = "" -o "$container_release_version" = "" ]; then echo "The --arch and --release must be specified when using --baseurl" usage exit 1 fi fi if [ "$arch" = "" ]; then arch=$(uname -m) fi if [ -n "$patch_rootfs" ]; then container_rootfs="$patch_rootfs" container_release_get $container_rootfs container_rootfs_patch exit 0 fi if [ -z $name ]; then echo "Container name must be given" usage exit 1 fi if [ -z $cfg_dir ]; then echo "Configuration directory must be given, check lxc-create" usage exit 1 fi basearch=$arch if [ "$arch" != "sparc64" ]; then echo "Bad architecture given, check lxc-create" usage exit 1 fi if [ -f /etc/sparclinux-release ]; then host_distribution="SPARCLinux" host_release_version=`cat /etc/sparclinux-release |awk '{print $5}'` host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` else echo "Unable to determine host distribution" exit 1 fi echo "Host is $host_distribution $host_release_version" if [ -z "$container_rootfs" ]; then container_rootfs="$cfg_dir/rootfs" fi if [ -n "$template_rootfs" ]; then container_release_get $template_rootfs else if [ -z "$container_release_version" ]; then if [ $host_distribution = "SPARCLinux" ]; then container_release_version=$host_release_version else echo "No release specified with -R, defaulting to 1.latest" container_release_version="1.latest" fi fi container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` fi container_config_create if [ -n "$template_rootfs" ]; then container_rootfs_clone else container_rootfs_create fi container_release_get $container_rootfs container_rootfs_configure echo "Container : $container_rootfs" echo "Config : $cfg_dir/config" echo "Network : eth0 ($lxc_network_type) on $lxc_network_link" lxc-2.0.0/templates/lxc-ubuntu-cloud.in0000644061062106075000000002626012701247216015000 00000000000000#!/bin/bash # template script for generating ubuntu container for LXC based on released # cloud images. # # Copyright © 2012 Serge Hallyn # # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA set -e STATE_DIR="@LOCALSTATEDIR@" HOOK_DIR="@LXCHOOKDIR@" CLONE_HOOK_FN="$HOOK_DIR/ubuntu-cloud-prep" LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" KNOWN_RELEASES="precise trusty vivid wily xenial" skip_arch_check=${UCTEMPLATE_SKIP_ARCH_CHECK:-0} # Make sure the usual locations are in PATH export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin if [ -r /etc/default/lxc ]; then . /etc/default/lxc fi 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 copy_configuration() { path=$1 rootfs=$2 name=$3 arch=$4 release=$5 if [ $arch = "i386" ]; then arch="i686" fi # if there is exactly one veth network entry, make sure it has an # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` if [ $nics -eq 1 ]; then grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config fi # Generate the configuration file ## Relocate all the network config entries sed -i -e "/lxc.network/{w ${path}/config-network" -e "d}" $path/config ## Relocate any other config entries sed -i -e "/lxc./{w ${path}/config-auto" -e "d}" $path/config ## Add all the includes echo "" >> $path/config echo "# Common configuration" >> $path/config if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.common.conf" >> $path/config fi if [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.${release}.conf" >> $path/config fi if [ $in_userns -eq 1 ] && [ -e "${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/ubuntu-cloud.userns.conf" >> $path/config fi ## Add the container-specific config echo "" >> $path/config echo "# Container specific configuration" >> $path/config [ -e "$path/config-auto" ] && cat $path/config-auto >> $path/config && rm $path/config-auto grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.utsname = $name lxc.arch = $arch EOF ## Re-add the previously removed network config echo "" >> $path/config echo "# Network configuration" >> $path/config cat $path/config-network >> $path/config rm $path/config-network # Set initial timezone as on host if [ -f /etc/timezone ]; then cat /etc/timezone > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata elif [ -f /etc/sysconfig/clock ]; then . /etc/sysconfig/clock echo $ZONE > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata else echo "Timezone in container is not configured. Adjust it manually." fi # rmdir /dev/shm for containers that have /run/shm # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did # get bind mounted to the host's /run/shm. So try to rmdir # it, and in case that fails move it out of the way. # NOTE: This can only be removed once 12.04 goes out of support if [ ! -L $rootfs/dev/shm ] && [ -e $rootfs/dev/shm ]; then rmdir $rootfs/dev/shm 2>/dev/null || mv $rootfs/dev/shm $rootfs/dev/shm.bak ln -s /run/shm $rootfs/dev/shm fi return 0 } usage() { cat < ]: Release name of container, defaults to host [ --rootfs ]: Path in which rootfs will be placed [ -a | --arch ]: Architecture of container, defaults to host architecture [ -T | --tarball ]: Location of tarball [ -d | --debug ]: Run with 'set -x' to debug errors [ -s | --stream]: Use specified stream rather than 'tryreleased' Additionally, clone hooks can be passed through (ie, --userdata). For those, see: $CLONE_HOOK_FN --help EOF return 0 } options=$(getopt -o a:hp:r:n:Fi:CLS:T:ds:u: -l arch:,help,rootfs:,path:,release:,name:,flush-cache,hostid:,auth-key:,cloud,no_locales,tarball:,debug,stream:,userdata:,vendordata:,mapped-uid:,mapped-gid: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" mapped_uid=-1 mapped_gid=-1 # default release is trusty, or the systems release if recognized release=trusty if [ -f /etc/lsb-release ]; then . /etc/lsb-release rels=$(ubuntu-distro-info --supported 2>/dev/null) || rels="$KNOWN_RELEASES" for r in $rels; do [ "$DISTRIB_CODENAME" = "$r" ] && release="$r" done fi # Code taken from debootstrap if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/dpkg --print-architecture` elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then arch=`/usr/bin/udpkg --print-architecture` else arch=$(uname -m) if [ "$arch" = "i686" ]; then arch="i386" elif [ "$arch" = "x86_64" ]; then arch="amd64" elif [ "$arch" = "armv7l" ]; then # note: arm images don't exist before oneiric; are called armhf in # trusty and later; and are not supported by the query, so we don't actually # support them yet (see check later on). When Query2 is available, # we'll use that to enable arm images. arch="armhf" elif [ "$arch" = "aarch64" ]; then arch="arm64" elif [ "$arch" = "ppc64le" ]; then arch="ppc64el" fi fi debug=0 hostarch=$arch cloud=0 locales=1 flushcache=0 stream="tryreleased" cloneargs=() while true do case "$1" in -h|--help) usage $0 && exit 1;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; -F|--flush-cache) flushcache=1; shift 1;; -r|--release) release=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -T|--tarball) tarball=$2; shift 2;; -d|--debug) debug=1; shift 1;; -s|--stream) stream=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; -L|--no?locales) cloneargs[${#cloneargs[@]}]="--no-locales"; shift 1;; -i|--hostid) cloneargs[${#cloneargs[@]}]="--hostid=$2"; shift 2;; -u|--userdata) cloneargs[${#cloneargs[@]}]="--userdata=$2"; shift 2;; -V|--vendordata) cloneargs[${#cloneargs[@]}]="--vendordata=$2"; shift 2;; -C|--cloud) cloneargs[${#cloneargs[@]}]="--cloud"; shift 1;; -S|--auth-key) cloneargs[${#cloneargs[@]}]="--auth-key=$2"; shift 2;; --mapped-uid) mapped_uid=$2; shift 2;; --mapped-gid) mapped_gid=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done cloneargs=( "--name=$name" "${cloneargs[@]}" ) if [ $debug -eq 1 ]; then set -x fi if [ "$arch" = "i686" ]; then arch=i386 fi if [ "$skip_arch_check" = "0" ]; then case "$hostarch:$arch" in $arch:$arch) : ;; # the host == container amd64:i386) :;; # supported "cross" arm64:arm*) :;; # supported "cross" armel:armhf) :;; # supported "cross" armhf:armel) :;; # supported "cross" *) echo "cannot create '$arch' container on hostarch '$hostarch'"; exit 1;; esac fi if [ "$stream" != "daily" -a "$stream" != "released" -a "$stream" != "tryreleased" ]; then echo "Only 'daily' and 'released' and 'tryreleased' streams are supported" exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi # detect rootfs config="$path/config" if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi type ubuntu-cloudimg-query type wget # determine the url, tarball, and directory names # download if needed # Allow the cache base to be set by environment variable cache=${LXC_CACHE_PATH:-"$STATE_DIR/cache/lxc"}/cloud-$release if [ $in_userns -eq 1 ]; then STATE_DIR="$HOME/.cache/lxc" cache=${LXC_CACHE_PATH:-"$STATE_DIR"}/cloud-$release fi mkdir -p $cache if [ "$stream" = "tryreleased" ]; then stream=released ubuntu-cloudimg-query $release $stream $arch 1>/dev/null 2>/dev/null || stream=daily fi if [ -n "$tarball" ]; then url2="$tarball" else if ! url1=`ubuntu-cloudimg-query $release $stream $arch --format "%{url}\n"`; then echo "There is no download available for release=$release, stream=$stream, arch=$arch" [ "$stream" = "daily" ] || echo "You may try with '--stream=daily'" exit 1 fi url2=`echo $url1 | sed -e 's/.tar.gz/-root\0/' -e 's/.tar.gz/.tar.xz/'` fi filename=`basename $url2` wgetcleanup() { rm -f $filename } do_extract_rootfs() { cd $cache if [ $flushcache -eq 1 ]; then echo "Clearing the cached images" rm -f $filename fi trap wgetcleanup EXIT SIGHUP SIGINT SIGTERM if [ ! -f $filename ]; then wget $url2 fi trap EXIT trap SIGHUP trap SIGINT trap SIGTERM echo "Extracting container rootfs" mkdir -p $rootfs cd $rootfs if [ $in_userns -eq 1 ]; then tar --anchored --exclude="dev/*" --numeric-owner -xpf "$cache/$filename" mkdir -p $rootfs/dev/pts/ else tar --numeric-owner -xpf "$cache/$filename" fi } if [ -n "$tarball" ]; then do_extract_rootfs else mkdir -p "$STATE_DIR/lock/subsys/" ( flock -x 9 do_extract_rootfs ) 9>"$STATE_DIR/lock/subsys/lxc-ubuntu-cloud" fi copy_configuration $path $rootfs $name $arch $release "$CLONE_HOOK_FN" "${cloneargs[@]}" "$rootfs" if [ $mapped_uid -ne -1 ]; then chown $mapped_uid $path/config chown -R $mapped_uid $STATE_DIR chown -R $mapped_uid $cache fi if [ $mapped_gid -ne -1 ]; then chgrp $mapped_gid $path/config chgrp -R $mapped_gid $STATE_DIR chgrp -R $mapped_gid $cache fi echo "Container $name created." exit 0 # vi: ts=4 expandtab lxc-2.0.0/templates/lxc-cirros.in0000644061062106075000000002421712701247216013653 00000000000000#!/bin/bash # template script for generating ubuntu container for LXC # # This script consolidates and extends the existing lxc ubuntu scripts # # Copyright © 2013 Canonical Ltd. # Author: Scott Moser # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, 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; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # Detect use under userns (unsupported) # 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/" 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" case "${UNAME_M}" in i?86) DEF_ARCH="i386";; x86_64) DEF_ARCH="x86_64";; arm*) DEF_ARCH="arm";; *) 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 # Allow the cache base to be set by environment variable if [ $(id -u) -eq 0 ]; then CACHE_D=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc/cirros"} else CACHE_D=${LXC_CACHE_PATH:-"$HOME/.cache/lxc/cirros"} fi error() { echo "$@" 1>&2; } inargs() { local needle="$1" x="" shift for x in "$@"; do [ "$needle" = "$x" ] && return 0 done return 1 } Usage() { cat <&2; [ $# -eq 0 ] || error "$@"; return 1; } debug() { local level=${1}; shift; [ "${level}" -gt "${VERBOSITY}" ] && return error "${@}" } jsondict() { local k="" v="" ret="{" for arg in "$@"; do k="${arg%%=*}" v="${arg#*=}" ret="${ret} \"${k}\": \"$v\"," done ret="${ret%,} }" echo "$ret" } copy_configuration() { local path=$1 rootfs=$2 name=$3 arch=$4 release=$5 cat >> "$path/config" <> $path/config fi } insert_ds_nocloud() { local root_d="$1" authkey="$2" udfile="$3" local sdir="$root_d/var/lib/cloud/seed/nocloud" mkdir -p "$sdir" || { error "failed to make datasource dir $sdir"; return 1; } rm -f "$sdir/meta-data" "$sdir/user-data" || { error "failed to clean old data from $sdir"; return 1; } iid="iid-local01" jsondict "instance-id=$iid" \ ${authkeys:+"public-keys=${authkeys}"} > "$sdir/meta-data" || { error "failed to write metadata to $sdir/meta-data"; return 1; } if [ -n "$udfile" ]; then cat "$udfile" > "$sdir/user-data" || { error "failed to write user-data to $sdir"; return 1; } else rm -f "$sdir/user-data" fi } insert_ds() { local dstype="$1" root_d="$2" authkey="$3" udfile="$4" case "$dstype" in nocloud) insert_ds_nocloud "$root_d" "$authkey" "$udfile" esac } extract_rootfs() { local tarball="$1" rootfs_d="$2" mkdir -p "${rootfs_d}" || { error "failed to make rootfs dir ${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 } download_tarball() { local arch="$1" ver="$2" cached="$3" baseurl="$4" local out="" outd="" file="" dlpath="" file="cirros-$ver-$arch-lxc.tar.gz" dlpath="$ver/$file" outd="${cached}/${dlpath%/*}" if [ -f "$cached/$dlpath" ]; then _RET="$cached/$dlpath" return 0 fi mkdir -p "${outd}" || { error "failed to create ${outd}"; return 1; } debug 1 "downloading ${baseurl%/}/$dlpath" to "${cached}/$dlpath" wget "${baseurl%/}/$dlpath" -O "$cached/${dlpath}.$$" && mv "$cached/$dlpath.$$" "$cached/$dlpath" || { rm -f "$cached/$dlpath.$$"; error "failed to download $dlpath"; return 1; } _RET="$cached/$dlpath" } create_main() { local short_opts="a:hn:p:S:uvV" 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}" -- "$@") && eval set -- "${getopt_out}" || { bad_Usage; return; } local arch="${DEF_ARCH}" dsource="${DEF_SOURCE}" version="${DEF_VERSION}" local authkey_f="" authkeys="" userdata_f="" path="" tarball="" local cur="" next="" local rootfs_d="" while [ $# -ne 0 ]; do cur=$1; next=$2; case "$cur" in -a|--arch) arch="$next"; shift;; -h|--help) Usage ; return 0;; -n|--name) name="$next"; shift;; -v|--verbose) VERBOSITY=$((${VERBOSITY}+1));; -S|--auth-key) authkey_f="$next"; shift;; -p|--path) path=$next; shift;; -v|--version) version=$next; shift;; -u|--userdata) userdata_f="$next"; shift;; --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; done [ -n "$rootfs_d" ] || rootfs_d="$path/rootfs" [ $# -eq 0 ] || { bad_Usage "unexpected arguments: $*"; return; } [ -n "$path" ] || { error "'path' parameter is required"; return 1; } if [ "$(id -u)" != "0" ]; then { error "must be run as root"; return 1; } fi case "$arch" in i?86) arch="i386";; amd64) arch="x86_64";; esac inargs "$arch" "${ARCHES[@]}" || { error "bad arch '$arch'. allowed: ${ARCHES[*]}"; return 1; } inargs "$dsource" "${SOURCES[@]}" || { error "bad source '$dsource'. allowed: ${SOURCES[*]}"; return 1; } if [ "$dsource" = "none" ] && [ -n "$userdata_f" -o -n "$authkey_f" ]; then error "userdata and authkey are incompatible with --source=none"; return 1; fi if [ -n "$authkey_f" ]; then if [ ! -f "$authkey_f" ]; then error "--auth-key=${authkey_f} must reference a file" return 1 fi authkeys=$(cat "$authkey_f") || { error "failed to read ${authkey_f}"; return 1; } fi if [ -n "$userdata_f" -a ! -f "${userdata_f}" ]; then error "${userdata_f}: --userdata arg not a file" return 1 fi if [ -z "$tarball" ]; then if inargs "$version" "${STREAMS[@]}"; then out=$(wget -O - -q "${DOWNLOAD_URL%/}/version/$version") || { error "failed to convert 'version=$version'"; return 1; } version="$out" fi download_tarball "$arch" "$version" "${CACHE_D}" "${DOWNLOAD_URL}" || return tarball="$_RET" fi extract_rootfs "${tarball}" "${rootfs_d}" || return 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' \ "$rootfs_d/etc/inittab" || { error "failed to fix console entry for $version"; return 1; } fi if [ "$dsource" != "none" ]; then insert_ds "$dsource" "$path/rootfs" "$authkeys" "$userdata_f" || { error "failed to insert userdata to $path/rootfs" return 1 } fi copy_configuration "$path" "$path/rootfs" "$name" "$arch" "$release" return } create_main "$@" # vi: ts=4 expandtab lxc-2.0.0/templates/Makefile.in0000644061062106075000000004674612701247223013314 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = templates ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ $(top_srcdir)/config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = lxc-alpine lxc-altlinux lxc-archlinux lxc-busybox \ lxc-centos lxc-cirros lxc-debian lxc-download lxc-fedora \ lxc-gentoo lxc-openmandriva lxc-opensuse lxc-oracle lxc-plamo \ lxc-slackware lxc-sshd lxc-ubuntu lxc-ubuntu-cloud \ lxc-sparclinux CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(templatesdir)" SCRIPTS = $(templates_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/lxc-alpine.in \ $(srcdir)/lxc-altlinux.in $(srcdir)/lxc-archlinux.in \ $(srcdir)/lxc-busybox.in $(srcdir)/lxc-centos.in \ $(srcdir)/lxc-cirros.in $(srcdir)/lxc-debian.in \ $(srcdir)/lxc-download.in $(srcdir)/lxc-fedora.in \ $(srcdir)/lxc-gentoo.in $(srcdir)/lxc-openmandriva.in \ $(srcdir)/lxc-opensuse.in $(srcdir)/lxc-oracle.in \ $(srcdir)/lxc-plamo.in $(srcdir)/lxc-slackware.in \ $(srcdir)/lxc-sparclinux.in $(srcdir)/lxc-sshd.in \ $(srcdir)/lxc-ubuntu-cloud.in $(srcdir)/lxc-ubuntu.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDIR = @BINDIR@ CAP_LIBS = @CAP_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CGMANAGER_CFLAGS = @CGMANAGER_CFLAGS@ CGMANAGER_LIBS = @CGMANAGER_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_CGROUP_PATTERN = @DEFAULT_CGROUP_PATTERN@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCDIR = @DOCDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ HAVE_DOXYGEN = @HAVE_DOXYGEN@ INCLUDEDIR = @INCLUDEDIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCALSTATEDIR = @LOCALSTATEDIR@ LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBDIR = @LUA_LIBDIR@ LUA_LIBS = @LUA_LIBS@ LUA_SHAREDIR = @LUA_SHAREDIR@ LUA_VERSION = @LUA_VERSION@ LXCBINHOOKDIR = @LXCBINHOOKDIR@ LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATECONFIG = @LXCTEMPLATECONFIG@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ LXC_DISTRO_SYSCONF = @LXC_DISTRO_SYSCONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ LXC_USERNIC_DB = @LXC_USERNIC_DB@ LXC_VERSION = @LXC_VERSION@ LXC_VERSION_ABI = @LXC_VERSION_ABI@ LXC_VERSION_BASE = @LXC_VERSION_BASE@ LXC_VERSION_BETA = @LXC_VERSION_BETA@ LXC_VERSION_MAJOR = @LXC_VERSION_MAJOR@ LXC_VERSION_MICRO = @LXC_VERSION_MICRO@ LXC_VERSION_MINOR = @LXC_VERSION_MINOR@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NIH_CFLAGS = @NIH_CFLAGS@ NIH_DBUS_CFLAGS = @NIH_DBUS_CFLAGS@ NIH_DBUS_LIBS = @NIH_DBUS_LIBS@ NIH_LIBS = @NIH_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ PYTHON = @PYTHON@ PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RUNTIME_PATH = @RUNTIME_PATH@ SBINDIR = @SBINDIR@ SECCOMP_CFLAGS = @SECCOMP_CFLAGS@ SECCOMP_LIBS = @SECCOMP_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ db2xman = @db2xman@ docdir = @docdir@ docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ templatesdir = @LXCTEMPLATEDIR@ templates_SCRIPTS = \ lxc-alpine \ lxc-altlinux \ lxc-archlinux \ lxc-busybox \ lxc-centos \ lxc-cirros \ lxc-debian \ lxc-download \ lxc-fedora \ lxc-gentoo \ lxc-openmandriva \ lxc-opensuse \ lxc-oracle \ lxc-plamo \ lxc-slackware \ lxc-sshd \ lxc-ubuntu \ lxc-ubuntu-cloud \ lxc-sparclinux all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu templates/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu templates/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): lxc-alpine: $(top_builddir)/config.status $(srcdir)/lxc-alpine.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-altlinux: $(top_builddir)/config.status $(srcdir)/lxc-altlinux.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-archlinux: $(top_builddir)/config.status $(srcdir)/lxc-archlinux.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-busybox: $(top_builddir)/config.status $(srcdir)/lxc-busybox.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-centos: $(top_builddir)/config.status $(srcdir)/lxc-centos.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-cirros: $(top_builddir)/config.status $(srcdir)/lxc-cirros.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-debian: $(top_builddir)/config.status $(srcdir)/lxc-debian.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-download: $(top_builddir)/config.status $(srcdir)/lxc-download.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-fedora: $(top_builddir)/config.status $(srcdir)/lxc-fedora.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-gentoo: $(top_builddir)/config.status $(srcdir)/lxc-gentoo.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-openmandriva: $(top_builddir)/config.status $(srcdir)/lxc-openmandriva.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-opensuse: $(top_builddir)/config.status $(srcdir)/lxc-opensuse.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-oracle: $(top_builddir)/config.status $(srcdir)/lxc-oracle.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-plamo: $(top_builddir)/config.status $(srcdir)/lxc-plamo.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-slackware: $(top_builddir)/config.status $(srcdir)/lxc-slackware.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-sshd: $(top_builddir)/config.status $(srcdir)/lxc-sshd.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-ubuntu: $(top_builddir)/config.status $(srcdir)/lxc-ubuntu.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-ubuntu-cloud: $(top_builddir)/config.status $(srcdir)/lxc-ubuntu-cloud.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-sparclinux: $(top_builddir)/config.status $(srcdir)/lxc-sparclinux.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-templatesSCRIPTS: $(templates_SCRIPTS) @$(NORMAL_INSTALL) @list='$(templates_SCRIPTS)'; test -n "$(templatesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(templatesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(templatesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(templatesdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(templatesdir)$$dir" || exit $$?; \ } \ ; done uninstall-templatesSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(templates_SCRIPTS)'; test -n "$(templatesdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(templatesdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(templatesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-templatesSCRIPTS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-templatesSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip \ install-templatesSCRIPTS installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \ uninstall uninstall-am uninstall-templatesSCRIPTS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lxc-2.0.0/templates/lxc-slackware.in0000644061062106075000000004546012701247216014331 00000000000000#!/bin/bash # # lxc: linux Container library # Authors: # Daniel Lezcano # Template for slackware by Matteo Bernardini # some parts are taken from the debian one (used as model) # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 # Add some directories to PATH in case we create containers with sudo export PATH=/sbin:/usr/sbin:$PATH cache=${cache:-/var/cache/lxc/slackware} # Use the primary Slackware site by default, but please consider changing # this to a closer mirror site. MIRROR=${MIRROR:-http://ftp.slackware.com/pub/slackware} if [ -z "$arch" ]; then case "$( uname -m )" in i?86) arch=i486 ;; arm*) arch=arm ;; *) arch=$( uname -m ) ;; esac fi LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" 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 < $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" cat >$rootfs/etc/fstab <$rootfs/tmp/rcs.patch <<'EOF' --- ./etc/rc.orig/rc.6 2012-08-15 01:03:12.000000000 +0200 +++ ./etc/rc.d/rc.6 2013-02-17 10:26:30.888839354 +0100 @@ -9,6 +9,12 @@ # Author: Miquel van Smoorenburg # Modified by: Patrick J. Volkerding, # +# minor tweaks for an lxc container +# by Matteo Bernardini , +# based also on Chris Willing's modifications +# http://www.vislab.uq.edu.au/howto/lxc/rc.6 +# a check for a container variable is made to jump sections +container="lxc" # Set the path. PATH=/sbin:/etc:/bin:/usr/bin @@ -37,6 +43,9 @@ ;; esac +# lxc container check +if [ ! $container = "lxc" ]; then + # Save the system time to the hardware clock using hwclock --systohc. if [ -x /sbin/hwclock ]; then # Check for a broken motherboard RTC clock (where ioports for rtc are @@ -53,6 +62,8 @@ fi fi +fi # end container check + # Run any local shutdown scripts: if [ -x /etc/rc.d/rc.local_shutdown ]; then /etc/rc.d/rc.local_shutdown stop @@ -148,6 +159,9 @@ sleep 2 fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Shut down PCMCIA devices: if [ -x /etc/rc.d/rc.pcmcia ]; then . /etc/rc.d/rc.pcmcia stop @@ -155,11 +169,16 @@ /bin/sleep 5 fi +fi # end container check + # Turn off process accounting: if [ -x /sbin/accton -a -r /var/log/pacct ]; then /sbin/accton off fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Terminate acpid before syslog: if [ -x /etc/rc.d/rc.acpid -a -r /var/run/acpid.pid ]; then # quit . /etc/rc.d/rc.acpid stop @@ -170,6 +189,8 @@ sh /etc/rc.d/rc.udev force-stop fi +fi # end container check + # Kill all remaining processes. if [ ! "$1" = "fast" ]; then echo "Sending all processes the SIGTERM signal." @@ -179,6 +200,9 @@ /sbin/killall5 -9 fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Try to turn off quota. if /bin/grep -q quota /etc/fstab ; then if [ -x /sbin/quotaoff ]; then @@ -187,6 +211,8 @@ fi fi +fi # end container check + # Carry a random seed between reboots. echo "Saving random seed from /dev/urandom in /etc/random-seed." # Use the pool size from /proc, or 512 bytes: @@ -205,6 +231,9 @@ rm -f /var/lock/subsys/* fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Turn off swap: echo "Turning off swap." /sbin/swapoff -a @@ -216,6 +245,8 @@ echo "Remounting root filesystem read-only." /bin/mount -v -n -o remount,ro / +fi # end container check + # This never hurts: /bin/sync @@ -240,12 +271,17 @@ done fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Deactivate LVM volume groups: if [ -r /etc/lvmtab -o -d /etc/lvm/backup ]; then echo "Deactivating LVM volume groups:" /sbin/vgchange -an --ignorelockingfailure fi +fi # end container check + # This never hurts again (especially since root-on-LVM always fails # to deactivate the / logical volume... but at least it was # remounted as read-only first) @@ -258,6 +294,9 @@ # This is to ensure all processes have completed on SMP machines: wait +# lxc container check +if [ ! $container = "lxc" ]; then + if [ -x /sbin/genpowerd ]; then # See if this is a powerfail situation: if /bin/egrep -q "FAIL|SCRAM" /etc/upsstatus 2> /dev/null ; then @@ -274,6 +313,13 @@ fi fi +else + +# confirm successful shutdown of the container +echo ; echo "* container stopped. *" ; echo + +fi # end container check + # Now halt (poweroff with APM or ACPI enabled kernels) or reboot. if [ "$command" = "reboot" ]; then echo "Rebooting." --- ./etc/rc.orig/rc.S 2012-09-13 21:38:34.000000000 +0200 +++ ./etc/rc.d/rc.S 2013-02-17 09:39:41.579799641 +0100 @@ -4,9 +4,18 @@ # # Mostly written by: Patrick J. Volkerding, # +# minor tweaks for an lxc container +# by Matteo Bernardini , +# based also on Chris Willing's modifications +# http://www.vislab.uq.edu.au/howto/lxc/rc.S +# a check for a container variable is made to jump sections +container="lxc" PATH=/sbin:/usr/sbin:/bin:/usr/bin +# lxc container check +if [ ! $container = "lxc" ]; then + # Try to mount /proc: /sbin/mount -v proc /proc -n -t proc 2> /dev/null @@ -254,10 +263,27 @@ read junk; fi # Done checking root filesystem +else + # We really don't want to start udev in the container + if [ -f /etc/rc.d/rc.udev ]; then + chmod -x /etc/rc.d/rc.udev + fi + # Alsa won't work + if [ -f /etc/rc.d/rc.alsa ]; then + chmod -x /etc/rc.d/rc.alsa + fi + # This too + if [ -f /etc/rc.d/rc.loop ]; then + chmod -x /etc/rc.d/rc.loop + fi +fi # end container check # Any /etc/mtab that exists here is old, so we start with a new one: /bin/rm -f /etc/mtab{,~,.tmp} && /bin/touch /etc/mtab +# lxc container check +if [ ! $container = "lxc" ]; then + # Add entry for / to /etc/mtab: /sbin/mount -f -w / @@ -337,6 +363,8 @@ # mounted read-write. /sbin/swapon -a 2> /dev/null +fi # end container check + # Clean up some temporary files: rm -f /var/run/* /var/run/*/* /var/run/*/*/* /etc/nologin \ /etc/dhcpc/*.pid /etc/forcefsck /etc/fastboot \ @@ -364,7 +392,7 @@ # if the first line of that file begins with the word 'Linux'. # You are free to modify the rest of the file as you see fit. if [ -x /bin/sed ]; then - /bin/sed -i "{1s/^Linux.*/$(/bin/uname -sr)\./}" /etc/motd + /bin/sed -i "{1s/^Linux.*/$(/bin/uname -sr) lxc container\./}" /etc/motd fi # If there are SystemV init scripts for this runlevel, run them. @@ -372,6 +400,9 @@ . /etc/rc.d/rc.sysvinit fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Run serial port setup script: # CAREFUL! This can make some systems hang if the rc.serial script isn't # set up correctly. If this happens, you may have to edit the file from a @@ -380,6 +411,8 @@ sh /etc/rc.d/rc.serial start fi +fi # end container check + # Carry an entropy pool between reboots to improve randomness. if [ -f /etc/random-seed ]; then echo "Using /etc/random-seed to initialize /dev/urandom." --- ./etc/rc.orig/rc.M 2012-09-25 19:47:07.000000000 +0200 +++ ./etc/rc.d/rc.M 2013-02-17 09:39:41.579799641 +0100 @@ -10,6 +10,10 @@ # Author: Fred N. van Kempen, # Heavily modified by Patrick Volkerding # +# minor tweaks for an lxc container +# by Matteo Bernardini : +# a check for a container variable is made to jump sections +container="lxc" # Tell the viewers what's going to happen. echo "Going multiuser..." @@ -20,6 +24,9 @@ /sbin/ldconfig & fi +# lxc container check +if [ ! $container = "lxc" ]; then + # Screen blanks after 15 minutes idle time, and powers down in one hour # if the kernel supports APM or ACPI power management: /bin/setterm -blank 15 -powersave powerdown -powerdown 60 @@ -33,6 +40,8 @@ /bin/hostname darkstar fi +fi # end container check + # Set the permissions on /var/log/dmesg according to whether the kernel # permits non-root users to access kernel dmesg information: if [ -r /proc/sys/kernel/dmesg_restrict ]; then @@ -135,6 +144,9 @@ chmod 755 / 2> /dev/null chmod 1777 /tmp /var/tmp +# lxc container check +if [ ! $container = "lxc" ]; then + # Start APM or ACPI daemon. # If APM is enabled in the kernel, start apmd: if [ -e /proc/apm ]; then @@ -146,6 +158,8 @@ . /etc/rc.d/rc.acpid start fi +fi # end container check + # Update any existing icon cache files: if find /usr/share/icons 2> /dev/null | grep -q icon-theme.cache ; then for theme_dir in /usr/share/icons/* ; do --- ./etc/rc.orig/rc.inet1 2012-08-05 19:13:27.000000000 +0200 +++ ./etc/rc.d/rc.inet1 2013-02-17 09:39:41.579799641 +0100 @@ -3,6 +3,11 @@ # This script is used to bring up the various network interfaces. # # @(#)/etc/rc.d/rc.inet1 10.2 Sun Jul 24 12:45:56 PDT 2005 (pjv) +# +# minor tweaks for an lxc container +# by Matteo Bernardini : +# a check for a container variable is made to jump sections +container="lxc" ############################ # READ NETWORK CONFIG FILE # @@ -105,6 +110,10 @@ [ "${IFNAME[$i]}" = "${1}" ] && break i=$(($i+1)) done + + # lxc container check + if [ ! $container = "lxc" ]; then + # If the interface is a bridge, then create it first: [ -n "${BRNICS[$i]}" ] && br_open $i # If the interface isn't in the kernel yet (but there's an alias for it in @@ -115,6 +124,9 @@ /sbin/modprobe ${1} fi fi + + fi # end container check + if grep `echo ${1}: | cut -f 1 -d :`: /proc/net/dev 1> /dev/null ; then # interface exists if ! /sbin/ifconfig | grep -w "${1}" 1>/dev/null || \ ! /sbin/ifconfig ${1} | grep -w inet 1> /dev/null ; then # interface not up or not configured EOF ( cd $rootfs ; patch -p1 < tmp/rcs.patch ; rm tmp/rcs.patch ) # 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 # better not use this in a container sed -i 's/.*genpowerfail.*//' $rootfs/etc/inittab # add a message to rc.local that confirms successful container startup echo "echo ; echo \"* container $name started. *\" ; echo" >> $rootfs/etc/rc.d/rc.local # 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 } 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 < $CONF/slackpkg.conf # v2.8 ARCH=$arch TEMP=$cache/cache-$release-$arch WORKDIR=$cache/slackpkg-$release-$arch DELALL=off CHECKMD5=on CHECKGPG=on CHECKSIZE=off PRIORITY=( patches %PKGMAIN extra pasture testing ) POSTINST=on ONLY_NEW_DOTNEW=off ONOFF=on DOWNLOAD_ALL=on DIALOG=off BATCH=on DEFAULT_ANSWER=y 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 < $CONF/templates/minimal-lxc.template aaa_base aaa_elflibs aaa_terminfo bash bin bzip2 coreutils dhcpcd dialog diffutils e2fsprogs elvis etc findutils gawk glibc-solibs gnupg grep gzip iputils logrotate mpfr net-tools network-scripts ncurses openssh openssl-solibs pkgtools procps-ng sed shadow sharutils slackpkg sysklogd sysvinit sysvinit-functions sysvinit-scripts tar udev util-linux wget which 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 # force klog to use the system call interface to the kernel message # buffers - needed for unprivileged containers sed -i 's|3\ \-x|3 -x -s|' $ROOT/etc/rc.d/rc.syslog || true return 0 ) 200>/var/lock/subsys/lxc return $? } copy_configuration() { path=$1 rootfs=$2 name=$3 cat <> $path/config lxc.utsname = $name lxc.arch = $arch lxc.mount = $rootfs/etc/fstab lxc.include = ${LXC_TEMPLATE_CONFIG}/slackware.common.conf EOF if [ $? -ne 0 ]; then echo "Failed to add configuration." return 1 fi return 0 } clean() { if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -n -x 200 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 200>/var/lock/subsys/lxc } usage() { cat < --clean EOF return 0 } options=$(getopt -o hp:n:a:r:c -l help,rootfs:,path:,name:,arch:,release:,clean -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do 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;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi type installpkg if [ $? -ne 0 ]; then echo "'installpkg' command is missing." exit 1 fi type slackpkg if [ $? -ne 0 ]; then echo "'slackpkg' command is missing." exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required." exit 1 fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'." exit 1 fi # 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 if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi echo set -e install_slackware $rootfs if [ $? -ne 0 ]; then echo "Failed to install slackware." exit 1 fi echo configure_slackware $cache/rootfs-$release-$arch $name if [ $? -ne 0 ]; then echo "Failed to configure slackware for a container." exit 1 fi echo rootfs=$path/rootfs copy_slackware $rootfs if [ $? -ne 0 ]; then echo "Failed to copy rootfs." exit 1 fi echo copy_configuration $path $rootfs $name if [ $? -ne 0 ]; then echo "Failed to write configuration file." exit 1 fi if [ ! -z $clean ]; then clean || exit 1 exit 0 fi lxc-2.0.0/templates/lxc-oracle.in0000644061062106075000000012070212701247216013613 00000000000000#!/bin/sh # # Template script for generating Oracle Enterprise Linux container for LXC # based on lxc-fedora, lxc-ubuntu # # Copyright © 2011 Wim Coekaerts # Copyright © 2012 Dwight Engen # # Modified for Oracle Linux 5 # Wim Coekaerts # # Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script # Dwight Engen # # 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 # version 2.1 of the License, or (at your option) any later version. # # This library 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 # use virbr0 that is setup by default by libvirtd lxc_network_type=veth lxc_network_link=virbr0 die() { echo "failed: $1" exit 1 } is_btrfs_subvolume() { if which btrfs >/dev/null 2>&1 && \ btrfs subvolume list "$1" >/dev/null 2>&1; then return 0 fi return 1 } can_chcon() { if which chcon >/dev/null 2>&1; then selinuxenabled >/dev/null 2>&1 return $? fi return 1 } # fix up the container_rootfs container_rootfs_patch() { echo "Patching container rootfs $container_rootfs for Oracle Linux $container_release_major.$container_release_minor" # copy ourself into the container to be used to --patch the rootfs when # yum update on certain packages is done. we do this here instead of in # container_rootfs_configure() in case the patching done in this function # is updated in the future, we can inject the updated version of ourself # into older containers. if [ $container_rootfs != "/" ]; then cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch if [ $container_release_major -lt "6" ]; then mkdir -p $container_rootfs/usr/lib/yum-plugins cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/lib/yum-plugins fi if [ $container_release_major -ge "6" ]; then mkdir -p $container_rootfs/usr/share/yum-plugins cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins fi mkdir -p $container_rootfs/etc/yum/pluginconf.d cat < $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf [main] enabled=1 packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng EOF fi if [ $container_release_major = "4" ]; then # yum plugin type of TYPE_INTERFACE works in all releases but gives a # deprecation warning on major > 4, so we default to TYPE_INTERACTIVE # and fix it up here sed -i 's|TYPE_INTERACTIVE|TYPE_INTERFACE|' $container_rootfs/usr/lib/yum-plugins/lxc-patch.py if [ -f $container_rootfs/etc/yum.repos.d/ULN-Base.repo ]; then mv $container_rootfs/etc/yum.repos.d/ULN-Base.repo \ $container_rootfs/etc/yum.repos.d/ULN-Base.repo.lxc-disabled fi echo "plugins = 1" >>$container_rootfs/etc/yum.conf fi # "disable" selinux in the guest. The policy in the container isn't # likely to match the hosts (unless host == guest exactly) and the # kernel can only be enforcing one policy. # # The OL 5 init honors /etc/selinux/config, but note that # this doesnt actually disable it if it's enabled in the host, since # libselinux::is_selinux_enabled() in the guest will check # /proc/filesystems and see selinuxfs, thus reporting that it is on # (ie. check the output of sestatus in the guest). We also replace # /usr/sbin/selinuxenabled with a symlink to /bin/false so that init # scripts (ie. mcstransd) that call that think selinux is disabled. mkdir -p $container_rootfs/selinux echo 0 > $container_rootfs/selinux/enforce if [ -e $container_rootfs/etc/selinux/config ]; then sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config else mkdir -p $container_rootfs/etc/selinux echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config fi sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd # setting /proc/$$/loginuid doesn't work under user namespace, which # prevents logins from working sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/sshd sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login if [ -f $container_rootfs/usr/sbin/selinuxenabled ]; then mv $container_rootfs/usr/sbin/selinuxenabled $container_rootfs/usr/sbin/selinuxenabled.lxcorig ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled fi # ensure /dev/ptmx refers to the newinstance devpts of the container, or # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512) rm -f $container_rootfs/dev/ptmx ln -s pts/ptmx $container_rootfs/dev/ptmx # OL7 has systemd, no rc.sysinit if [ $container_release_major = "7" ]; then # from mhw in the fedora template: We do need to disable the # "ConditionalPathExists=/dev/tty0" line or no gettys are started on # the ttys in the container. Lets do it in an override copy of the # service so it can still pass rpm verifies and not be automatically # updated by a new systemd version. sed -e 's/^ConditionPathExists=/#LXC ConditionPathExists=/' \ < $container_rootfs/usr/lib/systemd/system/getty\@.service \ > $container_rootfs/etc/systemd/system/getty\@.service # Setup getty service on the 4 ttys we are going to allow in the # default config. Number should match lxc.tty ( cd $container_rootfs/etc/systemd/system/getty.target.wants for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done ) # We only want to spawn a getty on /dev/console in lxc, libvirt-lxc # symlinks /dev/console to /dev/tty1 sed -i '/Before=getty.target/a ConditionVirtualization=lxc' $container_rootfs/usr/lib/systemd/system/console-getty.service # disable some systemd services, set default boot, sigpwr target rm -f $container_rootfs/usr/lib/systemd/system/sysinit.target.wants/kmod-static-nodes.service chroot $container_rootfs systemctl -q disable graphical.target chroot $container_rootfs systemctl -q enable multi-user.target if [ ! -e $container_rootfs/etc/systemd/system/sigpwr.target ]; then chroot $container_rootfs ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target fi # systemd in userns won't be able to set /proc/self/oom_score_adj which # prevents the dbus service from starting sed -i 's|^OOMScoreAdjust|#LXC OOMScoreAdjust|' $container_rootfs/usr/lib/systemd/system/dbus.service return fi # silence error in checking for selinux sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit # on ol4 pam_limits prevents logins when using user namespaces if [ $container_release_major = "4" ]; then sed -i 's|session[ \t]*required[ \t]*/lib/security/\$ISA/pam_limits.so|#session required /lib/security/$ISA/pam_limits.so|' $container_rootfs/etc/pam.d/system-auth fi # avoid error in ol5 attempting to copy non-existent resolv.conf if [ $container_release_major = "5" ]; then sed -i 's|resolv.conf.predhclient|resolv.conf.predhclient 2>/dev/null|' $container_rootfs/sbin/dhclient-script fi # disable interactive ovmd asking questions if [ -f $container_rootfs/etc/sysconfig/ovmd ]; then sed -i 's|INITIAL_CONFIG=yes|INITIAL_CONFIG=no|' $container_rootfs/etc/sysconfig/ovmd fi # disable disabling of ipv4 forwarding and defrag on shutdown since # we mount /proc/sys ro if [ $container_release_major = "5" ]; then sed -i 's|-f /proc/sys/net/ipv4/ip_forward|-w /proc/sys/net/ipv4/ip_forward|' $container_rootfs/etc/rc.d/init.d/network sed -i 's|-f /proc/sys/net/ipv4/ip_always_defrag|-w /proc/sys/net/ipv4/ip_always_defrag|' $container_rootfs/etc/rc.d/init.d/network fi # disable ipv6 on ol6 rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global # remove module stuff for iptables it just shows errors that are not # relevant in a container if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config fi # disable readahead in the container if [ $container_release_major = "6" -a -e $container_rootfs/etc/sysconfig/readahead ]; then rm -f $container_rootfs/etc/init/readahead-collector.conf rm -f $container_rootfs/etc/init/readahead-disable-services.conf sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead fi if [ $container_release_major = "4" ]; then # enable fastboot always sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.sysinit sed -i 's|\[ -f /fastboot \]|/bin/true|' $container_rootfs/etc/rc.d/rc.sysinit # dont attempt to set kernel parameters sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.sysinit sed -i 's|action $"Configuring kernel parameters|# LXC action $"Configuring kernel parameters|' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/network 2>/dev/null sed -i 's|action $"Setting network parameters|# LXC action $"Setting network parameters|' $container_rootfs/etc/init.d/NetworkManager 2>/dev/null fi # no need to attempt to mount / sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit # disable udev in the container if [ $container_release_major = "4" ]; then sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.sysinit sed -i 's|\[ -x /sbin/start_udev \]|# LXC no udev|' $container_rootfs/etc/rc.d/rc.sysinit else sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit fi # disable nash raidautorun in the container since no /dev/md* if [ $container_release_major = "4" -o $container_release_major = "5" ]; then sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.sysinit sed -i 's|echo "raidautorun /dev/md0"|echo ""|' $container_rootfs/etc/rc.d/rc.sysinit fi # prevent rc.sysinit from attempting to loadkeys if [ \( $container_release_major = "4" -o $container_release_major = "5" \) -a -e $container_rootfs/etc/sysconfig/keyboard ]; then rm $container_rootfs/etc/sysconfig/keyboard fi # dont use the hwclock, it messes up the host's time if [ $container_release_major = "4" ]; then sed -i 's|runcmd $"Syncing hardware clock|# LXC no hwclock runcmd $"Syncing hardware clock|' $container_rootfs/etc/rc.d/init.d/halt else sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt fi sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit # dont start lvm if [ $container_release_major -lt "6" -a -f $container_rootfs/sbin/lvm.static ]; then mv $container_rootfs/sbin/lvm.static $container_rootfs/sbin/lvm.static.lxc-disabled fi if [ $container_release_major = "6" ]; then touch $container_rootfs/.nolvm fi # fix assumptions that plymouth is available sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit rm -f $container_rootfs/etc/init/plymouth-shutdown.conf rm -f $container_rootfs/etc/init/quit-plymouth.conf rm -f $container_rootfs/etc/init/splash-manager.conf # dont try to unmount /dev/lxc devices sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt # don't try to unmount swap sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt # sem_open(3) checks that /dev/shm is SHMFS_SUPER_MAGIC, so make sure to # mount /dev/shm (normally done by dracut initrd) as tmpfs if [ $container_release_major = "4" -o $container_release_major = "5" ]; then grep -q "mount -t tmpfs tmpfs /dev/shm" $container_rootfs/etc/rc.sysinit if [ $? -eq 1 ]; then echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.sysinit echo "mkdir -p /dev/shm && mount -t tmpfs tmpfs /dev/shm" >>$container_rootfs/etc/rc.d/rc.sysinit fi fi if [ $container_release_major = "6" ]; then sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit fi # there might be other services that are useless but the below set is a good start # some of these might not exist in the image, so we silence chkconfig complaining # about the service file not being found for service in \ acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \ ip6tables irqbalance iscsi iscsid isdn kdump kudzu \ lm_sensors lvm2-monitor mdmonitor microcode_ctl \ ntpd pcmcia postfix sendmail udev-post xfs ; do chroot $container_rootfs chkconfig 2>/dev/null $service off done for service in rsyslog ; do chroot $container_rootfs chkconfig 2>/dev/null $service on done } container_rootfs_configure() { container_rootfs_patch echo "Configuring container for Oracle Linux $container_release_major.$container_release_minor" # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest # will report its name and be resolv'able by the hosts dnsmasq cat < $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes HOSTNAME=$name DHCP_HOSTNAME=\`hostname\` NM_CONTROLLED=no TYPE=Ethernet EOF # set the hostname if [ $container_release_major -ge "7" ]; then # systemd honors /etc/hostname echo "$name" >$container_rootfs/etc/hostname fi cat < $container_rootfs/etc/sysconfig/network NETWORKING=yes NETWORKING_IPV6=no HOSTNAME=$name EOF # set minimal hosts echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts # this file has to exist for libvirt/Virtual machine monitor to boot the container touch $container_rootfs/etc/mtab # setup console and tty[1-4] for login. note that /dev/console and # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. # lxc will maintain these links and bind mount ptys over /dev/lxc/* # since lxc.devttydir is specified in the config. # allow root login on console, tty[1-4], and pts/0 for libvirt echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty echo "lxc/console" >>$container_rootfs/etc/securetty for i in 1 2 3 4; do echo "lxc/tty$i" >>$container_rootfs/etc/securetty done echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty for i in 0 1 2 3 4; do echo "pts/$i" >>$container_rootfs/etc/securetty done # prevent mingetty from calling vhangup(2) since it fails with userns if [ -f $container_rootfs/etc/init/tty.conf ]; then sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf fi # create maygetty which only spawns a getty on the console when running # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty # as /dev/tty1 cat <$container_rootfs/sbin/maygetty #!/bin/sh if [ "\$container" = "lxc" ]; then exec /sbin/mingetty \$@ fi exec sleep infinity EOF chmod 755 $container_rootfs/sbin/maygetty # start a getty on /dev/console, /dev/tty[1-4] if [ $container_release_major = "4" -o $container_release_major = "5" ]; then sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/inittab sed -i '/1:2345:respawn/i cns:2345:respawn:/sbin/maygetty --nohangup --noclear console' $container_rootfs/etc/inittab sed -i '/5:2345:respawn/d' $container_rootfs/etc/inittab sed -i '/6:2345:respawn/d' $container_rootfs/etc/inittab fi if [ $container_release_major = "6" ]; then cat < $container_rootfs/etc/init/console.conf # console - getty # # This service maintains a getty on the console from the point the system is # started until it is shut down again. start on stopped rc RUNLEVEL=[2345] stop on runlevel [!2345] env container respawn exec /sbin/maygetty --nohangup --noclear /dev/console EOF fi # lxc-shutdown sends SIGPWR to init, OL4 and OL5 have SysVInit, just # make it do shutdown now instead of delaying 2 minutes. OL6 uses # upstart, so we create an upstart job to handle SIGPWR to shut down # cleanly. We use "init 0" instead of shutdown -h now to avoid SELinux # permission denied when upstart's shutdown tries to connect to the # /com/ubuntu/upstart socket. if [ $container_release_major = "4" -o $container_release_major = "5" ]; then sed -i 's|pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; |pf::powerfail:/sbin/shutdown -f -h now "|' $container_rootfs/etc/inittab elif [ $container_release_major = "6" ]; then cat < $container_rootfs/etc/init/power-status-changed.conf # power-status-changed - used to cleanly shut down the container # # This task is run whenever init receives SIGPWR # Used to shut down the machine. start on power-status-changed exec init 0 EOF fi # start with a clean /var/log/messages rm -f $container_rootfs/var/log/messages # set initial timezone as on host if [ -f /etc/sysconfig/clock ]; then . /etc/sysconfig/clock if [ $container_release_major = "5" -o $container_release_major = "6" ]; then echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock chroot $container_rootfs tzdata-update else ZONE="${ZONE// /_}" chroot $container_rootfs ln -sf ../usr/share/zoneinfo/$ZONE /etc/localtime fi else ZONE=`readlink /etc/localtime | sed -s "s/\.\.\/usr\/share\/zoneinfo\///g"` if [ "$ZONE" ]; then if [ $container_release_major = "5" -o $container_release_major = "6" ]; then echo ZONE=$ZONE > $container_rootfs/etc/sysconfig/clock chroot $container_rootfs tzdata-update else # if /etc/localtime is a symlink, this should preserve it. cp -a /etc/localtime $container_rootfs/etc/localtime fi else echo "Timezone in container is not configured. Adjust it manually." fi fi # add oracle user, set root password chroot $container_rootfs useradd -m -s /bin/bash oracle echo "oracle:oracle" | chroot $container_rootfs chpasswd echo "root:root" | chroot $container_rootfs chpasswd printf "Added container user:\033[1moracle\033[0m password:\033[1moracle\033[0m\n" printf "Added container user:\033[1mroot\033[0m password:\033[1mroot\033[0m\n" } # create the container's lxc config file container_config_create() { echo "Create configuration file $cfg_dir/config" mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir" echo "# Common configuration" >> $cfg_dir/config if [ -e "@LXCTEMPLATECONFIG@/oracle.common.conf" ]; then echo "lxc.include = @LXCTEMPLATECONFIG@/oracle.common.conf" >> $cfg_dir/config fi # generate a hwaddr for the container with a high mac address # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303 local hwaddr="fe:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \ head -n 1 |awk '{print $2}' | cut -c1-10 |\ sed 's/\(..\)/\1:/g; s/.$//'`" cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" # Container configuration for Oracle Linux $container_release_major.$container_release_minor lxc.arch = $arch lxc.utsname = $name EOF grep -q "^lxc.rootfs" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs = $container_rootfs" >> $cfg_dir/config if [ $container_release_major != "4" ]; then echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config fi # systemd services like logind and journald need these if [ $container_release_major != "7" ]; then echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config fi echo "# Networking" >>$cfg_dir/config # see if the network settings were already specified lxc_network_type=`grep '^lxc.network.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'` if [ -z "$lxc_network_type" -a \ \( $host_distribution = "OracleServer" -o \ $host_distribution = "Fedora" \) ]; then echo "lxc.network.type = veth" >>$cfg_dir/config echo "lxc.network.flags = up" >>$cfg_dir/config echo "lxc.network.link = virbr0" >>$cfg_dir/config fi cat <> $cfg_dir/config || die "unable to create $cfg_dir/config" lxc.network.name = eth0 lxc.network.mtu = 1500 lxc.network.hwaddr = $hwaddr EOF } container_rootfs_clone() { if is_btrfs_subvolume $template_rootfs; then # lxc-create already made $container_rootfs a btrfs subvolume, but # in this case we want to snapshot the original subvolume so we we # have to delete the one that lxc-create made btrfs subvolume delete $container_rootfs btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template" else echo "Copying rootfs ..." cp -axT $template_rootfs $container_rootfs || die "copy template" fi } container_rootfs_repo_create() { echo "# LXC generated .repo file" >$1 echo "[$2]" >>$1 echo "name=Oracle Linux $container_release_major.$container_release_minor ($basearch)" >>$1 echo "baseurl=$3/" >>$1 echo "enabled=1" >>$1 echo "skip_if_unavailable=1" >>$1 if [ "$4" != "" ]; then echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1 echo "gpgcheck=1" >>$1 else echo "gpgcheck=0" >>$1 fi } container_rootfs_dev_create() { # create required devices. note that /dev/console will be created by lxc # or libvirt itself to be a symlink to the right pty. # take care to not nuke /dev in case $container_rootfs isn't set dev_path="$container_rootfs/dev" if [ $container_rootfs != "/" -a -d $dev_path ]; then rm -rf $dev_path fi mkdir -p $dev_path if can_chcon; then # ensure symlinks created in /dev have the right context chcon -t device_t $dev_path fi mknod -m 666 $dev_path/null c 1 3 mknod -m 666 $dev_path/zero c 1 5 mknod -m 666 $dev_path/random c 1 8 mknod -m 666 $dev_path/urandom c 1 9 mkdir -m 755 $dev_path/pts mkdir -m 1777 $dev_path/shm mknod -m 666 $dev_path/tty c 5 0 mknod -m 666 $dev_path/tty1 c 4 1 mknod -m 666 $dev_path/tty2 c 4 2 mknod -m 666 $dev_path/tty3 c 4 3 mknod -m 666 $dev_path/tty4 c 4 4 mknod -m 666 $dev_path/full c 1 7 mknod -m 600 $dev_path/initctl p # set selinux labels same as host if can_chcon; then for node in null zero random urandom pts shm \ tty tty0 tty1 tty2 tty3 tty4 full ; do chcon --reference /dev/$node $dev_path/$node 2>/dev/null done fi } container_rootfs_create() { if can_chcon; then chcon --reference / $container_rootfs 2>/dev/null fi cmds="rpm wget yum" if [ $container_release_major -lt "6" ]; then if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then db_dump_cmd="db5.1_dump" fi if [ $host_distribution = "OracleServer" -o \ $host_distribution = "Fedora" ]; then db_dump_cmd="db_dump" fi cmds="$cmds $db_dump_cmd file" fi for cmd in $cmds; do which $cmd >/dev/null 2>&1 if [ $? -ne 0 ]; then die "The $cmd command is required, please install it" fi done mkdir -p @LOCALSTATEDIR@/lock/subsys ( flock -x 9 if [ $? -ne 0 ]; then die "The template is busy." fi echo "Yum installing release $container_release_major.$container_release_minor for $basearch" if [ -n "$repourl" ]; then yum_url=$repourl else yum_url=http://public-yum.oracle.com fi if [ $container_release_major = "4" -o $container_release_major = "5" ]; then latest_L="el" latest_U="EL" else latest_L="ol" latest_U="OL" fi if [ -n "$baseurl" ]; then # create .repo pointing at baseurl repo="lxc-install" mkdir -p $container_rootfs/etc/yum.repos.d container_rootfs_repo_create \ $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl else # get public-yum repo file if [ $container_release_major = "4" ]; then repofile=public-yum-el4.repo elif [ $container_release_major = "5" ]; then repofile=public-yum-el5.repo elif [ $container_release_major = "6" ]; then repofile=public-yum-ol6.repo elif [ $container_release_major = "7" ]; then repofile=public-yum-ol7.repo else die "Unsupported release $container_release_major" fi mkdir -p $container_rootfs/etc/yum.repos.d wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile if [ $? -ne 0 ]; then die "Unable to download repo file $yum_url/$repofile, release unavailable" fi # yum will take $basearch from host, so force the arch we want sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile # replace url if they specified one if [ -n "$repourl" ]; then sed -i "s|baseurl=http://public-yum.oracle.com/repo|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile sed -i "s|gpgkey=http://public-yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile fi # disable all repos, then enable the repo for the version we are installing. if [ $container_release_minor = "latest" ]; then repo=$latest_L""$container_release_major"_"$container_release_minor elif [ $container_release_major = "7" ]; then repo="ol"$container_release_major"_u"$container_release_minor"_base" elif [ $container_release_major = "6" ]; then if [ $container_release_minor = "0" ]; then repo="ol"$container_release_major"_ga_base" else repo="ol"$container_release_major"_u"$container_release_minor"_base" fi elif [ $container_release_major = "5" ]; then if [ $container_release_minor = "0" ]; then repo="el"$container_release_major"_ga_base" elif [ $container_release_minor -lt "6" ]; then repo="el"$container_release_major"_u"$container_release_minor"_base" else repo="ol"$container_release_major"_u"$container_release_minor"_base" fi elif [ $container_release_major = "4" -a $container_release_minor -gt "5" ]; then repo="el"$container_release_major"_u"$container_release_minor"_base" else die "Unsupported release $container_release_major.$container_release_minor" fi sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile fi container_rootfs_dev_create # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt echo "" >$container_rootfs/etc/fstab # create rpm db, download and yum install minimal packages mkdir -p $container_rootfs/var/lib/rpm rpm --root $container_rootfs --initdb yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck" min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils oraclelinux-release" if [ $container_release_major -lt "6" ]; then min_pkgs="$min_pkgs db4-utils" fi # we unshare the mount namespace because yum installing the ol4 # packages causes $rootfs/proc to be mounted on lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs if [ $? -ne 0 ]; then die "Failed to download and install the rootfs, aborting." fi # rsyslog and pam depend on coreutils for some common commands in # their POSTIN scriptlets, but coreutils wasn't installed yet. now # that coreutils is installed, reinstall the packages so their POSTIN # runs right. similarly, libutempter depends on libselinux.so.1 when # it runs /usr/sbin/groupadd, so reinstall it too redo_pkgs="" if [ $container_release_major = "5" ]; then if [ $container_release_minor = "latest" ]; then redo_pkgs="pam rsyslog libutempter" elif [ $container_release_minor -lt 2 ]; then redo_pkgs="pam" elif [ $container_release_minor -lt 6 ]; then redo_pkgs="pam rsyslog" elif [ $container_release_minor -gt 5 ]; then redo_pkgs="pam rsyslog libutempter" fi fi # shadow utils fails on ol4 and ol6.1 if [ $container_release_major = "4" -o \ $container_release_major = "6" -a $container_release_minor = "1" ]; then redo_pkgs="shadow-utils" fi if [ x"$redo_pkgs" != x ]; then rpm --root $container_rootfs --nodeps -e $redo_pkgs lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs if [ $? -ne 0 ]; then die "Unable to reinstall packages" fi fi # if installing from a baseurl, create a .repo that the container # can use to update to _latest from http://public-yum.oracle.com if [ -n "$baseurl" ]; then container_rootfs_repo_create \ "$container_rootfs/etc/yum.repos.d/public-yum-"$latestL""$container_release_major".repo" \ $latest_L""$container_release_major"_latest" \ $yum_url"/repo/OracleLinux/"$latest_U""$container_release_major"/latest/$basearch" gpg fi # these distributions put the rpm database in a place the guest is # not expecting it, so move it if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm fi # if the native rpm created the db with Hash version 9, we need to # downgrade it to Hash version 8 for use with OL5.x db_version=`file $container_rootfs/var/lib/rpm/Packages | \ grep -o 'version [0-9]*' |awk '{print $2}'` if [ $container_release_major -lt "6" -a $db_version != "8" ]; then echo "Fixing (downgrading) rpm database from version $db_version" rm -f $container_rootfs/var/lib/rpm/__db* for db in $container_rootfs/var/lib/rpm/* ; do $db_dump_cmd $db |chroot $container_rootfs db_load /var/lib/rpm/`basename $db`.new mv $db.new $db done fi # the host rpm may not be the same as the guest, rebuild the db with # the guest rpm version echo "Rebuilding rpm database" rm -f $container_rootfs/var/lib/rpm/__db* chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-oracle-$name if [ $? -ne 0 ]; then exit 1 fi } container_release_get() { if [ -f $1/etc/oracle-release ]; then container_release_version=`cat $1/etc/oracle-release |awk '/^Oracle/ {print $5}'` container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` elif grep -q "Enterprise Linux AS" $1/etc/redhat-release; then container_release_major=`cat $1/etc/redhat-release |awk '{print $7}'` container_release_minor=`cat $1/etc/redhat-release |awk '{print $10}' |tr -d ")"` container_release_version="$container_release_major.$container_release_minor" elif grep -q "Enterprise Linux Server" $1/etc/redhat-release; then container_release_version=`cat $1/etc/redhat-release |awk '{print $7}'` container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` else echo "Unable to determine container release version" exit 1 fi } usage() { cat < architecture (ie. i386, x86_64) -R|--release= release to download for the new container --rootfs= rootfs path -r|--rpms= additional rpms to install into container -u|--url= replace yum repo url (ie. Oracle public-yum mirror) --baseurl= use package repository (ie. file:///mnt) arch and release must also be specified -t|--templatefs= copy/clone rootfs at path instead of downloading -P|--patch= only patch the rootfs at path for use as a container -h|--help Release is of the format "major.minor", for example "5.8", "6.3", or "6.latest" This template supports Oracle Linux releases 4.6 - 7.0 EOF return 0 } options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) cfg_dir=$2; shift 2;; --rootfs) container_rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; -a|--arch) arch=$2; shift 2;; -R|--release) container_release_version=$2; shift 2;; -r|--rpms) user_pkgs=$2; shift 2;; -u|--url) repourl=$2; shift 2;; -t|--templatefs) template_rootfs=$2; shift 2;; --patch) patch_rootfs=$2; shift 2;; --baseurl) baseurl=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done # make sure mandatory args are given and valid if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -n "$baseurl" ]; then if [ "$arch" = "" -o "$container_release_version" = "" ]; then echo "The --arch and --release must be specified when using --baseurl" usage exit 1 fi fi if [ "$arch" = "" ]; then arch=$(uname -m) fi if [ -n "$patch_rootfs" ]; then container_rootfs="$patch_rootfs" container_release_get $container_rootfs container_rootfs_patch exit 0 fi if [ -z $name ]; then echo "Container name must be given" usage exit 1 fi if [ -z $cfg_dir ]; then echo "Configuration directory must be given, check lxc-create" usage exit 1 fi basearch=$arch if [ "$arch" = "i686" ]; then basearch="i386" fi if [ "$arch" != "i386" -a "$arch" != "x86_64" ]; then echo "Bad architecture given, check lxc-create" usage exit 1 fi if which lsb_release >/dev/null 2>&1; then host_distribution=`lsb_release --id |awk '{print $3}'` host_release_version=`lsb_release --release |awk '{print $2}'` host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` else if [ -f /etc/fedora-release ]; then host_distribution="Fedora" host_release_version=`cat /etc/fedora-release |awk '{print $3}'` host_release_major=$host_release_version host_release_minor=0 elif [ -f /etc/oracle-release ]; then host_distribution="OracleServer" host_release_version=`cat /etc/oracle-release |awk '{print $5}'` host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` else echo "Unable to determine host distribution, ensure lsb_release is installed" exit 1 fi fi echo "Host is $host_distribution $host_release_version" if [ -z "$container_rootfs" ]; then container_rootfs="$cfg_dir/rootfs" fi if [ -n "$template_rootfs" ]; then container_release_get $template_rootfs else if [ -z "$container_release_version" ]; then if [ $host_distribution = "OracleServer" ]; then container_release_version=$host_release_version else echo "No release specified with -R, defaulting to 6.5" container_release_version="6.5" fi fi container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` fi container_config_create if [ -n "$template_rootfs" ]; then container_rootfs_clone else container_rootfs_create fi container_release_get $container_rootfs container_rootfs_configure echo "Container : $container_rootfs" echo "Config : $cfg_dir/config" echo "Network : eth0 ($lxc_network_type) on $lxc_network_link" lxc-2.0.0/templates/lxc-debian.in0000644061062106075000000004643512701247216013602 00000000000000#!/bin/bash # # lxc: linux Container library # Authors: # Daniel Lezcano # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 export GREP_OPTIONS="" MIRROR=${MIRROR:-http://httpredir.debian.org/debian} SECURITY_MIRROR=${SECURITY_MIRROR:-http://security.debian.org/} LOCALSTATEDIR="@LOCALSTATEDIR@" LXC_TEMPLATE_CONFIG="@LXCTEMPLATECONFIG@" # Allows the lxc-cache directory to be set by environment variable LXC_CACHE_PATH=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc"} configure_debian() { rootfs=$1 hostname=$2 num_tty=$3 # squeeze only has /dev/tty and /dev/tty0 by default, # therefore creating missing device nodes for tty1-4. for tty in $(seq 1 $num_tty); do if [ ! -e $rootfs/dev/tty$tty ]; then mknod $rootfs/dev/tty$tty c 4 $tty fi done # configure the inittab cat < $rootfs/etc/inittab id:3:initdefault: si::sysinit:/etc/init.d/rcS l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin 1:2345:respawn:/sbin/getty 38400 console $(for tty in $(seq 1 $num_tty); do echo "c${tty}:12345:respawn:/sbin/getty 38400 tty${tty} linux" ; done;) p6::ctrlaltdel:/sbin/init 6 p0::powerfail:/sbin/init 0 EOF # symlink mtab [ -e "$rootfs/etc/mtab" ] && rm $rootfs/etc/mtab ln -s /proc/self/mounts $rootfs/etc/mtab # disable selinux in debian mkdir -p $rootfs/selinux echo 0 > $rootfs/selinux/enforce # configure the network using the dhcp cat < $rootfs/etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp EOF # set the hostname cat < $rootfs/etc/hostname $hostname EOF # reconfigure some services # remove pointless services in a container chroot $rootfs /usr/sbin/update-rc.d -f checkroot.sh disable chroot $rootfs /usr/sbin/update-rc.d -f umountfs disable chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh disable chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh disable # generate new SSH keys if [ -x $rootfs/var/lib/dpkg/info/openssh-server.postinst ]; then cat > $rootfs/usr/sbin/policy-rc.d << EOF #!/bin/sh exit 101 EOF chmod +x $rootfs/usr/sbin/policy-rc.d if [ -f $rootfs/etc/init/ssh.conf ]; then mv $rootfs/etc/init/ssh.conf $rootfs/etc/init/ssh.conf.disabled fi rm -f $rootfs/etc/ssh/ssh_host_*key* DPKG_MAINTSCRIPT_PACKAGE=openssh DPKG_MAINTSCRIPT_NAME=postinst chroot $rootfs /var/lib/dpkg/info/openssh-server.postinst configure sed -i "s/root@$(hostname)/root@$hostname/g" $rootfs/etc/ssh/ssh_host_*.pub if [ -f "$rootfs/etc/init/ssh.conf.disabled" ]; then mv $rootfs/etc/init/ssh.conf.disabled $rootfs/etc/init/ssh.conf fi rm -f $rootfs/usr/sbin/policy-rc.d fi # set initial timezone as on host if [ -f /etc/timezone ]; then cat /etc/timezone > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata elif [ -f /etc/sysconfig/clock ]; then . /etc/sysconfig/clock echo $ZONE > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata else echo "Timezone in container is not configured. Adjust it manually." fi echo "root:root" | chroot $rootfs chpasswd echo "Root password is 'root', please change !" return 0 } write_sourceslist() { local rootfs="$1"; shift local release="$1"; shift local arch="$1"; shift local prefix="deb" if [ -n "${arch}" ]; then prefix="deb [arch=${arch}]" fi if [ "$mainonly" = 1 ]; then non_main='' else non_main=' contrib non-free' fi cat >> "${rootfs}/etc/apt/sources.list" << EOF ${prefix} $MIRROR ${release} main${non_main} EOF if [ "$release" != "unstable" -a "$release" != "sid" ]; then cat >> "${rootfs}/etc/apt/sources.list" << EOF ${prefix} $SECURITY_MIRROR ${release}/updates main${non_main} EOF fi } install_packages() { local rootfs="$1"; shift local packages="$*" chroot ${rootfs} apt-get update if [ -n "${packages}" ]; then chroot ${rootfs} apt-get install --force-yes -y --no-install-recommends ${packages} fi } configure_debian_systemd() { path=$1 rootfs=$2 config=$3 num_tty=$4 # this only works if we have getty@.service to manipulate if [ -f ${rootfs}/lib/systemd/system/getty\@.service ]; then sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \ -e 's/After=dev-%i.device/After=/' \ < ${rootfs}/lib/systemd/system/getty\@.service \ > ${rootfs}/etc/systemd/system/getty\@.service fi # just in case systemd is not installed mkdir -p ${rootfs}/{lib,etc}/systemd/system mkdir -p ${rootfs}/etc/systemd/system/getty.target.wants # Fix getty-static-service as debootstrap does not install dbus if [ -e $rootfs//lib/systemd/system/getty-static.service ] ; then local tty_services=$(for i in $(seq 2 $num_tty); do echo -n "getty@tty${i}.service "; done; ) sed 's/ getty@tty.*/'" $tty_services "'/g' \ $rootfs/lib/systemd/system/getty-static.service | \ sed 's/\(tty2-tty\)[5-9]/\1'"${num_tty}"'/g' > $rootfs/etc/systemd/system/getty-static.service fi # This function has been copied and adapted from lxc-fedora rm -f ${rootfs}/etc/systemd/system/default.target chroot ${rootfs} ln -s /dev/null /etc/systemd/system/udev.service chroot ${rootfs} ln -s /dev/null /etc/systemd/system/systemd-udevd.service chroot ${rootfs} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target # Make systemd honor SIGPWR chroot ${rootfs} ln -s /lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target # Setup getty service on the ttys we are going to allow in the # default config. Number should match lxc.tty ( cd ${rootfs}/etc/systemd/system/getty.target.wants for i in $(seq 1 $num_tty) ; do ln -sf ../getty\@.service getty@tty${i}.service; done ) # Since we use static-getty.target; we need to mask container-getty@.service generated by # container-getty-generator, so we don't get multiple instances of agetty running. # See https://github.com/lxc/lxc/issues/520 and https://github.com/lxc/lxc/issues/484 ( cd ${rootfs}/etc/systemd/system/getty.target.wants for i in $(seq 0 $num_tty); do ln -sf /dev/null container-getty\@${i}.service; done ) return 0 } cleanup() { rm -rf $cache/partial-$release-$arch rm -rf $cache/rootfs-$release-$arch } download_debian() { packages=\ ifupdown,\ locales,\ libui-dialog-perl,\ dialog,\ isc-dhcp-client,\ netbase,\ net-tools,\ iproute,\ openssh-server cache=$1 arch=$2 release=$3 trap cleanup EXIT SIGHUP SIGINT SIGTERM # Create the cache mkdir -p "$cache" # If debian-archive-keyring isn't installed, fetch GPG keys directly releasekeyring=/usr/share/keyrings/debian-archive-keyring.gpg if [ ! -f $releasekeyring ]; then releasekeyring="$cache/archive-key.gpg" case $release in "squeeze") gpgkeyname="archive-key-6.0" ;; "wheezy") gpgkeyname="archive-key-7.0" ;; *) gpgkeyname="archive-key-8" ;; esac wget https://ftp-master.debian.org/keys/${gpgkeyname}.asc -O - --quiet \ | gpg --import --no-default-keyring --keyring=${releasekeyring} fi # check the mini debian was not already downloaded mkdir -p "$cache/partial-$release-$arch" if [ $? -ne 0 ]; then echo "Failed to create '$cache/partial-$release-$arch' directory" return 1 fi # download a mini debian into a cache echo "Downloading debian minimal ..." debootstrap --verbose --variant=minbase --arch=$arch \ --include=$packages --keyring=${releasekeyring} \ "$release" "$cache/partial-$release-$arch" $MIRROR if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv "$1/partial-$release-$arch" "$1/rootfs-$release-$arch" echo "Download complete." trap EXIT trap SIGINT trap SIGTERM trap SIGHUP return 0 } copy_debian() { cache=$1 arch=$2 rootfs=$3 release=$4 # make a local copy of the minidebian echo -n "Copying rootfs to $rootfs..." mkdir -p $rootfs rsync -Ha "$cache/rootfs-$release-$arch"/ $rootfs/ || return 1 return 0 } install_debian() { rootfs=$1 release=$2 arch=$3 cache="$4/debian" mkdir -p $LOCALSTATEDIR/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs-$release-$arch ... " if [ ! -e "$cache/rootfs-$release-$arch" ]; then download_debian $cache $arch $release if [ $? -ne 0 ]; then echo "Failed to download 'debian base'" return 1 fi fi copy_debian $cache $arch $rootfs $release if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>$LOCALSTATEDIR/lock/subsys/lxc-debian return $? } copy_configuration() { path=$1 rootfs=$2 hostname=$3 arch=$4 num_tty=$5 # Generate the configuration file # if there is exactly one veth network entry, make sure it has an # associated hwaddr. nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l` if [ $nics -eq 1 ]; then grep -q "^lxc.network.hwaddr" $path/config || sed -i -e "/^lxc\.network\.type[ \t]*=[ \t]*veth/a lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')" $path/config fi ## Add all the includes echo "" >> $path/config echo "# Common configuration" >> $path/config if [ -e "${LXC_TEMPLATE_CONFIG}/debian.common.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.common.conf" >> $path/config fi if [ -e "${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" ]; then echo "lxc.include = ${LXC_TEMPLATE_CONFIG}/debian.${release}.conf" >> $path/config fi ## Add the container-specific config echo "" >> $path/config echo "# Container specific configuration" >> $path/config grep -q "^lxc.rootfs" $path/config 2> /dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.tty = $num_tty lxc.utsname = $hostname lxc.arch = $arch EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } post_process() { local rootfs="$1"; shift local release="$1"; shift local arch="$1"; shift local hostarch="$1"; shift local packages="$*" # Disable service startup cat > ${rootfs}/usr/sbin/policy-rc.d << EOF #!/bin/sh exit 101 EOF chmod +x ${rootfs}/usr/sbin/policy-rc.d # If the container isn't running a native architecture, setup multiarch if [ "${arch}" != "${hostarch}" ]; then # Test if dpkg supports multiarch if ! chroot $rootfs dpkg --print-foreign-architecture 2>&1; then chroot $rootfs dpkg --add-architecture ${hostarch} fi fi # Write a new sources.list containing both native and multiarch entries > ${rootfs}/etc/apt/sources.list if [ "${arch}" = "${hostarch}" ]; then write_sourceslist ${rootfs} ${release} ${arch} else write_sourceslist ${rootfs} ${release} fi # Install Packages in container if [ -n "${packages}" ]; then local pack_list="`echo ${packages} | sed 's/,/ /g'`" echo "Installing packages: ${pack_list}" install_packages ${rootfs} ${pack_list} fi # Re-enable service startup rm ${rootfs}/usr/sbin/policy-rc.d # reconfigure locales if [ -z "$LANG" ]; then cat >> $rootfs/etc/locale.gen << EOF en_US.UTF-8 UTF-8 EOF chroot $rootfs locale-gen en_US.UTF-8 UTF-8 chroot $rootfs update-locale LANG=en_US.UTF-8 else encoding=$(echo $LANG | cut -d. -f2) chroot $rootfs sed -e "s/^# \(${LANG} ${encoding}\)/\1/" \ -i /etc/locale.gen 2> /dev/null cat >> $rootfs/etc/locale.gen << EOF $LANG $encoding EOF chroot $rootfs locale-gen $LANG $encoding chroot $rootfs update-locale LANG=$LANG fi # end } clean() { cache=${LXC_CACHE_PATH:-"$LOCALSTATEDIR/cache/lxc/debian"} if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>$LOCALSTATEDIR/lock/subsys/lxc-debian } usage() { cat < [-c|--clean] [-a|--arch=] [-r|--release=] [--mirror=] [--security-mirror=] [--package=] Options : -h, --help print this help text -p, --path=PATH directory where config and rootfs of this VM will be kept -a, --arch=ARCH The container architecture. Can be one of: i686, x86_64, amd64, armhf, armel, powerpc. Defaults to host arch. -r, --release=RELEASE Debian release. Can be one of: wheezy, jessie, stretch, sid. Defaults to current stable. --mirror=MIRROR Debian mirror to use during installation. Overrides the MIRROR environment variable (see below). --security-mirror=SECURITY_MIRROR Debian mirror to use for security updates. Overrides the SECURITY_MIRROR environment variable (see below). --packages=PACKAGE_NAME1,PACKAGE_NAME2,... List of additional packages to install. Comma separated, without space. -c, --clean only clean up the cache and terminate --enable-non-free include also Debian's contrib and non-free repositories. Environment variables: MIRROR The Debian package mirror to use. See also the --mirror switch above. Defaults to '$MIRROR' SECURITY_MIRROR The Debian package security mirror to use. See also the --security-mirror switch above. Defaults to '$SECURITY_MIRROR' EOF return 0 } options=$(getopt -o hp:n:a:r:c -l arch:,clean,help,enable-non-free,mirror:,name:,packages:,path:,release:,rootfs:,security-mirror: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" arch=$(uname -m) if [ "$arch" = "i686" ]; then arch="i386" elif [ "$arch" = "x86_64" ]; then arch="amd64" elif [ "$arch" = "armv7l" ]; then arch="armhf" fi hostarch=$arch mainonly=1 while true do case "$1" in -h|--help) usage $0 && exit 1;; --) shift 1; break ;; -a|--arch) arch=$2; shift 2;; -c|--clean) clean=1; shift 1;; --enable-non-free) mainonly=0; shift 1;; --mirror) MIRROR=$2; shift 2;; -n|--name) name=$2; shift 2;; --packages) packages=$2; shift 2;; -p|--path) path=$2; shift 2;; -r|--release) release=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; --security-mirror) SECURITY_MIRROR=$2; shift 2;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi if [ "$arch" = "i686" ]; then arch=i386 fi if [ "$arch" = "x86_64" ]; then arch=amd64 fi if [ $hostarch = "i386" -a $arch = "amd64" ]; then echo "can't create $arch container on $hostarch" exit 1 fi if [ $hostarch = "armhf" -o $hostarch = "armel" ] && \ [ $arch != "armhf" -a $arch != "armel" ]; then echo "can't create $arch container on $hostarch" exit 1 fi if [ $hostarch = "powerpc" -a $arch != "powerpc" ]; then echo "can't create $arch container on $hostarch" exit 1 fi type debootstrap if [ $? -ne 0 ]; then echo "'debootstrap' command is missing" exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi current_release=`wget ${MIRROR}/dists/stable/Release -O - 2> /dev/null | head |awk '/^Codename: (.*)$/ { print $2; }'` release=${release:-${current_release}} valid_releases=('wheezy' 'jessie' 'stretch' 'sid') if [[ ! "${valid_releases[*]}" =~ (^|[^[:alpha:]])$release([^[:alpha:]]|$) ]]; then echo "Invalid release ${release}, valid ones are: ${valid_releases[*]}" exit 1 fi # detect rootfs config="$path/config" if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2> /dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs[ \t]+=/{ print $2 }' $config) else rootfs=$path/rootfs fi fi # determine the number of ttys - default is 4 if grep -q '^lxc.tty' $config 2> /dev/null ; then num_tty=$(awk -F= '/^lxc.tty[ \t]+=/{ print $2 }' $config) else num_tty=4 fi install_debian $rootfs $release $arch $LXC_CACHE_PATH if [ $? -ne 0 ]; then echo "failed to install debian" exit 1 fi configure_debian $rootfs $name $num_tty if [ $? -ne 0 ]; then echo "failed to configure debian for a container" exit 1 fi copy_configuration $path $rootfs $name $arch $num_tty if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi configure_debian_systemd $path $rootfs $config $num_tty post_process ${rootfs} ${release} ${arch} ${hostarch} ${packages} if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi lxc-2.0.0/templates/lxc-plamo.in0000644061062106075000000002575512701247216013472 00000000000000#!/bin/bash -eu # # template script for generating Plamo Linux container for LXC # # # lxc: linux Container library # Authors: # KATOH Yasufumi # TAMUKI Shoichi # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ref. https://github.com/Ponce/lxc-slackware/blob/master/lxc-slackware # lxc-ubuntu script # 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 [ -r /etc/default/lxc ] && . /etc/default/lxc DLSCHEME=${DLSCHEME:-"http"} MIRRORSRV=${MIRRORSRV:-"repository.plamolinux.org"} MIRRORPATH=${MIRRORPATH:-"/pub/linux/Plamo"} CATEGORIES=${CATEGORIES-"00_base 01_minimum"} EXTRACTGRS=${EXTRACTGRS-""} IGNOREPKGS=${IGNOREPKGS-"grub kernel lilo linux_firmware microcode_ctl cpufreqd cpufrequtils gpm"} ADDONPKGS=${ADDONPKGS-"`echo contrib/Hamradio/{morse,qrq}`"} download_plamo() { # check the mini plamo was not already downloaded if ! mkdir -p $ptcache ; then echo "Failed to create '$ptcache' directory." return 1 fi # download a mini plamo into a cache echo "Downloading Plamo-$release minimal..." cd $ptcache case $DLSCHEME in http) depth=2 ;; ftp) depth=3 ;; esac rej=${IGNOREPKGS%% *} ; [ -n "$rej" ] && rej="$rej-*" if [ `echo $IGNOREPKGS | wc -w` -gt 1 ] ; then for p in ${IGNOREPKGS#* } ; do rej="$rej,$p-*" ; done fi for i in $CATEGORIES ; do wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \ -I $MIRRORPATH/Plamo-$release/$arch/plamo/$i \ -X $MIRRORPATH/Plamo-$release/$arch/plamo/$i/old \ $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/plamo/$i if [ $? -ne 0 ] ; then echo "Failed to download the rootfs, aborting." return 1 fi done for i in $EXTRACTGRS ; do wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \ -I $MIRRORPATH/Plamo-$release/$arch/contrib/$i \ -X $MIRRORPATH/Plamo-$release/$arch/contrib/$i/old \ $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/contrib/$i if [ $? -ne 0 ] ; then echo "Failed to download the rootfs, aborting." return 1 fi done for p in $ADDONPKGS ; do wget -nv -e robots=off -r -l $depth -nd -A "`basename $p`-*" \ -I $MIRRORPATH/Plamo-$release/$arch/`dirname $p` \ -X $MIRRORPATH/Plamo-$release/$arch/`dirname $p`/old \ $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/`dirname $p` if [ $? -ne 0 ] ; then echo "Failed to download the rootfs, aborting." return 1 fi done mv $ptcache $dlcache echo "Download complete." return 0 } copy_plamo() { # make a local copy of the mini plamo echo "Copying $rtcache to $rootfs..." mkdir -p $rootfs find $rtcache -mindepth 1 -maxdepth 1 -exec cp -a {} $rootfs \; || return 1 return 0 } install_plamo() { mkdir -p @LOCALSTATEDIR@/lock/subsys ( if ! flock -n 9 ; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $dlcache..." if [ ! -d $dlcache ] ; then if ! download_plamo ; then echo "Failed to download plamo $release base packages." return 1 fi fi # install "installpkg" command temporarily with static linked tar # command into the lxc cache directory to keep the original uid/ # gid of files/directories. echo "Installing 'installpkg' command into $dlcache/sbin..." ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var ) sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg* PATH=$dlcache/sbin:$PATH echo "Installing packages to $rtcache..." if [ ! -d $rtcache ] ; then mkdir -p $rtcache for p in `ls -cr $dlcache/*.t?z` ; do installpkg -root $rtcache -priority ADD $p done fi echo "Copy $rtcache to $rootfs..." if ! copy_plamo ; then echo "Failed to copy rootfs." return 1 fi return 0 ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo } configure_plamo() { # suppress log level output for udev sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf # /etc/fstab cat <<- "EOF" > $rootfs/etc/fstab none /proc proc defaults 0 0 none /sys sysfs defaults 0 0 none /dev tmpfs defaults 0 0 none /tmp tmpfs defaults 0 0 none /dev/pts devpts gid=5,mode=620 0 0 none /proc/bus/usb usbfs noauto 0 0 none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0 EOF # /etc/inittab cat <<- "EOF" | patch $rootfs/etc/inittab 32,33c32,33 < # What to do when power fails (shutdown to single user). < pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING" --- > # What to do when power fails (shutdown). > pf::powerfail:/sbin/shutdown -h +0 "THE POWER IS FAILING" 47a48 > 1:1235:respawn:/sbin/agetty 38400 console 52,53d52 < c5:1235:respawn:/sbin/agetty 38400 tty5 linux < c6:12345:respawn:/sbin/agetty 38400 tty6 linux EOF # set the hostname echo "$name" > $rootfs/etc/HOSTNAME # set minimal hosts echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts # configure the network using the dhcp echo "DHCP" > $rootfs/var/run/inet1-scheme # localtime (JST) ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver) sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login # glibc configure mv $rootfs/etc/ld.so.conf{.new,} chroot $rootfs ldconfig # root password echo "Setting root password to 'root'..." echo "root:root" | chroot $rootfs chpasswd echo "Please change root password!" ed - $rootfs/etc/rc.d/rc.S <<- "EOF" /^mount -w -n -t proc/;/^mkdir \/dev\/shm/-1d /^mknod \/dev\/null/;/^# Clean \/etc\/mtab/-2d /^# copy the rules/;/^# Set the hostname/-1d /^# Check the integrity/;/^# Clean up temporary/-1d w EOF # /etc/rc.d/rc.M ed - $rootfs/etc/rc.d/rc.M <<- "EOF" /^# Screen blanks/;/^# Initialize ip6tables/-1d /^# Initialize sysctl/;/^echo "Starting services/-1d /^sync/;/^# All done/-1d w EOF # /etc/rc.d/rc.inet1.tradnet head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly cat <<- EOF >> /tmp/netconfig.rconly PCMCIA=n RC=$rootfs/etc/rc.d/rc.inet1.tradnet IFCONFIG=sbin/ifconfig ROUTE=sbin/route INET1SCHEME=var/run/inet1-scheme IPADDR=127.0.0.1 NETWORK=127.0.0.0 DHCPCD=usr/sbin/dhclient LOOPBACK=y make_config_file EOF rm -f $rootfs/etc/rc.d/rc.inet1.tradnet sh /tmp/netconfig.rconly rm -f /tmp/netconfig.rconly sed -i '/cmdline/s/if/& false \&\&/' $rootfs/etc/rc.d/rc.inet1.tradnet return 0 } copy_configuration() { ret=0 cat <<- EOF >> $path/config || let ret++ lxc.utsname = $name lxc.arch = $arch EOF if [ -f "@LXCTEMPLATECONFIG@/plamo.common.conf" ] ; then cat <<- "EOF" >> $path/config || let ret++ lxc.include = @LXCTEMPLATECONFIG@/plamo.common.conf EOF fi if [ $ret -ne 0 ] ; then echo "Failed to add configuration." return 1 fi return 0 } post_process() { # nothing do in Plamo Linux true } do_bindhome() { # bind-mount the user's path into the container's /home h=`getent passwd $bindhome | cut -d: -f6` mkdir -p $rootfs/$h echo "lxc.mount.entry = $h $rootfs/$h none bind 0 0" >> $path/config # copy /etc/passwd, /etc/shadow, and /etc/group entries into container if ! pwd=`getent passwd $bindhome` ; then echo "Warning: failed to copy password entry for $bindhome." else echo $pwd >> $rootfs/etc/passwd fi echo `getent shadow $bindhome` >> $rootfs/etc/shadow } cleanup() { [ -d $dlcache -a -d $rtcache ] || return 0 # lock, so we won't purge while someone is creating a repository ( if ! flock -n 9 ; then echo "Cache repository is busy." return 1 fi echo "Purging the download cache..." rm -rf --one-file-system $dlcache $rtcache || return 1 echo "Done." return 0 ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo } usage() { cat <<- EOF $prog [-h|--help] -p|--path= -n|--name= --rootfs= [-c|--clean] [-r|--release=] [-a|--arch=] [-b|--bindhome=] release: $release arch: x86 or x86_64: defaults to host arch bindhome: bind 's home into the container EOF } prog=`basename $0` path="" ; name="" ; rootfs="" clean=0 release=${release:-6.x} arch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch bindhome="" sopts=hp:n:cr:a:b: lopts=help,path:,name:,rootfs:,clean,release:,arch:,bindhome: if ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then usage exit 1 fi eval set -- "$options" while true ; do case "$1" in -h|--help) usage && exit 0 ;; -p|--path) path=$2 ; shift 2 ;; -n|--name) name=$2 ; shift 2 ;; --rootfs) rootfs=$2 ; shift 2 ;; -c|--clean) clean=1 ; shift 1 ;; -r|--release) release=$2 ; shift 2 ;; -a|--arch) arch=$2 ; shift 2 ;; -b|--bindhome) bindhome=$2 ; shift 2 ;; --) shift 1 ; break ;; *) break ;; esac done if [ $clean -eq 1 -a -z "$path" ] ; then cleanup || exit 1 exit 0 fi if [ $hostarch == "x86" -a $arch == "x86_64" ] ; then echo "Can't create x86_64 container on x86." exit 1 fi if [ -z "$path" ] ; then echo "'path' parameter is required." exit 1 fi if [ -z "$name" ] ; then echo "'name' parameter is required." exit 1 fi if [ `id -u` -ne 0 ] ; then echo "This script should be run as 'root'." exit 1 fi cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc}" ptcache=$cache/partial-${prog##*-}-$release-$arch dlcache=$cache/cache-${prog##*-}-$release-$arch rtcache=$cache/rootfs-${prog##*-}-$release-$arch if [ -z "$rootfs" ] ; then if grep -q "^lxc.rootfs" $path/config ; then rootfs=`awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config` else rootfs=$path/rootfs fi fi if ! install_plamo ; then echo "Failed to install plamo $release." exit 1 fi if ! configure_plamo ; then echo "Failed to configure plamo $release for a container." exit 1 fi if ! copy_configuration ; then echo "Failed to write configuration file." exit 1 fi post_process if [ -n "$bindhome" ] ; then do_bindhome fi if [ $clean -eq 1 ] ; then cleanup || exit 1 exit 0 fi lxc-2.0.0/templates/lxc-opensuse.in0000644061062106075000000003715712701247216014222 00000000000000#!/bin/bash # # template script for generating OpenSUSE container for LXC # # # lxc: linux Container library # Authors: # Daniel Lezcano # Frederic Crozat # Michael H. Warfield # Johannes Kastl # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 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 configure_opensuse() { rootfs=$1 hostname=$2 # set first network adapter as dhcp. This is the most common config. cat < $rootfs/etc/sysconfig/network/ifcfg-eth0 STARTMODE='auto' BOOTPROTO='dhcp' EOF # create empty fstab touch $rootfs/etc/fstab # set the hostname cat < $rootfs/etc/HOSTNAME $hostname EOF # ensure /etc/hostname is available too ln -s -f HOSTNAME $rootfs/etc/hostname # do not use hostname from HOSTNAME variable cat <> $rootfs/etc/sysconfig/cron unset HOSTNAME EOF # set minimal hosts cat < $rootfs/etc/hosts 127.0.0.1 localhost $hostname EOF # disable yast->bootloader in container cat < $rootfs/etc/sysconfig/bootloader LOADER_TYPE=none LOADER_LOCATION=none EOF # set /dev/console as securetty cat << EOF >> $rootfs/etc/securetty console EOF cat <> $rootfs/etc/sysconfig/boot # disable root fsck ROOTFS_FSCK="0" ROOTFS_BLKDEV="/dev/null" EOF # remove pointless services in a container ln -s /dev/null $rootfs/etc/systemd/system/proc-sys-fs-binfmt_misc.automount ln -s /dev/null $rootfs/etc/systemd/system/console-shell.service ln -s /dev/null $rootfs/etc/systemd/system/systemd-vconsole-setup.service sed -e 's/ConditionPathExists=.*//' /usr/lib/systemd/system/getty@.service > $rootfs/etc/systemd/system/getty@.service ln -s getty@.service $rootfs/etc/systemd/system/getty@tty1.service ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@console.service ln -s -f ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty1.service ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty2.service ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty3.service ln -s ../getty@.service $rootfs/etc/systemd/system/getty.target.wants/getty@tty4.service # copy host poweroff target as sigpwr target to make shutdown work # see https://wiki.archlinux.org/index.php/Linux_Containers#Container_cannot_be_shutdown_if_using_systemd cp /usr/lib/systemd/system/poweroff.target $rootfs/usr/lib/systemd/system/sigpwr.target touch $rootfs/etc/sysconfig/kernel echo "Please change root-password !" echo "root:root" | chpasswd -R $rootfs return 0 } download_opensuse() { cache=$1 arch=$2 if [ ! -x /usr/bin/build ]; then echo "Could not create openSUSE template :" echo "you need to install \"build\" package" return 1 fi # check the mini opensuse was not already downloaded mkdir -p "$cache/partial-$arch" if [ $? -ne 0 ]; then echo "Failed to create '$cache/partial-$arch' directory" return 1 fi # download a mini opensuse into a cache echo "Downloading opensuse minimal ..." mkdir -p "$cache/partial-$arch-packages" zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss/ repo-oss || return 1 # Leap update repos were rearranged if [ $DISTRO == "leap/42.1" ]; then zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/oss/ update || return 1 else zypper --quiet --root $cache/partial-$arch-packages --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update || return 1 fi zypper --quiet --root $cache/partial-$arch-packages --non-interactive --gpg-auto-import-keys update || return 1 zypper --root $cache/partial-$arch-packages --non-interactive in --auto-agree-with-licenses --download-only zypper lxc patterns-openSUSE-base bash iputils sed tar rsyslog || return 1 cat > $cache/partial-$arch-packages/opensuse.conf << EOF Preinstall: aaa_base bash coreutils diffutils Preinstall: filesystem fillup glibc grep insserv-compat perl-base Preinstall: libbz2-1 libgcc_s1 libncurses5 pam Preinstall: permissions libreadline6 rpm sed tar libz1 libselinux1 Preinstall: liblzma5 libcap2 libacl1 libattr1 Preinstall: libpopt0 libelf1 liblua5_1 Preinstall: libpcre1 RunScripts: aaa_base Support: zypper Support: patterns-openSUSE-base Support: lxc Support: ncurses-utils Support: iputils Support: udev Support: netcfg Support: hwinfo insserv-compat module-init-tools openSUSE-release openssh Support: pwdutils rpcbind sysconfig Ignore: rpm:suse-build-key,build-key Ignore: systemd:systemd-presets-branding EOF if [ $DISTRO = "13.2" ] then echo "Support: python3-base" >> $cache/partial-$arch-packages/opensuse.conf fi # dhcpcd is not in the default repos with Leap 42.1 if [ $DISTRO != "leap/42.1" ] then echo "Support: dhcpcd" >> $cache/partial-$arch-packages/opensuse.conf fi # Leap doesn't seem to have iproute2 utils installed if [ $DISTRO == "leap/42.1" ] then echo "Support: net-tools iproute2" >> $cache/partial-$arch-packages/opensuse.conf fi if [ "$arch" = "i686" ]; then mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/ for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i586/*" ; do ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/i686/ done mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686 for i in "$cache/partial-$arch-packages/var/cache/zypp/packages/update/i586/*" ; do ln -s $i $cache/partial-$arch-packages/var/cache/zypp/packages/update/i686/ done fi # openSUSE 13.2 has no noarch directory in update [ -d $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch ] || mkdir -p $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch CLEAN_BUILD=1 BUILD_ARCH="$arch" BUILD_ROOT="$cache/partial-$arch" BUILD_DIST="$cache/partial-$arch-packages/opensuse.conf" PATH="$PATH:/usr/lib/build" /usr/lib/build/init_buildsystem --clean --configdir /usr/lib/build/configs --cachedir $cache/partial-$arch-cache --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/repo-oss/suse/noarch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/update/$arch --repository $cache/partial-$arch-packages/var/cache/zypp/packages/update/noarch || return 1 chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/distribution/$DISTRO/repo/oss repo-oss || return 1 if [ $DISTRO == "leap/42.1" ]; then chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/oss update || return 1 else chroot $cache/partial-$arch /usr/bin/zypper --quiet --non-interactive ar http://download.opensuse.org/update/$DISTRO/ update || return 1 fi # really clean the image rm -fr $cache/partial-$arch/{.build,.guessed_dist,.srcfiles*,installed-pkg} rm -fr $cache/partial-$arch/dev # make sure we have a minimal /dev mkdir -p "$cache/partial-$arch/dev" mknod -m 666 $cache/partial-$arch/dev/null c 1 3 mknod -m 666 $cache/partial-$arch/dev/zero c 1 5 # create mtab symlink rm -f $cache/partial-$arch/etc/mtab ln -sf /proc/self/mounts $cache/partial-$arch/etc/mtab # ensure /var/run and /run are symlinked rm -fr $cache/partial-$arch/var/run ln -s -f ../run $cache/partial-$arch/var/run if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi rm -fr "$cache/partial-$arch-packages" mv "$1/partial-$arch" "$1/rootfs-$arch" echo "Download complete." return 0 } copy_opensuse() { cache=$1 arch=$2 rootfs=$3 # make a local copy of the mini opensuse echo "Copying rootfs to $rootfs ..." mkdir -p $rootfs rsync -Ha $cache/rootfs-$arch/ $rootfs/ || return 1 return 0 } install_opensuse() { # Allow the cache base to be set by environment variable cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/opensuse/$DISTRO}" rootfs=$1 mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs-$arch ... " if [ ! -e "$cache/rootfs-$arch" ]; then download_opensuse $cache $arch if [ $? -ne 0 ]; then echo "Failed to download 'opensuse base'" return 1 fi fi echo "Copy $cache/rootfs-$arch to $rootfs ... " copy_opensuse $cache $arch $rootfs if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse return $? } # Generate a random hardware (MAC) address composed of FE followed by # 5 random bytes... create_hwaddr() { openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' } copy_configuration() { path=$1 rootfs=$2 name=$3 grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo " lxc.rootfs = $rootfs_path " >> $path/config # The following code is to create static MAC addresses for each # interface in the container. This code will work for multiple # interfaces in the default config. It will also strip any # hwaddr stanzas out of the default config since we can not share # MAC addresses between containers. # # This code is largely mimiced from the Fedora Template. mv $path/config $path/config.def while read LINE do # This should catch variable expansions from the default config... if expr "${LINE}" : '.*\$' > /dev/null 2>&1 then LINE=$(eval "echo \"${LINE}\"") fi # There is a tab and a space in the regex bracket below! # Seems that \s doesn't work in brackets. KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=') if [[ "${KEY}" != "lxc.network.hwaddr" ]] then echo "${LINE}" >> $path/config if [[ "${KEY}" == "lxc.network.link" ]] then echo "lxc.network.hwaddr = $(create_hwaddr)" >> $path/config fi fi done < $path/config.def rm -f $path/config.def if [ -e "@LXCTEMPLATECONFIG@/opensuse.common.conf" ]; then echo " # Include common configuration lxc.include = @LXCTEMPLATECONFIG@/opensuse.common.conf " >> $path/config fi # Append things which require expansion here... cat <> $path/config lxc.arch = $arch lxc.utsname = $name lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined # example simple networking setup, uncomment to enable #lxc.network.type = $lxc_network_type #lxc.network.flags = up #lxc.network.link = $lxc_network_link #lxc.network.name = eth0 # Additional example for veth network type # static MAC address, #lxc.network.hwaddr = 00:16:3e:77:52:20 # persistent veth device name on host side # Note: This may potentially collide with other containers of same name! #lxc.network.veth.pair = v-$name-e0 EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } clean() { cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc/opensuse}" if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-opensuse } usage() { cat < -r|--release nn.n --clean Please give the release as 13.1, 13.2 etc. If no release is given, openSUSE 13.1 is installed. EOF return 0 } # Make arch a global. This may become configurable? arch=$(uname -m) options=$(getopt -o hp:n:r:c -l help,rootfs:,path:,name:,release:,clean -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; -r|--release) DISTRO=$2; shift 2;; -c|--clean) clean=1; shift 1;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi type zypper > /dev/null if [ $? -ne 0 ]; then echo "'zypper' command is missing" exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi if grep -q Harlequin /etc/os-release || grep -q Tumbleweed /etc/os-release ; then BVER=`rpm -q --qf '%{version}\n' build` if [ $? -ne 0 -o "$BVER" -lt "20141120" ]; then echo "Building openSUSE containers with your version of the build package is broken. Please install the update to version 20141120 or newer." exit 1 fi fi if [ -z "$DISTRO" ]; then echo "" echo "No release selected, using openSUSE 13.1" DISTRO=13.1 else echo "" case "$DISTRO" in 13.1) echo "Selected openSUSE 13.1" ;; 13.2) echo "Selected openSUSE 13.2" ;; 42.1|leap/42.1|leap) echo "Selected openSUSE Leap 42.1" DISTRO="leap/42.1" ;; *) echo "You have chosen an invalid release, quitting..." exit 1 ;; esac fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi # detect rootfs config="$path/config" if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi install_opensuse $rootfs if [ $? -ne 0 ]; then echo "failed to install opensuse" exit 1 fi configure_opensuse $rootfs $name if [ $? -ne 0 ]; then echo "failed to configure opensuse for a container" exit 1 fi copy_configuration $path $rootfs $name if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi lxc-2.0.0/templates/lxc-fedora.in0000644061062106075000000014074212701247216013614 00000000000000#!/bin/bash # # template script for generating fedora container for LXC # # # lxc: linux Container library # Authors: # Daniel Lezcano # Ramez Hanna # Michael H. Warfield # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #Configurations default_path=@LXCPATH@ # Some combinations of the tuning knobs below do not exactly make sense. # but that's ok. # # If the "root_password" is non-blank, use it, else set a default. # This can be passed to the script as an environment variable and is # set by a shell conditional assignment. Looks weird but it is what it is. # # If the root password contains a ding ($) then try to expand it. # That will pick up things like ${name} and ${RANDOM}. # If the root password contains more than 3 consecutive X's, pass it as # a template to mktemp and take the result. # # If root_display_password = yes, display the temporary root password at exit. # If root_store_password = yes, store it in the configuration directory # If root_prompt_password = yes, invoke "passwd" to force the user to change # the root password after the container is created. # If root_expire_password = yes, you will be prompted to change the root # password at the first login. # # These are conditional assignments... The can be overridden from the # preexisting environment variables... # # Make sure this is in single quotes to defer expansion to later! # :{root_password='Root-${name}-${RANDOM}'} : ${root_password='Root-${name}-XXXXXX'} # Now, it doesn't make much sense to display, store, and force change # together. But, we gotta test, right??? : ${root_display_password='no'} : ${root_store_password='yes'} # Prompting for something interactive has potential for mayhem # with users running under the API... Don't default to "yes" : ${root_prompt_password='no'} # Expire root password? Default to yes, but can be overridden from # the environment variable : ${root_expire_password='yes'} # These are only going into comments in the resulting config... lxc_network_type=veth lxc_network_link=lxcbr0 # is this fedora? # Alow for weird remixes like the Raspberry Pi # # Use the Mitre standard CPE identifier for the release ID if possible... # This may be in /etc/os-release or /etc/system-release-cpe. We # should be able to use EITHER. Give preference to /etc/os-release for now. # 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 if [ -e /etc/os-release ] then # This is a shell friendly configuration file. We can just source it. # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME . /etc/os-release echo "Host CPE ID from /etc/os-release: ${CPE_NAME}" fi if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ] then CPE_NAME=$(head -n1 /etc/system-release-cpe) CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)') if [ "${CPE_URI}" != "cpe:/o" ] then CPE_NAME= else echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}" # Probably a better way to do this but sill remain posix # compatible but this works, shrug... # Must be nice and not introduce convenient bashisms here. ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)') VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)') fi fi if [ "${CPE_NAME}" != "" -a "${ID}" = "fedora" -a "${VERSION_ID}" != "" ] then fedora_host_ver=${VERSION_ID} is_fedora=true elif [ -e /etc/redhat-release ] then # Only if all other methods fail, try to parse the redhat-release file. fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release ) if [ "$fedora_host_ver" != "" ] then is_fedora=true fi fi configure_fedora() { # disable selinux in fedora mkdir -p $rootfs_path/selinux echo 0 > $rootfs_path/selinux/enforce # Also kill it in the /etc/selinux/config file if it's there... if [[ -f $rootfs_path/etc/selinux/config ]] then sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config fi # Nice catch from Dwight Engen in the Oracle template. # Wantonly plagerized here with much appreciation. if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled fi # This is a known problem and documented in RedHat bugzilla as relating # to a problem with auditing enabled. This prevents an error in # the container "Cannot make/remove an entry for the specified session" sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd if [ -f ${rootfs_path}/etc/pam.d/crond ] then sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond fi # In addition to disabling pam_loginuid in the above config files # we'll also disable it by linking it to pam_permit to catch any # we missed or any that get installed after the container is built. # # Catch either or both 32 and 64 bit archs. if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ] then ( cd ${rootfs_path}/lib/security/ mv pam_loginuid.so pam_loginuid.so.disabled ln -s pam_permit.so pam_loginuid.so ) fi if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ] then ( cd ${rootfs_path}/lib64/security/ mv pam_loginuid.so pam_loginuid.so.disabled ln -s pam_permit.so pam_loginuid.so ) fi # Set default localtime to the host localtime if not set... if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ] then # if /etc/localtime is a symlink, this should preserve it. cp -a /etc/localtime ${rootfs_path}/etc/localtime fi # Deal with some dain bramage in the /etc/init.d/halt script. # Trim it and make it our own and link it in before the default # halt script so we can intercept it. This also preventions package # updates from interferring with our interferring with it. # # There's generally not much in the halt script that useful but what's # in there from resetting the hardware clock down is generally very bad. # So we just eliminate the whole bottom half of that script in making # ourselves a copy. That way a major update to the init scripts won't # trash what we've set up. # # This is mostly for legacy distros since any modern systemd Fedora # release will not have this script so we won't try to intercept it. if [ -f ${rootfs_path}/etc/init.d/halt ] then sed -e '/hwclock/,$d' \ < ${rootfs_path}/etc/init.d/halt \ > ${rootfs_path}/etc/init.d/lxc-halt echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt chmod 755 ${rootfs_path}/etc/init.d/lxc-halt # Link them into the rc directories... ( cd ${rootfs_path}/etc/rc.d/rc0.d ln -s ../init.d/lxc-halt S00lxc-halt cd ${rootfs_path}/etc/rc.d/rc6.d ln -s ../init.d/lxc-halt S00lxc-reboot ) fi # configure the network using the dhcp cat < ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes HOSTNAME=${utsname} DHCP_HOSTNAME=\`hostname\` NM_CONTROLLED=no TYPE=Ethernet MTU=${MTU} EOF # set the hostname cat < ${rootfs_path}/etc/sysconfig/network NETWORKING=yes HOSTNAME=${utsname} EOF # set hostname on systemd Fedora systems if [ $release -gt 14 ]; then echo "${utsname}" > ${rootfs_path}/etc/hostname fi # set minimal hosts cat < $rootfs_path/etc/hosts 127.0.0.1 localhost.localdomain localhost $utsname ::1 localhost6.localdomain6 localhost6 EOF # These mknod's really don't make any sense with modern releases of # Fedora with systemd, devtmpfs, and autodev enabled. They are left # here for legacy reasons and older releases with upstart and sysv init. dev_path="${rootfs_path}/dev" rm -rf $dev_path mkdir -p $dev_path mknod -m 666 ${dev_path}/null c 1 3 mknod -m 666 ${dev_path}/zero c 1 5 mknod -m 666 ${dev_path}/random c 1 8 mknod -m 666 ${dev_path}/urandom c 1 9 mkdir -m 755 ${dev_path}/pts mkdir -m 1777 ${dev_path}/shm mknod -m 666 ${dev_path}/tty c 5 0 mknod -m 666 ${dev_path}/tty0 c 4 0 mknod -m 666 ${dev_path}/tty1 c 4 1 mknod -m 666 ${dev_path}/tty2 c 4 2 mknod -m 666 ${dev_path}/tty3 c 4 3 mknod -m 666 ${dev_path}/tty4 c 4 4 mknod -m 600 ${dev_path}/console c 5 1 mknod -m 666 ${dev_path}/full c 1 7 mknod -m 600 ${dev_path}/initctl p mknod -m 666 ${dev_path}/ptmx c 5 2 # setup console and tty[1-4] for login. note that /dev/console and # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. # lxc will maintain these links and bind mount ptys over /dev/lxc/* # since lxc.devttydir is specified in the config. # allow root login on console, tty[1-4], and pts/0 for libvirt echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty echo "lxc/console" >>${rootfs_path}/etc/securetty echo "lxc/tty1" >>${rootfs_path}/etc/securetty echo "lxc/tty2" >>${rootfs_path}/etc/securetty echo "lxc/tty3" >>${rootfs_path}/etc/securetty echo "lxc/tty4" >>${rootfs_path}/etc/securetty echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty echo "pts/0" >>${rootfs_path}/etc/securetty if [ ${root_display_password} = "yes" ] then echo "Setting root password to '$root_password'" fi if [ ${root_store_password} = "yes" ] then touch ${config_path}/tmp_root_pass chmod 600 ${config_path}/tmp_root_pass echo ${root_password} > ${config_path}/tmp_root_pass echo "Storing root password in '${config_path}/tmp_root_pass'" fi echo "root:$root_password" | chroot $rootfs_path chpasswd if [ ${root_expire_password} = "yes" ] then # Also set this password as expired to force the user to change it! chroot $rootfs_path passwd -e root fi # specifying this in the initial packages doesn't always work. # Even though it should have... echo "installing fedora-release package" mount -o bind /dev ${rootfs_path}/dev mount -t proc proc ${rootfs_path}/proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf ${rootfs_path}/etc/ # Rebuild the rpm database based on the target rpm version... rm -f ${rootfs_path}/var/lib/rpm/__db* chroot ${rootfs_path} rpm --rebuilddb chroot ${rootfs_path} yum -y install fedora-release if [[ ! -e ${rootfs_path}/sbin/NetworkManager ]] then # NetworkManager has not been installed. Use the # legacy chkconfig command to enable the network startup # scripts in the container. chroot ${rootfs_path} chkconfig network on fi umount ${rootfs_path}/proc umount ${rootfs_path}/dev # silence some needless startup errors touch ${rootfs_path}/etc/fstab # give us a console on /dev/console sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \ ${rootfs_path}/etc/sysconfig/init return 0 } configure_fedora_init() { sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit # don't mount devpts, for pete's sake sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit chroot ${rootfs_path} chkconfig udev-post off chroot ${rootfs_path} chkconfig network on if [ -d ${rootfs_path}/etc/init ] then # This is to make upstart honor SIGPWR. Should do no harm # on systemd systems and some systems may have both. cat <${rootfs_path}/etc/init/power-status-changed.conf # power-status-changed - shutdown on SIGPWR # start on power-status-changed exec /sbin/shutdown -h now "SIGPWR received" EOF fi } configure_fedora_systemd() { rm -f ${rootfs_path}/etc/systemd/system/default.target touch ${rootfs_path}/etc/fstab chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target # Make systemd honor SIGPWR chroot ${rootfs_path} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target # if desired, prevent systemd from over-mounting /tmp with tmpfs if [ $masktmp -eq 1 ]; then chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/tmp.mount fi #dependency on a device unit fails it specially that we disabled udev # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service # # Actually, the After=dev-%i.device line does not appear in the # Fedora 17 or Fedora 18 systemd getty\@.service file. It may be left # over from an earlier version and it's not doing any harm. We do need # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are # started on the ttys in the container. Lets do it in an override copy of # the service so it can still pass rpm verifies and not be automatically # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/ sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \ -e 's/After=dev-%i.device/After=/' \ < ${rootfs_path}/lib/systemd/system/getty\@.service \ > ${rootfs_path}/etc/systemd/system/getty\@.service # Setup getty service on the 4 ttys we are going to allow in the # default config. Number should match lxc.tty ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done ) } ### BEGIN Bootstrap Environment Code... Michael H. Warfield /\/\|=mhw=|\/\/ # Ok... Heads up. If you're reading these comments, you're either a # template owner or someone wondering how the hell I did this (or, worse, # someone in the future trying to maintain it). This code is slightly # "evil coding bastard" code with one significant hack / dirty trick # that you would probably miss just reading the code below. I'll mark # it out with comments. # # Because of what this code does, it deserves a lot of comments so people # can understand WHY I did it this way... # # Ultimate Objective - Build a Fedora container on a host system which does # not have a (complete compatible) version of rpm and/or yum. That basically # means damn near any distro other than Fedora and Ubuntu (which has rpm and # yum available). Only requirements for this function are rsync and # squashfs available to the kernel. If you don't have those, why are you # even attempting to build containers? # # Challenge for this function - Bootstrap a Fedora install bootstrap # run time environment which has all the pieces to run rpm and yum and # from which we can build targets containers even where the host system # has no support for rpm, yum, or fedora. # # Steps: # Stage 0 - Download a Fedora LiveOS squashfs core (netinst core). # Stage 1 - Extract filesystem from Stage 0 and update to full rpm & yum # Stage 2 - Use Stage 1 to build a rootfs with python, rpm, and yum. # # Stage 2 becomes our bootstrap file system which can be cached # and then used to build other arbitrary vesions of Fedora of a # given architecture. Note that this only has to run once for # Fedora on a given architecture since rpm and yum can build other # versions. We'll arbitrarily pick Fedora 20 to build this. This # will need to change as time goes on. # Programmers Note... A future fall back may be to download the netinst # iso image instead of the LiveOS squasfs image and work from that. # That may be more general but will introduce another substep # (mounting the iso) to the stage0 setup. # This system is designed to be as autonomous as possible so all whitelists # and controls are self-contained. # Initial testing - Whitelist nobody. Build for everybody... # Initial deployment - Whitelist Fedora. # Long term - Whitelist Fedora, Debian, Ubuntu, CentOs, Scientific, and NST. # List of distros which do not (should not) need a bootstrap (but we will test # for rpm and yum none the less... OS SHOULD be taken from CPE values but # Debian / Ubuntu doesn't support CPE yet. # BOOTSTRAP_WHITE_LIST="" BOOTSTRAP_WHITE_LIST="fedora" # BOOTSTRAP_WHITE_LIST="fedora debian ubuntu centos scientific sl nst" BOOTSTRAP=0 BOOTSTRAP_DIR= BOOTSTRAP_CHROOT= fedora_get_bootstrap() { echo "Bootstrap Environment testing..." WHITE_LISTED=1 # We need rpm. No rpm - not possible to white list... if ! which rpm > /dev/null 2>&1 then WHITE_LISTED=0 fi # We need yum No yum - not possible to white list... if ! which yum > /dev/null 2>&1 then WHITE_LISTED=0 fi if [[ ${WHITE_LISTED} != 0 ]] then for OS in ${BOOTSTRAP_WHITE_LIST} do if [[ ${ID} = ${OS} ]] then echo " OS ${ID} is whitelisted. Installation Bootstrap Environment not required. " return 0; fi done fi echo " Fedora Installation Bootstrap Build..." if ! which rsync > /dev/null 2>&1 then echo " Unable to locate rsync. Cravely bailing out before even attempting to build an Installation Bootstrap Please install rsync and then rerun this process. " return 255 fi [[ -d ${cache_base} ]] || mkdir -p ${cache_base} cd ${cache_base} # We know we don't have a cache directory of this version or we # would have never reached this code to begin with. But we may # have another Fedora cache directory from which we could run... # We'll give a preference for close matches preferring higher over # lower - which makes for really ugly code... # Is this a "bashism" that will need cleaning up???? BOOTSTRAP_LIST="$(( $release + 1 ))/rootfs $(( $release - 1 ))/rootfs \ $(( $release + 2 ))/rootfs $(( $release - 2 ))/rootfs \ $(( $release + 3 ))/rootfs $(( $release - 3 ))/rootfs \ bootstrap" for bootstrap in ${BOOTSTRAP_LIST} do if [[ -d ${bootstrap} ]] then echo " Existing Bootstrap found. Testing..." mount -o bind /dev ${bootstrap}/dev mount -t proc proc ${bootstrap}/proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf ${bootstrap}/etc/ rm -f ${bootstrap}/var/lib/rpm/__db* chroot ${bootstrap} rpm --rebuilddb chroot ${bootstrap} yum -y update RC=$? umount ${bootstrap}/proc umount ${bootstrap}/dev if [[ 0 == ${RC} ]] then BOOTSTRAP=1 BOOTSTRAP_DIR="${cache_base}/${bootstrap}" BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " BOOTSTRAP_INSTALL_ROOT=/run/install echo " Functional Installation Bootstrap exists and appears to be completed. Will use existing Bootstrap: ${BOOTSTRAP_DIR} " return 0 fi echo " Installation Bootstrap in ${BOOTSTRAP_DIR} exists but appears to be non-functional. Skipping... It should be removed. " fi done TMP_BOOTSTRAP_DIR=$( mktemp -d --tmpdir=${cache_base} bootstrap_XXXXXX ) cd ${TMP_BOOTSTRAP_DIR} mkdir squashfs stage0 stage1 bootstrap ### Stage 0 setup. # Download the LiveOS squashfs image # mount image to "squashfs" # mount contained LiveOS to stage0 # We're going to use the archives.fedoraproject.org mirror for the initial stages... # 1 - It's generally up to date and complete # 2 - It's has high bandwidth access # 3 - It supports rsync and wildcarding (and we need both) # 4 - Not all the mirrors carry the LiveOS images if [[ ! -f ../LiveOS/squashfs.img ]] then echo " Downloading stage 0 LiveOS squashfs file system from archives.fedoraproject.org... Have a beer or a cup of coffee. This will take a bit (~300MB). " sleep 3 # let him read it... # Right now, we are using Fedora 20 for the inial bootstrap. # We could make this the "current" Fedora rev (F > 15). rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/LiveOS . if [[ 0 == $? ]] then echo "Download of squashfs image complete." mv LiveOS .. else echo " Download of squashfs image failed. " return 255 fi else echo "Using cached stage 0 LiveOS squashfs file system." fi mount -o loop ../LiveOS/squashfs.img squashfs if [[ $? != 0 ]] then echo " Mount of LiveOS squashfs image failed! You mush have squashfs support available to mount image. Unable to continue. Correct and retry process later! LiveOS image not removed. Process may be rerun without penalty of downloading LiveOS again. If LiveOS is corrupt, remove ${cache_base}/LiveOS before rerunning to redownload. " return 255 fi mount -o loop squashfs/LiveOS/rootfs.img stage0 if [[ $? != 0 ]] then echo " Mount of LiveOS stage0 rootfs image failed! LiveOS download may be corrupt. Remove ${cache_base}/LiveOS to force a new download or troubleshoot cached image and then rerun process. " return 255 fi ### Stage 1 setup. # Copy stage0 (which is ro) to stage1 area (rw) for modification. # Unmount stage0 mounts - we're done with stage 0 at this point. # Download our rpm and yum rpm packages. # Force install of rpm and yum into stage1 image (dirty hack!) echo "Stage 0 complete, building Stage 1 image... This will take a couple of minutes. Patience..." echo "Creating Stage 1 r/w copy of r/o Stage 0 squashfs image from LiveOS." rsync -aAHS stage0/. stage1/ umount stage0 umount squashfs cd stage1 # Setup stage1 image with pieces to run installs... mount -o bind /dev dev mount -t proc proc proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf etc/ mkdir run/install echo "Updating Stage 1 image with full rpm and yum packages" # Retrieve our 2 rpm packages we need to force down the throat # of this LiveOS image we're camped out on. This is the beginning # of the butt ugly hack. Look close or you may missing it... rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/r/rpm-[0-9]* \ ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/y/yum-[0-9]* . # And here it is... # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! chroot . rpm -ivh --nodeps rpm-* yum-* # Did you catch it? # The LiveOS image contains rpm (but not rpmdb) and yum (but not # yummain.py - What the hell good does yum do with no # yummain.py?!?! - Sigh...). It contains all the supporting # pieces but the rpm database has not be initialized and it # doesn't know all the dependences (seem to) have been met. # So we do a "--nodeps" rpm install in the chrooted environment # to force the installation of the full rpm and yum packages. # # For the purists - Yes, I know the rpm database is wildly out # of whack now. That's why this is a butt ugly hack / dirty trick. # But, this is just the stage1 image that we are going to discard as # soon as the stage2 image is built, so we don't care. All we care # is that the stage2 image ends up with all the pieces it need to # run yum and rpm and that the stage2 rpm database is coherent. # # NOW we can really go to work! ### Stage 2 setup. # Download our Fedora Release rpm packages. # Install fedora-release into bootstrap to initialize fs and databases. # Install rpm, and yum into bootstrap image using yum echo "Stage 1 creation complete. Building stage 2 Installation Bootstrap" mount -o bind ../bootstrap run/install rsync -av ${mirrorurl}/fedora/linux/releases/20/Fedora/$basearch/os/Packages/f/fedora-release-20* . # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! chroot . rpm --root /run/install --nodeps -ivh fedora-release-* # yum will take $basearch from host, so force the arch we want sed -i "s|\$basearch|$basearch|" ./run/install/etc/yum.repos.d/* chroot . yum -y --nogpgcheck --installroot /run/install install python rpm yum umount run/install umount proc umount dev # That's it! We should now have a viable installation BOOTSTRAP in # bootstrap We'll do a yum update in that to verify and then # move it to the cache location before cleaning up. cd ../bootstrap mount -o bind /dev dev mount -t proc proc proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf etc/ # yum will take $basearch from host, so force the arch we want sed -i "s|\$basearch|$basearch|" ./etc/yum.repos.d/* chroot . yum -y update RC=$? umount proc umount dev cd .. if [[ ${RC} != 0 ]] then echo " Build of Installation Bootstrap failed. Temp directory not removed so it can be investigated. " return 255 fi # We know have a working run time environment in rootfs... mv bootstrap .. cd .. rm -rf ${TMP_BOOTSTRAP_DIR} echo " Build of Installation Bootstrap complete! We now return you to your normally scheduled template creation. " BOOTSTRAP=1 BOOTSTRAP_DIR="${cache_base}/bootstrap" BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " BOOTSTRAP_INSTALL_ROOT=/run/install return 0 } fedora_bootstrap_mounts() { if [[ ${BOOTSTRAP} -ne 1 ]] then return 0 fi BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " echo "Mounting Bootstrap mount points" [[ -d ${BOOTSTRAP_DIR}/run/install ]] || mkdir -p ${BOOTSTRAP_DIR}/run/install mount -o bind ${INSTALL_ROOT} ${BOOTSTRAP_DIR}/run/install mount -o bind /dev ${BOOTSTRAP_DIR}/dev mount -t proc proc ${BOOTSTRAP_DIR}/proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf ${BOOTSTRAP_DIR}/etc/ } fedora_bootstrap_umounts() { if [[ ${BOOTSTRAP} -ne 1 ]] then return 0 fi umount ${BOOTSTRAP_DIR}/proc umount ${BOOTSTRAP_DIR}/dev umount ${BOOTSTRAP_DIR}/run/install } # This is the code to create the initial roofs for Fedora. It may # require a run time environment by calling the routines above... download_fedora() { # check the mini fedora was not already downloaded INSTALL_ROOT=$cache/partial mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then echo "Failed to create '$INSTALL_ROOT' directory" return 1 fi # download a mini fedora into a cache echo "Downloading fedora minimal ..." # These will get changed if it's decided that we need a # boostrap environment (can not build natively). These # are the defaults for the non-boostrap (native) mode. BOOTSTRAP_INSTALL_ROOT=${INSTALL_ROOT} BOOTSTRAP_CHROOT= BOOTSTRAP_DIR= PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils fedora-release" MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$basearch" if [[ ${release} -lt 17 ]] then # The reflects the move of db_dump and db_load from db4_utils to # libdb_utils in Fedora 17 and above and it's inclusion as a dep... # Prior to Fedora 11, we need to explicitly include it! PKG_LIST="${PKG_LIST} db4-utils" fi if [[ ${release} -ge 21 ]] then # Since Fedora 21, a separate fedora-repos package is needed. # Before, the information was conained in fedora-release. PKG_LIST="${PKG_LIST} fedora-repos" fi DOWNLOAD_OK=no # We're splitting the old loop into two loops plus a directory retrival. # First loop... Try and retrive a mirror list with retries and a slight # delay between attempts... for trynumber in 1 2 3 4; do [ $trynumber != 1 ] && echo "Trying again..." # This code is mildly "brittle" in that it assumes a certain # page format and parsing HTML. I've done worse. :-P MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d') if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ] then break fi echo "Failed to get a mirror on try $trynumber" sleep 3 done # This will fall through if we didn't get any URLS above for MIRROR_URL in ${MIRROR_URLS} do if [ "$release" -gt "16" ]; then RELEASE_URL="$MIRROR_URL/Packages/f" else RELEASE_URL="$MIRROR_URL/Packages/" fi echo "Fetching release rpm name from $RELEASE_URL..." # This code is mildly "brittle" in that it assumes a certain directory # page format and parsing HTML. I've done worse. :-P RELEASE_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-release-${release}-/!d" -e 's/.*.*//' ) if [ $? -ne 0 -o "${RELEASE_RPM}" = "" ]; then echo "Failed to identify fedora release rpm." continue fi echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......" curl -L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM} if [ $? -ne 0 ]; then echo "Failed to download fedora release rpm ${RELEASE_RPM}." continue fi # F21 and newer need fedora-repos in addition to fedora-release. if [ "$release" -ge "21" ]; then echo "Fetching repos rpm name from $RELEASE_URL..." REPOS_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-repos-${release}-/!d" -e 's/.*.*//' ) if [ $? -ne 0 -o "${REPOS_RPM}" = "" ]; then echo "Failed to identify fedora repos rpm." continue fi echo "Fetching fedora repos rpm from ${RELEASE_URL}/${REPOS_RPM}..." curl -L -f "${RELEASE_URL}/${REPOS_RPM}" > ${INSTALL_ROOT}/${REPOS_RPM} if [ $? -ne 0 ]; then echo "Failed to download fedora repos rpm ${RELEASE_RPM}." continue fi fi DOWNLOAD_OK=yes break done if [ $DOWNLOAD_OK != yes ]; then echo "Aborting" return 1 fi mkdir -p ${INSTALL_ROOT}/var/lib/rpm if ! fedora_get_bootstrap then echo "Fedora Bootstrap setup failed" return 1 fi fedora_bootstrap_mounts ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --initdb # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --nodeps -ivh ${BOOTSTRAP_INSTALL_ROOT}/${RELEASE_RPM} # F21 and newer need fedora-repos in addition to fedora-release... # Note that fedora-release and fedora-system have a mutual dependency. # So installing the reops package after the release package we can # spare one --nodeps. if [ "$release" -ge "21" ]; then ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} -ivh ${BOOTSTRAP_INSTALL_ROOT}/${REPOS_RPM} fi # yum will take $basearch from host, so force the arch we want sed -i "s|\$basearch|$basearch|" ${BOOTSTRAP_DIR}/${BOOTSTRAP_INSTALL_ROOT}/etc/yum.repos.d/* ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST} RC=$? if [[ ${BOOTSTRAP} -eq 1 ]] then # Here we have a bit of a sticky problem. We MIGHT have just installed # this template cache using versions of yum and rpm in the bootstrap # chroot that use a different database version than the target version. # That can be a very big problem. Solution is to rebuild the rpmdatabase # with the target database now that we are done building the cache. In the # vast majority of cases, this is a do-not-care with no harm done if we # didn't do it. But it catches several corner cases with older unsupported # releases and it really doesn't cost us a lot of time for a one shot # install that will never be done again for this rev. # # Thanks and appreciation to Dwight Engen and the Oracle template for the # database rewrite hint! echo "Fixing up rpm databases" # Change to our target install directory (if we're not already # there) just to simplify some of the logic to follow... cd ${INSTALL_ROOT} rm -f var/lib/rpm/__db* # Programmers Note (warning): # # Pay careful attention to the following commands! It # crosses TWO chroot boundaries linked by a bind mount! # In the bootstrap case, that's the bind mount of ${INSTALL_ROOT} # to the ${BOOTSTRAP_CHROOT}/run/install directory! This is # a deliberate hack across that bind mount to do a database # translation between two environments, neither of which may # be the host environment! It's ugly and hard to follow but, # if you don't understand it, don't mess with it! The pipe # is in host space between the two chrooted environments! # This is also why we cd'ed into the INSTALL_ROOT directory # in advance of this loop, so everything is relative to the # current working directory and congruent with the same working # space in both chrooted environments. The output into the new # db is also done in INSTALL_ROOT space but works in either host # space or INSTALL_ROOT space for the mv, so we don't care. It's # just not obvious what's happening in the db_dump and db_load # commands... # for db in var/lib/rpm/* ; do ${BOOTSTRAP_CHROOT} db_dump ${BOOTSTRAP_INSTALL_ROOT}/$db | chroot . db_load $db.new mv $db.new $db done # finish up by rebuilding the database... # This should be redundant but we do it for completeness and # any corner cases I may have missed... mount -t proc proc proc mount -o bind /dev dev chroot . rpm --rebuilddb umount dev umount proc fi fedora_bootstrap_umounts if [ ${RC} -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv "$INSTALL_ROOT" "$cache/rootfs" echo "Download complete." return 0 } copy_fedora() { # make a local copy of the minifedora echo -n "Copying rootfs to $rootfs_path ..." #cp -a $cache/rootfs-$basearch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path rsync -Ha $cache/rootfs/ $rootfs_path/ echo return 0 } update_fedora() { mount -o bind /dev ${cache}/rootfs/dev mount -t proc proc ${cache}/rootfs/proc # Always make sure /etc/resolv.conf is up to date in the target! cp /etc/resolv.conf ${cache}/rootfs/etc/ chroot ${cache}/rootfs yum -y update umount ${cache}/rootfs/proc umount ${cache}/rootfs/dev } install_fedora() { mkdir -p @LOCALSTATEDIR@/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs ... " if [ ! -e "$cache/rootfs" ]; then download_fedora if [ $? -ne 0 ]; then echo "Failed to download 'fedora base'" return 1 fi else echo "Cache found. Updating..." update_fedora if [ $? -ne 0 ]; then echo "Failed to update 'fedora base', continuing with last known good cache" else echo "Update finished" fi fi echo "Copy $cache/rootfs to $rootfs_path ... " copy_fedora if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora return $? } # Generate a random hardware (MAC) address composed of FE followed by # 5 random bytes... create_hwaddr() { openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' } copy_configuration() { mkdir -p $config_path grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo " lxc.rootfs = $rootfs_path " >> $config_path/config # The following code is to create static MAC addresses for each # interface in the container. This code will work for multiple # interfaces in the default config. It will also strip any # hwaddr stanzas out of the default config since we can not share # MAC addresses between containers. mv $config_path/config $config_path/config.def while read LINE do # This should catch variable expansions from the default config... if expr "${LINE}" : '.*\$' > /dev/null 2>&1 then LINE=$(eval "echo \"${LINE}\"") fi # There is a tab and a space in the regex bracket below! # Seems that \s doesn't work in brackets. KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=') if [[ "${KEY}" != "lxc.network.hwaddr" ]] then echo "${LINE}" >> $config_path/config if [[ "${KEY}" == "lxc.network.link" ]] then echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config fi fi done < $config_path/config.def rm -f $config_path/config.def if [ -e "@LXCTEMPLATECONFIG@/fedora.common.conf" ]; then echo " # Include common configuration lxc.include = @LXCTEMPLATECONFIG@/fedora.common.conf " >> $config_path/config fi # Append things which require expansion here... cat <> $config_path/config lxc.arch = $arch lxc.utsname = $utsname # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined # example simple networking setup, uncomment to enable #lxc.network.type = $lxc_network_type #lxc.network.flags = up #lxc.network.link = $lxc_network_link #lxc.network.name = eth0 # Additional example for veth network type # static MAC address, #lxc.network.hwaddr = 00:16:3e:77:52:20 # persistent veth device name on host side # Note: This may potentially collide with other containers of same name! #lxc.network.veth.pair = v-$name-e0 EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } clean() { if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache for Fedora-$release..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora } usage() { cat < [-p|--path=] [-c|--clean] [-R|--release=] [--fqdn=] [-a|--arch=] [--mask-tmp] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container Optional args: -p,--path path to where the container will be created, defaults to @LXCPATH@. --rootfs path for actual rootfs. -c,--clean clean the cache -R,--release Fedora release for the new container. Defaults to host's release if the host is Fedora. --fqdn fully qualified domain name (FQDN) for DNS and system naming -a,--arch Define what arch the container will be [i686,x86_64] --mask-tmp Prevent systemd from over-mounting /tmp with tmpfs. -h,--help print this help EOF return 0 } options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,arch:,fqdn:,mask-tmp -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi arch=$(uname -m) masktmp=0 eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs_path=$2; shift 2;; -n|--name) name=$2; shift 2;; -c|--clean) clean=1; shift 1;; -R|--release) release=$2; shift 2;; -a|--arch) newarch=$2; shift 2;; --fqdn) utsname=$2; shift 2;; --mask-tmp) masktmp=1; shift 1;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi basearch=${arch} # Map a few architectures to their generic Fedora repository archs. # The two ARM archs are a bit of a guesstimate for the v5 and v6 # archs. V6 should have hardware floating point (Rasberry Pi). # The "arm" arch is safer (no hardware floating point). So # there may be cases where we "get it wrong" for some v6 other # than RPi. case "$arch" in i686) basearch=i386 ;; armv3l|armv4l|armv5l) basearch=arm ;; armv6l|armv7l|armv8l) basearch=armhfp ;; *) ;; esac mirrorurl="archives.fedoraproject.org::fedora-archive" case "$basearch" in ppc64|s390x) mirrorurl="archives.fedoraproject.org::fedora-secondary" ;; *) ;; esac # Somebody wants to specify an arch. This is very limited case. # i386/i586/i686 on i386/x86_64 # - or - # x86_64 on x86_64 if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ] then case "${newarch}" in i386|i586|i686) if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ] then # Make the arch a generic x86 32 bit... arch=${newarch} basearch=i386 else basearch=bad fi ;; *) basearch=bad ;; esac if [ "${basearch}" = "bad" ] then echo "You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!" exit 1 fi fi # Allow the cache base to be set by environment variable cache_base=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/fedora/$basearch # Let's do something better for the initial root password. # It's not perfect but it will defeat common scanning brute force # attacks in the case where ssh is exposed. It will also be set to # expired, forcing the user to change it at first login. if [ "${root_password}" = "" ] then root_password=Root-${name}-${RANDOM} else # If it's got a ding in it, try and expand it! if [ $(expr "${root_password}" : '.*$.') != 0 ] then root_password=$(eval echo "${root_password}") fi # If it has more than 3 consecutive X's in it, feed it # through mktemp as a template. if [ $(expr "${root_password}" : '.*XXXX') != 0 ] then root_password=$(mktemp -u ${root_password}) fi fi if [ -z "${utsname}" ]; then utsname=${name} fi # This follows a standard "resolver" convention that an FQDN must have # at least two dots or it is considered a local relative host name. # If it doesn't, append the dns domain name of the host system. # # This changes one significant behavior when running # "lxc_create -n Container_Name" without using the # --fqdn option. # # Old behavior: # utsname and hostname = Container_Name # New behavior: # utsname and hostname = Container_Name.Domain_Name if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then utsname=${utsname}.$(dnsdomainname) fi fi needed_pkgs="" type curl >/dev/null 2>&1 if [ $? -ne 0 ]; then needed_pkgs="curl $needed_pkgs" fi if [ -n "$needed_pkgs" ]; then echo "Missing commands: $needed_pkgs" echo "Please install these using \"sudo yum install $needed_pkgs\"" exit 1 fi if [ -z "$path" ]; then path=$default_path/$name fi if [ -z "$release" ]; then if [ "$is_fedora" -a "$fedora_host_ver" ]; then release=$fedora_host_ver else echo "This is not a fedora host and release missing, defaulting to 22 use -R|--release to specify release" release=22 fi fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -z "$rootfs_path" ]; then rootfs_path=$path/rootfs # check for 'lxc.rootfs' passed in through default config by lxc-create if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then rootfs_path=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \ -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config) fi fi config_path=$path cache=$cache_base/$release revert() { echo "Interrupted, so cleaning up" lxc-destroy -n $name # maybe was interrupted before copy config rm -rf $path echo "exiting..." exit 1 } trap revert SIGHUP SIGINT SIGTERM copy_configuration if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi install_fedora if [ $? -ne 0 ]; then echo "failed to install fedora" exit 1 fi configure_fedora if [ $? -ne 0 ]; then echo "failed to configure fedora for a container" exit 1 fi # If the systemd configuration directory exists - set it up for what we need. if [ -d ${rootfs_path}/etc/systemd/system ] then configure_fedora_systemd fi # This configuration (rc.sysinit) is not inconsistent with the systemd stuff # above and may actually coexist on some upgraded systems. Let's just make # sure that, if it exists, we update this file, even if it's not used... if [ -f ${rootfs_path}/etc/rc.sysinit ] then configure_fedora_init fi if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi echo " Container rootfs and config have been created. Edit the config file to check/enable networking setup. " if [[ -d ${cache_base}/bootstrap ]] then echo "You have successfully built a Fedora container and cache. This cache may be used to create future containers of various revisions. The directory ${cache_base}/bootstrap contains a bootstrap which may no longer needed and can be removed. " fi if [[ -e ${cache_base}/LiveOS ]] then echo "A LiveOS directory exists at ${cache_base}/LiveOS. This is only used in the creation of the bootstrap run-time-environment and may be removed. " fi if [ ${root_display_password} = "yes" ] then echo "The temporary password for root is: '$root_password' You may want to note that password down before starting the container. " fi if [ ${root_store_password} = "yes" ] then echo "The temporary root password is stored in: '${config_path}/tmp_root_pass' " fi if [ ${root_prompt_password} = "yes" ] then echo "Invoking the passwd command in the container to set the root password. chroot ${rootfs_path} passwd " chroot ${rootfs_path} passwd else if [ ${root_expire_password} = "yes" ] then if ( mountpoint -q -- "${rootfs_path}" ) then echo "To reset the root password, you can do: lxc-start -n ${name} lxc-attach -n ${name} -- passwd lxc-stop -n ${name} " else echo " The root password is set up as "expired" and will require it to be changed at first login, which you should do as soon as possible. If you lose the root password or wish to change it without starting the container, you can change it from the host by running the following command (which will also reset the expired flag): chroot ${rootfs_path} passwd " fi fi fi lxc-2.0.0/templates/lxc-busybox.in0000644061062106075000000002757712701247216014061 00000000000000#!/bin/bash # # lxc: linux Container library # Authors: # Daniel Lezcano # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA LXC_MAPPED_UID= LXC_MAPPED_GID= SSH= # Make sure the usual locations are in PATH export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin 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 copy_binary() { binary_path=`which $1` if [ $? -ne 0 ]; then echo "Unable to find $1 binary on the system" return 1 fi dir_path="${binary_path%/*}" echo /{,usr/}{,s}bin | grep $dir_path >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Binary $1 is located at $binary_path and will not be copied" echo "($dir_path not supported)" return 1 fi cp $binary_path $rootfs/$binary_path if [ $? -ne 0 ]; then echo "Failed to copy $binary_path to rootfs" return 1 fi return 0 } install_busybox() { rootfs=$1 name=$2 res=0 tree="\ $rootfs/selinux \ $rootfs/dev \ $rootfs/home \ $rootfs/root \ $rootfs/etc \ $rootfs/etc/init.d \ $rootfs/bin \ $rootfs/usr/bin \ $rootfs/sbin \ $rootfs/usr/sbin \ $rootfs/proc \ $rootfs/sys \ $rootfs/mnt \ $rootfs/tmp \ $rootfs/var/log \ $rootfs/usr/share/udhcpc \ $rootfs/dev/pts \ $rootfs/dev/shm \ $rootfs/lib \ $rootfs/usr/lib \ $rootfs/lib64 \ $rootfs/usr/lib64" mkdir -p $tree || return 1 chmod 755 $tree || return 1 pushd $rootfs/dev > /dev/null || return 1 # minimal devices needed for busybox if [ $in_userns -eq 1 ]; then for dev in tty console tty0 tty1 ram0 null urandom; do echo "lxc.mount.entry = /dev/$dev dev/$dev none bind,optional,create=file 0 0" >> $path/config done else mknod -m 666 tty c 5 0 || res=1 mknod -m 666 console c 5 1 || res=1 mknod -m 666 tty0 c 4 0 || res=1 mknod -m 666 tty1 c 4 0 || res=1 mknod -m 666 tty5 c 4 0 || res=1 mknod -m 600 ram0 b 1 0 || res=1 mknod -m 666 null c 1 3 || res=1 mknod -m 666 zero c 1 5 || res=1 mknod -m 666 urandom c 1 9 || res=1 fi popd > /dev/null # root user defined cat <> $rootfs/etc/passwd root:x:0:0:root:/root:/bin/sh EOF cat <> $rootfs/etc/group root:x:0:root EOF # mount everything cat <> $rootfs/etc/init.d/rcS #!/bin/sh /bin/syslogd /bin/mount -a /bin/udhcpc EOF # executable chmod 744 $rootfs/etc/init.d/rcS || return 1 # launch rcS first then make a console available # and propose a shell on the tty, the last one is # not needed cat <> $rootfs/etc/inittab ::sysinit:/etc/init.d/rcS tty1::respawn:/bin/getty -L tty1 115200 vt100 console::askfirst:/bin/sh EOF # writable and readable for other chmod 644 $rootfs/etc/inittab || return 1 cat <> $rootfs/usr/share/udhcpc/default.script #!/bin/sh case "\$1" in deconfig) ip addr flush dev \$interface ;; renew|bound) # flush all the routes if [ -n "\$router" ]; then ip route del default 2> /dev/null fi # check broadcast if [ -n "\$broadcast" ]; then broadcast="broadcast \$broadcast" fi # add a new ip address ip addr add \$ip/\$mask \$broadcast dev \$interface if [ -n "\$router" ]; then ip route add default via \$router dev \$interface fi [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf for i in \$dns ; do echo nameserver \$i >> /etc/resolv.conf done ;; esac exit 0 EOF chmod 744 $rootfs/usr/share/udhcpc/default.script return $res } install_dropbear() { # copy dropbear binary copy_binary dropbear || return 1 # make symlinks to various ssh utilities utils="\ $rootfs/usr/bin/dbclient \ $rootfs/usr/bin/scp \ $rootfs/usr/bin/ssh \ $rootfs/usr/sbin/dropbearkey \ $rootfs/usr/sbin/dropbearconvert \ " echo $utils | xargs -n1 ln -s /usr/sbin/dropbear # add necessary config files mkdir $rootfs/etc/dropbear dropbearkey -t rsa -f $rootfs/etc/dropbear/dropbear_rsa_host_key > /dev/null 2>&1 dropbearkey -t dss -f $rootfs/etc/dropbear/dropbear_dss_host_key > /dev/null 2>&1 echo "'dropbear' ssh utility installed" return 0 } install_openssh() { # tools to be installed server_utils="sshd" client_utils="\ ssh \ scp \ " client_optional_utils="\ sftp \ ssh-add \ ssh-agent \ ssh-keygen \ ssh-keyscan \ ssh-argv0 \ ssh-copy-id \ " # new folders used by ssh ssh_tree="\ $rootfs/etc/ssh \ $rootfs/var/empty/sshd \ $rootfs/var/lib/empty/sshd \ $rootfs/var/run/sshd \ " # create folder structure mkdir -p $ssh_tree if [ $? -ne 0 ]; then return 1 fi # copy binaries for bin in $server_utils $client_utils; do copy_binary $bin || return 1 done for bin in $client_optional_utils; do tool_path=`which $bin` && copy_binary $bin done # add user and group cat <> $rootfs/etc/passwd sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin EOF cat <> $rootfs/etc/group sshd:x:74: EOF # generate container keys ssh-keygen -t rsa -N "" -f $rootfs/etc/ssh/ssh_host_rsa_key >/dev/null 2>&1 ssh-keygen -t dsa -N "" -f $rootfs/etc/ssh/ssh_host_dsa_key >/dev/null 2>&1 # by default setup root password with no password cat < $rootfs/etc/ssh/sshd_config Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin yes StrictModes yes RSAAuthentication yes PubkeyAuthentication yes IgnoreRhosts yes RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords yes ChallengeResponseAuthentication no EOF echo "'OpenSSH' utility installed" return 0 } configure_busybox() { rootfs=$1 which busybox >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "busybox executable is not accessible" return 1 fi # copy busybox in the rootfs cp $(which busybox) $rootfs/bin if [ $? -ne 0 ]; then echo "failed to copy busybox in the rootfs" return 1 fi # symlink busybox for the commands it supports # it would be nice to just use "chroot $rootfs busybox --install -s /bin" # but that only works right in a chroot with busybox >= 1.19.0 pushd $rootfs/bin > /dev/null || return 1 ./busybox --help | grep 'Currently defined functions:' -A300 | \ grep -v 'Currently defined functions:' | tr , '\n' | \ xargs -n1 ln -s busybox popd > /dev/null # relink /sbin/init ln $rootfs/bin/busybox $rootfs/sbin/init # /etc/fstab must exist for "mount -a" touch $rootfs/etc/fstab # passwd exec must be setuid chmod +s $rootfs/bin/passwd touch $rootfs/etc/shadow # setting passwd for root CHPASSWD_FILE=$rootfs/root/chpasswd.sh cat <$CHPASSWD_FILE echo "setting root password to \"root\"" mount -n --bind /lib $rootfs/lib if [ \$? -ne 0 ]; then echo "Failed bind-mounting /lib at $rootfs/lib" exit 1 fi chroot $rootfs chpasswd </dev/null root:root EOFF if [ \$? -ne 0 ]; then echo "Failed to change root password" exit 1 fi umount $rootfs/lib EOF lxc-unshare -s MOUNT -- /bin/sh < $CHPASSWD_FILE rm $CHPASSWD_FILE return 0 } copy_configuration() { path=$1 rootfs=$2 name=$3 grep -q "^lxc.rootfs" $path/config 2>/dev/null || echo "lxc.rootfs = $rootfs" >> $path/config cat <> $path/config lxc.haltsignal = SIGUSR1 lxc.rebootsignal = SIGTERM lxc.utsname = $name lxc.tty = 1 lxc.pts = 1 lxc.cap.drop = sys_module mac_admin mac_override sys_time # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined lxc.mount.auto = cgroup:mixed proc:mixed sys:mixed lxc.mount.entry = shm /dev/shm tmpfs defaults 0 0 EOF libdirs="\ lib \ usr/lib \ lib64 \ usr/lib64" for dir in $libdirs; do if [ -d "/$dir" ] && [ -d "$rootfs/$dir" ]; then echo "lxc.mount.entry = /$dir $dir none ro,bind 0 0" >> $path/config fi done echo "lxc.mount.entry = /sys/kernel/security sys/kernel/security none ro,bind,optional 0 0" >>$path/config } 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 < -s|--ssh={dropbear,openssh} EOF return 0 } options=$(getopt -o hp:n:s: -l help,rootfs:,path:,name:,mapped-uid:,mapped-gid:,ssh: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; --mapped-uid) LXC_MAPPED_UID=$2; shift 2;; --mapped-gid) LXC_MAPPED_GID=$2; shift 2;; -s|--ssh) SSH=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi # detect rootfs config="$path/config" if [ -z "$rootfs" ]; then if grep -q '^lxc.rootfs' $config 2>/dev/null ; then rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $config) else rootfs=$path/rootfs fi fi install_busybox $rootfs $name if [ $? -ne 0 ]; then echo "failed to install busybox's rootfs" exit 1 fi configure_busybox $rootfs if [ $? -ne 0 ]; then echo "failed to configure busybox template" exit 1 fi 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 [ -n "$SSH" ]; then case "$SSH" in "dropbear") install_dropbear if [ $? -ne 0 ]; then echo "Unable to install 'dropbear' ssh utility" exit 1 fi ;; "openssh") install_openssh if [ $? -ne 0 ]; then echo "Unable to install 'OpenSSH' utility" exit 1 fi ;; *) echo "$SSH: unrecognized ssh utility" exit 1 esac else which dropbear >/dev/null 2>&1 if [ $? -eq 0 ]; then install_dropbear fi fi lxc-2.0.0/templates/lxc-alpine.in0000644061062106075000000003123612701247216013621 00000000000000#!/bin/sh # vim: set ts=4: # Exit on error and treat unset variables as an error. set -eu # # LXC template for Alpine Linux 3+ # # Note: Do not replace tabs with spaces, it would break heredocs! # Authors: # Jakub Jirutka # 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 # version 2.1 of the License, or (at your option) any later version. # # This library 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #=========================== Constants ============================# # Make sure the usual locations are in PATH export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin readonly LOCAL_STATE_DIR='@LOCALSTATEDIR@' readonly LXC_TEMPLATE_CONFIG='@LXCTEMPLATECONFIG@' readonly LXC_CACHE_DIR="${LXC_CACHE_PATH:-"$LOCAL_STATE_DIR/cache/lxc"}/alpine" # SHA256 checksums of GPG keys for APK. readonly APK_KEYS_SHA256="\ 9c102bcc376af1498d549b77bdbfa815ae86faa1d2d82f040e616b18ef2df2d4 alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub 2adcf7ce224f476330b5360ca5edb92fd0bf91c92d83292ed028d7c4e26333ab alpine-devel@lists.alpinelinux.org-4d07755e.rsa.pub ebf31683b56410ecc4c00acd9f6e2839e237a3b62b5ae7ef686705c7ba0396a9 alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub 1bb2a846c0ea4ca9d0e7862f970863857fc33c32f5506098c636a62a726a847b alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub 12f899e55a7691225603d6fb3324940fc51cd7f133e7ead788663c2b7eecb00c alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub" readonly APK_KEYS_URI='http://alpinelinux.org/keys' readonly MIRRORS_LIST_URL='http://rsync.alpinelinux.org/alpine/MIRRORS.txt' : ${APK_KEYS_DIR:=/etc/apk/keys} if ! ls "$APK_KEYS_DIR"/alpine* >/dev/null 2>&1; then APK_KEYS_DIR="$LXC_CACHE_DIR/bootstrap/keys" fi readonly APK_KEYS_DIR : ${APK:=$(command -v apk || true)} if [ ! -x "$APK" ]; then APK="$LXC_CACHE_DIR/bootstrap/sbin/apk.static" fi readonly APK #======================== Helper Functions ========================# usage() { cat <<-EOF Template specific options can be passed to lxc-create after a '--' like this: lxc-create --name=NAME [lxc-create-options] -- [template-options] [PKG...] PKG Additional APK package(s) to install into the container. Template options: -a ARCH, --arch=ARCH The container architecture (e.g. x86, x86_64); defaults to the host arch. -d, --debug Run this script in a debug mode (set -x and wget w/o -q). -F, --flush-cache Remove cached files before build. -m URL --mirror=URL The Alpine mirror to use; defaults to random mirror. -r VER, --release=VER The Alpine release branch to install; default is the latest stable. Environment variables: APK The apk-tools binary to use when building rootfs. If not set or not executable and apk is not on PATH, then the script will download the latest apk-tools-static. APK_KEYS_DIR Path to directory with GPG keys for APK. If not set and /etc/apk/keys does not contain alpine keys, then the script will download the keys from ${APK_KEYS_URI}. LXC_CACHE_PATH Path to the cache directory where to store bootstrap files and APK packages. EOF } die() { local retval=$1; shift printf 'ERROR: %s\n' "$@" 1>&2 exit $retval } einfo() { printf "\n==> $1\n" } fetch() { if [ "$DEBUG" = 'yes' ]; then wget -T 10 -O - $@ else wget -T 10 -O - -q $@ fi } latest_release_branch() { local arch="$1" local branch=$(fetch "$MIRROR_URL/latest-stable/releases/$arch/latest-releases.yaml" \ | sed -En 's/^[ \t]*branch: (.*)$/\1/p' \ | head -n 1) [ -n "$branch" ] && echo "$branch" } parse_arch() { case "$1" in x86 | i[3-6]86) echo 'x86';; x86_64 | amd64) echo 'x86_64';; arm*) echo 'armhf';; *) return 1;; esac } random_mirror_url() { local url=$(fetch "$MIRRORS_LIST_URL" | shuf -n 1) [ -n "$url" ] && echo "$url" } run_exclusively() { local lock_name="$1" local timeout=$2 shift 2 mkdir -p "$LOCAL_STATE_DIR/lock/subsys" local retval { echo -n "Obtaining an exclusive lock..." if ! flock -x 9; then echo ' failed.' return 1 fi echo ' done' "$@"; retval=$? } 9> "$LOCAL_STATE_DIR/lock/subsys/lxc-alpine-$lock_name" return $retval } #============================ Bootstrap ===========================# bootstrap() { if [ "$FLUSH_CACHE" = 'yes' ] && [ -d "$LXC_CACHE_DIR/bootstrap" ]; then einfo 'Cleaning cached bootstrap files' rm -Rf "$LXC_CACHE_DIR/bootstrap" fi einfo 'Fetching and/or verifying APK keys' fetch_apk_keys "$APK_KEYS_DIR" if [ ! -x "$APK" ]; then einfo 'Fetching apk-tools static binary' local host_arch=$(parse_arch $(uname -m)) fetch_apk_static "$LXC_CACHE_DIR/bootstrap" "$host_arch" fi } fetch_apk_keys() { local dest="$1" local line keyname mkdir -p "$dest" cd "$dest" echo "$APK_KEYS_SHA256" | while read -r line; do keyname="${line##* }" if [ ! -f "$keyname" ]; then fetch "$APK_KEYS_URI/$keyname" > "$keyname" fi echo "$line" | sha256sum -c - done || exit 2 cd - >/dev/null } fetch_apk_static() { local dest="$1" local arch="$2" local pkg_name='apk-tools-static' mkdir -p "$dest" local pkg_ver=$(fetch "$MIRROR_URL/latest-stable/main/$arch/APKINDEX.tar.gz" \ | tar -xzO APKINDEX \ | sed -n "/P:${pkg_name}/,/^$/ s/V:\(.*\)$/\1/p") [ -n "$pkg_ver" ] || die 2 "Cannot find a version of $pkg_name in APKINDEX" fetch "$MIRROR_URL/latest-stable/main/$arch/${pkg_name}-${pkg_ver}.apk" \ | tar -xz -C "$dest" sbin/ # --extract --gzip --directory [ -f "$dest/sbin/apk.static" ] || die 2 'apk.static not found' local keyname=$(echo "$dest"/sbin/apk.static.*.pub | sed 's/.*\.SIGN\.RSA\.//') openssl dgst -sha1 \ -verify "$APK_KEYS_DIR/$keyname" \ -signature "$dest/sbin/apk.static.SIGN.RSA.$keyname" \ "$dest/sbin/apk.static" \ || die 2 'Signature verification for apk.static failed' # Note: apk doesn't return 0 for --version local out="$("$dest"/sbin/apk.static --version)" echo "$out" [ "${out%% *}" = 'apk-tools' ] || die 3 'apk.static --version failed' } #============================ Install ============================# install() { local dest="$1" local arch="$2" local branch="$3" local extra_packages="$4" local apk_cache="$LXC_CACHE_DIR/apk/$arch" local repo_url="$MIRROR_URL/$branch/main" if [ "$FLUSH_CACHE" = 'yes' ] && [ -d "$apk_cache" ]; then einfo "Cleaning cached APK packages for $arch" rm -Rf "$apk_cache" fi mkdir -p "$apk_cache" einfo "Installing Alpine Linux in $dest" cd "$dest" mkdir -p etc/apk ln -s "$apk_cache" etc/apk/cache echo "$repo_url" > etc/apk/repositories install_packages "$arch" alpine-base $extra_packages make_dev_nodes setup_inittab setup_hosts setup_network setup_services chroot . /bin/true \ || die 3 'Failed to execute /bin/true in chroot, the builded rootfs is broken!' rm etc/apk/cache cd - >/dev/null } install_packages() { local arch="$1"; shift local packages="$@" $APK --arch="$arch" --root=. --keys-dir="$APK_KEYS_DIR" \ --update-cache --initdb add $packages } make_dev_nodes() { mkdir -p -m 755 dev/pts mkdir -p -m 1777 dev/shm mknod -m 666 dev/zero c 1 5 mknod -m 666 dev/full c 1 7 mknod -m 666 dev/random c 1 8 mknod -m 666 dev/urandom c 1 9 local i; for i in $(seq 0 4); do mknod -m 620 dev/tty$i c 4 $i chown 0:5 dev/tty$i # root:tty done mknod -m 666 dev/tty c 5 0 chown 0:5 dev/tty # root:tty mknod -m 620 dev/console c 5 1 mknod -m 666 dev/ptmx c 5 2 chown 0:5 dev/ptmx # root:tty } setup_inittab() { # Remove unwanted ttys. sed -i '/^tty[5-9]\:\:.*$/d' etc/inittab cat <<-EOF >> etc/inittab # Main LXC console console ::respawn:/sbin/getty 38400 console EOF } setup_hosts() { # This runscript injects localhost entries with the current hostname # into /etc/hosts. cat <<'EOF' > etc/init.d/hosts #!/sbin/openrc-run start() { local start_tag='# begin generated' local end_tag='# end generated' local content=$( cat <<-EOF $start_tag by /etc/init.d/hosts 127.0.0.1 $(hostname).local $(hostname) localhost ::1 $(hostname).local $(hostname) localhost $end_tag EOF ) if grep -q "^${start_tag}" /etc/hosts; then # escape \n, busybox sed doesn't like them content=${content//$'\n'/\\$'\n'} sed -ni "/^${start_tag}/ { a\\${content} # read and discard next line and repeat until $end_tag or EOF :a; n; /^${end_tag}/!ba; n }; p" /etc/hosts else printf "$content" >> /etc/hosts fi } EOF chmod +x etc/init.d/hosts # Wipe it, will be generated by the above runscript. echo -n > etc/hosts } setup_network() { # Note: loopback is automatically started by LXC. cat <<-EOF > etc/network/interfaces auto eth0 iface eth0 inet dhcp EOF } setup_services() { local svc_name # Specify the LXC subsystem. sed -i 's/^#*rc_sys=.*/rc_sys="lxc"/' etc/rc.conf # boot runlevel for svc_name in bootmisc hosts syslog; do ln -s /etc/init.d/$svc_name etc/runlevels/boot/$svc_name done # default runlevel for svc_name in networking cron; do ln -s /etc/init.d/$svc_name etc/runlevels/default/$svc_name done } #=========================== Configure ===========================# configure_container() { local config="$1" local hostname="$2" local arch="$3" cat <<-EOF >> "$config" # Specify container architecture. lxc.arch = $arch # Set hostname. lxc.utsname = $hostname # If something doesn't work, try to comment this out. # Dropping sys_admin disables container root from doing a lot of things # that could be bad like re-mounting lxc fstab entries rw for example, # but also disables some useful things like being able to nfs mount, and # things that are already namespaced with ns_capable() kernel checks, like # hostname(1). lxc.cap.drop = sys_admin # Include common configuration. lxc.include = $LXC_TEMPLATE_CONFIG/alpine.common.conf EOF } #============================= Main ==============================# if [ "$(id -u)" != "0" ]; then die 1 "This script must be run as 'root'" fi # Parse command options. options=$(getopt -o a:dFm:n:p:r:h -l arch:,debug,flush-cache,mirror:,name:,\ path:,release:,rootfs:,help,mapped-uid:,mapped-gid: -- "$@") eval set -- "$options" # Clean variables and set defaults. arch="$(uname -m)" debug='no' flush_cache='no' mirror_url= name= path= release= rootfs= # Process command options. while [ $# -gt 0 ]; do case $1 in -a | --arch) arch=$2; shift 2 ;; -d | --debug) debug='yes'; shift 1 ;; -F | --flush-cache) flush_cache='yes'; shift 1 ;; -m | --mirror) mirror_url=$2; shift 2 ;; -n | --name) name=$2; shift 2 ;; -p | --path) path=$2; shift 2 ;; -r | --release) release=$2; shift 2 ;; --rootfs) rootfs=$2; shift 2 ;; -h | --help) usage; exit 0 ;; --) shift; break ;; --mapped-[ug]id) die 1 "This template can't be used for unprivileged containers." \ 'You may want to try the "download" template instead.' ;; *) echo "Unknown option: $1" 1>&2 usage; exit 1 ;; esac done extra_packages="$@" [ "$debug" = 'yes' ] && set -x # Set global variables. readonly DEBUG="$debug" readonly FLUSH_CACHE="$flush_cache" readonly MIRROR_URL="${mirror_url:-$(random_mirror_url)}" # Validate options. [ -n "$name" ] || die 1 'Missing required option --name' [ -n "$path" ] || die 1 'Missing required option --path' if [ -z "$rootfs" ] && [ -f "$path/config" ]; then rootfs="$(sed -nE 's/^lxc.rootfs\s*=\s*(.*)$/\1/p' "$path/config")" fi if [ -z "$rootfs" ]; then rootfs="$path/rootfs" fi arch=$(parse_arch "$arch") \ || die 1 "Unsupported architecture: $arch" if [ -z "$release" ]; then release=$(latest_release_branch "$arch") \ || die 2 'Failed to resolve Alpine last release branch' fi # Here we go! run_exclusively 'bootstrap' 10 bootstrap run_exclusively "$arch" 30 install "$rootfs" "$arch" "$release" "$extra_packages" configure_container "$path/config" "$name" "$arch" einfo "Container's rootfs and config have been created" cat <<-EOF Edit the config file $path/config to check/enable networking setup. The installed system is preconfigured for a loopback and single network interface configured via DHCP. To start the container, run "lxc-start -n $name". The root password is not set; to enter the container run "lxc-attach -n $name". EOF lxc-2.0.0/templates/lxc-centos.in0000644061062106075000000007132612701247216013650 00000000000000#!/bin/bash # # template script for generating centos container for LXC # # lxc: linux Container library # Authors: # Daniel Lezcano # Ramez Hanna # Fajar A. Nugraha # Michael H. Warfield # 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 # version 2.1 of the License, or (at your option) any later version. # This library 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 # Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #Configurations default_path=@LXCPATH@ # Some combinations of the tuning knobs below do not exactly make sense. # but that's ok. # # If the "root_password" is non-blank, use it, else set a default. # This can be passed to the script as an environment variable and is # set by a shell conditional assignment. Looks weird but it is what it is. # # If the root password contains a ding ($) then try to expand it. # That will pick up things like ${name} and ${RANDOM}. # If the root password contains more than 3 consecutive X's, pass it as # a template to mktemp and take the result. # # If root_display_password = yes, display the temporary root password at exit. # If root_store_password = yes, store it in the configuration directory # If root_prompt_password = yes, invoke "passwd" to force the user to change # the root password after the container is created. # If root_expire_password = yes, you will be prompted to change the root # password at the first login. # # These are conditional assignments... The can be overridden from the # preexisting environment variables... # # Make sure this is in single quotes to defer expansion to later! # :{root_password='Root-${name}-${RANDOM}'} : ${root_password='Root-${name}-XXXXXX'} # Now, it doesn't make much sense to display, store, and force change # together. But, we gotta test, right??? : ${root_display_password='no'} : ${root_store_password='yes'} # Prompting for something interactive has potential for mayhem # with users running under the API... Don't default to "yes" : ${root_prompt_password='no'} # Expire root password? Default to yes, but can be overridden from # the environment variable : ${root_expire_password='yes'} # These are only going into comments in the resulting config... lxc_network_type=veth lxc_network_link=lxcbr0 # is this centos? # Alow for weird remixes like the Raspberry Pi # # Use the Mitre standard CPE identifier for the release ID if possible... # This may be in /etc/os-release or /etc/system-release-cpe. We # should be able to use EITHER. Give preference to /etc/os-release for now. # 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 if [ -e /etc/os-release ] then # This is a shell friendly configuration file. We can just source it. # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME . /etc/os-release echo "Host CPE ID from /etc/os-release: ${CPE_NAME}" fi if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ] then CPE_NAME=$(head -n1 /etc/system-release-cpe) CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)') if [ "${CPE_URI}" != "cpe:/o" ] then CPE_NAME= else # Probably a better way to do this but sill remain posix # compatible but this works, shrug... # Must be nice and not introduce convenient bashisms here. # # According to the official registration at Mitre and NIST, # this should have been something like this for CentOS: # cpe:/o:centos:centos:6 # or this: # cpe:/o:centos:centos:6.5 # ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)') # The "enterprise_linux" is a bone toss back to RHEL. # Since CentOS and RHEL are so tightly coupled, we'll # take the RHEL version if we're running on it and do the # equivalent version for CentOS. if [ ${ID} = "linux" -o ${ID} = "enterprise_linux" ] then # Instead we got this: cpe:/o:centos:linux:6 ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:\([^:]*\)') fi VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)') echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}" fi fi if [ "${CPE_NAME}" != "" -a "${ID}" = "centos" -a "${VERSION_ID}" != "" ] then centos_host_ver=${VERSION_ID} is_centos=true elif [ "${CPE_NAME}" != "" -a "${ID}" = "redhat" -a "${VERSION_ID}" != "" ] then redhat_host_ver=${VERSION_ID} is_redhat=true elif [ -e /etc/centos-release ] then # Only if all other methods fail, try to parse the redhat-release file. centos_host_ver=$( sed -e '/^CentOS /!d' -e 's/CentOS.*\srelease\s*\([0-9][0-9.]*\)\s.*/\1/' < /etc/centos-release ) if [ "$centos_host_ver" != "" ] then is_centos=true fi fi force_mknod() { # delete a device node if exists, and create a new one rm -f $2 && mknod -m $1 $2 $3 $4 $5 } configure_centos() { # disable selinux in centos mkdir -p $rootfs_path/selinux echo 0 > $rootfs_path/selinux/enforce # Also kill it in the /etc/selinux/config file if it's there... if [ -f $rootfs_path/etc/selinux/config ] then sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config fi # Nice catch from Dwight Engen in the Oracle template. # Wantonly plagerized here with much appreciation. if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled fi # This is a known problem and documented in RedHat bugzilla as relating # to a problem with auditing enabled. This prevents an error in # the container "Cannot make/remove an entry for the specified session" sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd if [ -f ${rootfs_path}/etc/pam.d/crond ] then sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond fi # In addition to disabling pam_loginuid in the above config files # we'll also disable it by linking it to pam_permit to catch any # we missed or any that get installed after the container is built. # # Catch either or both 32 and 64 bit archs. if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ] then ( cd ${rootfs_path}/lib/security/ mv pam_loginuid.so pam_loginuid.so.disabled ln -s pam_permit.so pam_loginuid.so ) fi if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ] then ( cd ${rootfs_path}/lib64/security/ mv pam_loginuid.so pam_loginuid.so.disabled ln -s pam_permit.so pam_loginuid.so ) fi # Set default localtime to the host localtime if not set... if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ] then # if /etc/localtime is a symlink, this should preserve it. cp -a /etc/localtime ${rootfs_path}/etc/localtime fi # Deal with some dain bramage in the /etc/init.d/halt script. # Trim it and make it our own and link it in before the default # halt script so we can intercept it. This also preventions package # updates from interferring with our interferring with it. # # There's generally not much in the halt script that useful but what's # in there from resetting the hardware clock down is generally very bad. # So we just eliminate the whole bottom half of that script in making # ourselves a copy. That way a major update to the init scripts won't # trash what we've set up. if [ -f ${rootfs_path}/etc/init.d/halt ] then sed -e '/hwclock/,$d' \ < ${rootfs_path}/etc/init.d/halt \ > ${rootfs_path}/etc/init.d/lxc-halt echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt chmod 755 ${rootfs_path}/etc/init.d/lxc-halt # Link them into the rc directories... ( cd ${rootfs_path}/etc/rc.d/rc0.d ln -s ../init.d/lxc-halt S00lxc-halt cd ${rootfs_path}/etc/rc.d/rc6.d ln -s ../init.d/lxc-halt S00lxc-reboot ) fi # configure the network using the dhcp cat < ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes HOSTNAME=${utsname} NM_CONTROLLED=no TYPE=Ethernet MTU=${MTU} DHCP_HOSTNAME=\`hostname\` EOF # set the hostname cat < ${rootfs_path}/etc/sysconfig/network NETWORKING=yes HOSTNAME=${utsname} EOF # set minimal hosts cat < $rootfs_path/etc/hosts 127.0.0.1 localhost $name EOF # set minimal fstab cat < $rootfs_path/etc/fstab /dev/root / rootfs defaults 0 0 EOF # create lxc compatibility init script if [ "$release" = "6" ]; then cat < $rootfs_path/etc/init/lxc-sysinit.conf start on startup env container pre-start script if [ "x\$container" != "xlxc" -a "x\$container" != "xlibvirt" ]; then stop; fi rm -f /var/lock/subsys/* rm -f /var/run/*.pid [ -e /etc/mtab ] || ln -s /proc/mounts /etc/mtab mkdir -p /dev/shm mount -t tmpfs -o nosuid,nodev tmpfs /dev/shm initctl start tty TTY=console telinit 3 exit 0 end script EOF elif [ "$release" = "5" ]; then cat < $rootfs_path/etc/rc.d/lxc.sysinit #! /bin/bash rm -f /etc/mtab /var/run/*.{pid,lock} /var/lock/subsys/* rm -rf {/,/var}/tmp/* echo "/dev/root / rootfs defaults 0 0" > /etc/mtab exit 0 EOF chmod 755 $rootfs_path/etc/rc.d/lxc.sysinit sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|' $rootfs_path/etc/inittab # prevent mingetty from calling vhangup(2) since it fails with userns. # Same issue as oracle template: prevent mingetty from calling vhangup(2) # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589. sed -i 's|^1:|co:2345:respawn:/sbin/mingetty --nohangup console\n1:|' $rootfs_path/etc/inittab sed -i 's|^\([56]:\)|#\1|' $rootfs_path/etc/inittab fi dev_path="${rootfs_path}/dev" rm -rf $dev_path mkdir -p $dev_path mknod -m 666 ${dev_path}/null c 1 3 mknod -m 666 ${dev_path}/zero c 1 5 mknod -m 666 ${dev_path}/random c 1 8 mknod -m 666 ${dev_path}/urandom c 1 9 mkdir -m 755 ${dev_path}/pts mkdir -m 1777 ${dev_path}/shm mknod -m 666 ${dev_path}/tty c 5 0 mknod -m 666 ${dev_path}/tty0 c 4 0 mknod -m 666 ${dev_path}/tty1 c 4 1 mknod -m 666 ${dev_path}/tty2 c 4 2 mknod -m 666 ${dev_path}/tty3 c 4 3 mknod -m 666 ${dev_path}/tty4 c 4 4 mknod -m 600 ${dev_path}/console c 5 1 mknod -m 666 ${dev_path}/full c 1 7 mknod -m 600 ${dev_path}/initctl p mknod -m 666 ${dev_path}/ptmx c 5 2 # setup console and tty[1-4] for login. note that /dev/console and # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. # lxc will maintain these links and bind mount ptys over /dev/lxc/* # since lxc.devttydir is specified in the config. # allow root login on console, tty[1-4], and pts/0 for libvirt echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty echo "lxc/console" >>${rootfs_path}/etc/securetty echo "lxc/tty1" >>${rootfs_path}/etc/securetty echo "lxc/tty2" >>${rootfs_path}/etc/securetty echo "lxc/tty3" >>${rootfs_path}/etc/securetty echo "lxc/tty4" >>${rootfs_path}/etc/securetty echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty echo "pts/0" >>${rootfs_path}/etc/securetty # prevent mingetty from calling vhangup(2) since it fails with userns. # Same issue as oracle template: prevent mingetty from calling vhangup(2) # commit 2e83f7201c5d402478b9849f0a85c62d5b9f1589. sed -i 's|mingetty|mingetty --nohangup|' $rootfs_path/etc/init/tty.conf if [ ${root_display_password} = "yes" ] then echo "Setting root password to '$root_password'" fi if [ ${root_store_password} = "yes" ] then touch ${config_path}/tmp_root_pass chmod 600 ${config_path}/tmp_root_pass echo ${root_password} > ${config_path}/tmp_root_pass echo "Storing root password in '${config_path}/tmp_root_pass'" fi echo "root:$root_password" | chroot $rootfs_path chpasswd if [ ${root_expire_password} = "yes" ] then # Also set this password as expired to force the user to change it! chroot $rootfs_path passwd -e root fi # This will need to be enhanced for CentOS 7 when systemd # comes into play... /\/\|=mhw=|\/\/ return 0 } configure_centos_init() { sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit if [ "$release" = "6" ]; then chroot ${rootfs_path} chkconfig udev-post off fi chroot ${rootfs_path} chkconfig network on if [ -d ${rootfs_path}/etc/init ] then # This is to make upstart honor SIGPWR cat <${rootfs_path}/etc/init/power-status-changed.conf # power-status-changed - shutdown on SIGPWR # start on power-status-changed exec /sbin/shutdown -h now "SIGPWR received" EOF fi } download_centos() { # check the mini centos was not already downloaded INSTALL_ROOT=$cache/partial mkdir -p $INSTALL_ROOT if [ $? -ne 0 ]; then echo "Failed to create '$INSTALL_ROOT' directory" return 1 fi # download a mini centos into a cache echo "Downloading centos minimal ..." YUM0="yum --installroot $INSTALL_ROOT -y --nogpgcheck" if yum -h | grep -q 'releasever=RELEASEVER'; then YUM="$YUM0 --releasever=$release" else YUM="$YUM0" fi PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils" # use temporary repository definition REPO_FILE=$INSTALL_ROOT/etc/yum.repos.d/lxc-centos-temp.repo mkdir -p $(dirname $REPO_FILE) if [ -n "$repo" ]; then cat < $REPO_FILE [base] name=local repository baseurl="$repo" EOF else cat < $REPO_FILE [base] name=CentOS-$release - Base mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=os [updates] name=CentOS-$release - Updates mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=updates EOF fi # create minimal device nodes, needed for "yum install" and "yum update" process mkdir -p $INSTALL_ROOT/dev force_mknod 666 $INSTALL_ROOT/dev/null c 1 3 force_mknod 666 $INSTALL_ROOT/dev/urandom c 1 9 $YUM install $PKG_LIST if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi # use same nameservers as hosts, needed for "yum update later" cp /etc/resolv.conf $INSTALL_ROOT/etc/ # check whether rpmdb is under $HOME if [ ! -e $INSTALL_ROOT/var/lib/rpm/Packages -a -e $INSTALL_ROOT/$HOME/.rpmdb/Packages ]; then echo "Fixing rpmdb location ..." mv $INSTALL_ROOT/$HOME/.rpmdb/[A-Z]* $INSTALL_ROOT/var/lib/rpm/ rm -rf $INSTALL_ROOT/$HOME/.rpmdb chroot $INSTALL_ROOT rpm --rebuilddb 2>/dev/null fi # check whether rpmdb version is correct chroot $INSTALL_ROOT rpm --quiet -q yum 2>/dev/null ret=$? # if "rpm -q" doesn't work due to rpmdb version difference, # then we need to redo the process using the newly-installed yum if [ $ret -gt 0 ]; then echo "Reinstalling packages ..." mv $REPO_FILE $REPO_FILE.tmp mkdir $INSTALL_ROOT/etc/yum.repos.disabled mv $INSTALL_ROOT/etc/yum.repos.d/*.repo $INSTALL_ROOT/etc/yum.repos.disabled/ mv $REPO_FILE.tmp $REPO_FILE mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/etc cp /etc/resolv.conf $INSTALL_ROOT/$INSTALL_ROOT/etc/ mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/dev mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/null c 1 3 mknod -m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev/urandom c 1 9 mkdir -p $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum cp -al $INSTALL_ROOT/var/cache/yum/* $INSTALL_ROOT/$INSTALL_ROOT/var/cache/yum/ chroot $INSTALL_ROOT $YUM0 install $PKG_LIST if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv $INSTALL_ROOT/$INSTALL_ROOT $INSTALL_ROOT.tmp rm -rf $INSTALL_ROOT mv $INSTALL_ROOT.tmp $INSTALL_ROOT fi rm -f $REPO_FILE rm -rf $INSTALL_ROOT/var/cache/yum/* mv "$INSTALL_ROOT" "$cache/rootfs" echo "Download complete." return 0 } copy_centos() { # make a local copy of the mini centos echo -n "Copying rootfs to $rootfs_path ..." #cp -a $cache/rootfs-$arch $rootfs_path || return 1 # i prefer rsync (no reason really) mkdir -p $rootfs_path rsync -a $cache/rootfs/ $rootfs_path/ echo return 0 } update_centos() { YUM="chroot $cache/rootfs yum -y --nogpgcheck" $YUM update if [ $? -ne 0 ]; then return 1 fi $YUM clean packages } install_centos() { mkdir -p /var/lock/subsys/ ( flock -x 9 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi echo "Checking cache download in $cache/rootfs ... " if [ ! -e "$cache/rootfs" ]; then download_centos if [ $? -ne 0 ]; then echo "Failed to download 'centos base'" return 1 fi else echo "Cache found. Updating..." update_centos if [ $? -ne 0 ]; then echo "Failed to update 'centos base', continuing with last known good cache" else echo "Update finished" fi fi echo "Copy $cache/rootfs to $rootfs_path ... " copy_centos if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 9>/var/lock/subsys/lxc-centos return $? } create_hwaddr() { openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' } copy_configuration() { mkdir -p $config_path grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo " lxc.rootfs = $rootfs_path " >> $config_path/config # The following code is to create static MAC addresses for each # interface in the container. This code will work for multiple # interfaces in the default config. mv $config_path/config $config_path/config.def while read LINE do # This should catch variable expansions from the default config... if expr "${LINE}" : '.*\$' > /dev/null 2>&1 then LINE=$(eval "echo \"${LINE}\"") fi # There is a tab and a space in the regex bracket below! # Seems that \s doesn't work in brackets. KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=') if [[ "${KEY}" != "lxc.network.hwaddr" ]] then echo ${LINE} >> $config_path/config if [[ "${KEY}" == "lxc.network.link" ]] then echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config fi fi done < $config_path/config.def rm -f $config_path/config.def if [ -e "@LXCTEMPLATECONFIG@/centos.common.conf" ]; then echo " # Include common configuration lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf " >> $config_path/config fi # Append things which require expansion here... cat <> $config_path/config lxc.arch = $arch lxc.utsname = $utsname # When using LXC with apparmor, uncomment the next line to run unconfined: #lxc.aa_profile = unconfined # example simple networking setup, uncomment to enable #lxc.network.type = $lxc_network_type #lxc.network.flags = up #lxc.network.link = $lxc_network_link #lxc.network.name = eth0 # Additional example for veth network type # static MAC address, #lxc.network.hwaddr = 00:16:3e:77:52:20 # persistent veth device name on host side # Note: This may potentially collide with other containers of same name! #lxc.network.veth.pair = v-$name-e0 EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } clean() { if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -x 9 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache for centos-$release..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-centos } usage() { cat < [-p|--path=] [-c|--clean] [-R|--release=] [-a|--arch=] [-h|--help] Mandatory args: -n,--name container name, used to as an identifier for that container from now on Optional args: -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc/name. -c,--clean clean the cache -R,--release Centos release for the new container. if the host is Centos, then it will defaultto the host's release. --fqdn fully qualified domain name (FQDN) for DNS and system naming --repo repository to use (url) -a,--arch Define what arch the container will be [i686,x86_64] -h,--help print this help EOF return 0 } options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn: -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi arch=$(uname -m) eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; --rootfs) rootfs_path=$2; shift 2;; -n|--name) name=$2; shift 2;; -c|--clean) clean=1; shift 1;; -R|--release) release=$2; shift 2;; --repo) repo="$2"; shift 2;; -a|--arch) newarch=$2; shift 2;; --fqdn) utsname=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi basearch=${arch} # Map a few architectures to their generic CentOS repository archs. # The two ARM archs are a bit of a guesstimate for the v5 and v6 # archs. V6 should have hardware floating point (Rasberry Pi). # The "arm" arch is safer (no hardware floating point). So # there may be cases where we "get it wrong" for some v6 other # than RPi. case "$arch" in i686) basearch=i386 ;; armv3l|armv4l|armv5l) basearch=arm ;; armv6l|armv7l|armv8l) basearch=armhfp ;; *) ;; esac # Somebody wants to specify an arch. This is very limited case. # i386/i586/i686 on i386/x86_64 # - or - # x86_64 on x86_64 if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ] then case "${newarch}" in i386|i586|i686) if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ] then # Make the arch a generic x86 32 bit... arch=${newarch} basearch=i386 else basearch=bad fi ;; *) basearch=bad ;; esac if [ "${basearch}" = "bad" ] then echo "You cannot build a ${newarch} CentOS container on a ${arch} host. Sorry!" exit 1 fi fi # Allow the cache base to be set by environment variable cache_base=${LXC_CACHE_PATH:-"@LOCALSTATEDIR@/cache/lxc"}/centos/$basearch # Let's do something better for the initial root password. # It's not perfect but it will defeat common scanning brute force # attacks in the case where ssh is exposed. It will also be set to # expired, forcing the user to change it at first login. if [ "${root_password}" = "" ] then root_password=Root-${name}-${RANDOM} else # If it's got a ding in it, try and expand it! if [ $(expr "${root_password}" : '.*$.') != 0 ] then root_password=$(eval echo "${root_password}") fi # If it has more than 3 consecutive X's in it, feed it # through mktemp as a template. if [ $(expr "${root_password}" : '.*XXXX') != 0 ] then root_password=$(mktemp -u ${root_password}) fi fi if [ -z "${utsname}" ]; then utsname=${name} fi # This follows a standard "resolver" convention that an FQDN must have # at least two dots or it is considered a local relative host name. # If it doesn't, append the dns domain name of the host system. # # This changes one significant behavior when running # "lxc_create -n Container_Name" without using the # --fqdn option. # # Old behavior: # utsname and hostname = Container_Name # New behavior: # utsname and hostname = Container_Name.Domain_Name if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then utsname=${utsname}.$(dnsdomainname) fi fi type yum >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "'yum' command is missing" exit 1 fi if [ -z "$path" ]; then path=$default_path/$name fi if [ -z "$release" ]; then if [ "$is_centos" -a "$centos_host_ver" ]; then release=$centos_host_ver elif [ "$is_redhat" -a "$redhat_host_ver" ]; then # This is needed to clean out bullshit like 6workstation and 6server. release=$(expr $redhat_host_ver : '\([0-9.]*\)') else echo "This is not a CentOS or Redhat host and release is missing, defaulting to 6 use -R|--release to specify release" release=6 fi fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi if [ -z "$rootfs_path" ]; then rootfs_path=$path/rootfs # check for 'lxc.rootfs' passed in through default config by lxc-create if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then rootfs_path=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \ -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config) fi fi config_path=$path cache=$cache_base/$release revert() { echo "Interrupted, so cleaning up" lxc-destroy -n $name # maybe was interrupted before copy config rm -rf $path echo "exiting..." exit 1 } trap revert SIGHUP SIGINT SIGTERM copy_configuration if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi install_centos if [ $? -ne 0 ]; then echo "failed to install centos" exit 1 fi configure_centos if [ $? -ne 0 ]; then echo "failed to configure centos for a container" exit 1 fi configure_centos_init if [ ! -z "$clean" ]; then clean || exit 1 exit 0 fi echo " Container rootfs and config have been created. Edit the config file to check/enable networking setup. " if [ ${root_display_password} = "yes" ] then echo "The temporary password for root is: '$root_password' You may want to note that password down before starting the container. " fi if [ ${root_store_password} = "yes" ] then echo "The temporary root password is stored in: '${config_path}/tmp_root_pass' " fi if [ ${root_prompt_password} = "yes" ] then echo "Invoking the passwd command in the container to set the root password. chroot ${rootfs_path} passwd " chroot ${rootfs_path} passwd else if [ ${root_expire_password} = "yes" ] then if ( mountpoint -q -- "${rootfs_path}" ) then echo "To reset the root password, you can do: lxc-start -n ${name} lxc-attach -n ${name} -- passwd lxc-stop -n ${name} " else echo " The root password is set up as "expired" and will require it to be changed at first login, which you should do as soon as possible. If you lose the root password or wish to change it without starting the container, you can change it from the host by running the following command (which will also reset the expired flag): chroot ${rootfs_path} passwd " fi fi fi lxc-2.0.0/doc/0000755061062106075000000000000012701247243010057 500000000000000lxc-2.0.0/doc/lxc-usernsexec.sgml.in0000644061062106075000000001025212701247216014240 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-usernsexec 1 lxc-usernsexec Run a task as root in a new user namespace. lxc-usernsexec -m uid-map -- command Description lxc-usernsexec can be used to run a task as root in a new user namespace. Options The uid map to use in the user namespace. Each map consists of four colon-separate values. First a character 'u', 'g' or 'b' to specify whether this map pertains to user ids, group ids, or both; next the first userid in the user namespace; next the first userid as seen on the host; and finally the number of ids to be mapped. More than one map can be specified. If no map is specified, then by default the full uid and gid ranges granted by /etc/subuid and /etc/subgid will be mapped to the uids and gids starting at 0 in the container. Note that lxc-usernsexec always tries to setuid and setgid to 0 in the namespace. Therefore uid 0 in the namespace must be mapped. Examples To spawn a shell with the full allotted subuids mapped into the container, use lxc-usernsexec To run a different shell than /bin/sh, use lxc-usernsexec -- /bin/bash If your user id is 1000, root in a container is mapped to 190000, and you wish to chown a file you own to root in the container, you can use: lxc-usernsexec -m b:0:1000:1 -m b:1:190000:1 -- /bin/chown 1:1 $file This maps your userid to root in the user namespace, and 190000 to uid 1. Since root in the user namespace is privileged over all userids mapped into the namespace, you are allowed to change the file ownership, which you could not do on the host using a simple chown. &seealso; Author Serge Hallyn serge.hallyn@ubuntu.com lxc-2.0.0/doc/FAQ.txt0000644061062106075000000000300612701247216011146 00000000000000 Troubleshooting: =============== Error: ------ error while loading shared libraries reported after sudo make install and when trying to run lxc-execute. "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash" /usr/local/bin/lxc-execute: error while loading shared libraries: liblxc-0.5.0.so: cannot open shared object file: No such file or directory Answer: ------- update the ld cache by running ldconfig. Error: ------ error when starting a container. "lxc-start Invalid argument" "lxc-execute -n foo -f /usr/local/etc/lxc/lxc-macvlan.conf /bin/bash" "[syserr] lxc_start:96: Invalid argument - failed to fork into a new namespace" Answer: ------- read the lxc man page about kernel version prereq :) most probably your kernel is not configured to support the container options you want to use. Error: ------ On Ubuntu 8.10, if using the cvs source code rather than the provided tarball. Then make is failing with many errors similar to the line below: ========== ../../libtool: line 810: X--tag=CC: command not found ========== Answer: ------- This is related to a compatibility problem between the shipped config/ltmain.sh and the libtool version installed on your Ubuntu 8.10 machine. You have to replace the config/ltmain.sh from cvs head by the one from your libtool package, make some cleaning and reissue all the build process: ========== cd cp -f /usr/share/libtool/config/ltmain.sh config/ rm -f libtool ./bootstrap && ./configure && make && sudo make install ========== lxc-2.0.0/doc/lxc-checkconfig.sgml.in0000644061062106075000000000445012701247216014322 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-checkconfig 1 lxc-checkconfig check the current kernel for lxc support lxc-checkconfig Description lxc-checkconfig check the current kernel for lxc support Examples lxc-checkconfig check the current kernel. CONFIG can be set in the environment to an alternate location. &seealso; Author Stéphane Graber stgraber@ubuntu.com lxc-2.0.0/doc/lxc-device.sgml.in0000644061062106075000000001007412701247216013315 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-device 1 lxc-device manage devices of running containers lxc-device -h -n name add DEVICE NAME Description lxc-device manages devices in running container. Options The full command help message. The name of the target container. What action to perform. Only 'add' is supported at this point. The device to add to the container. It can either be the path to a device under /dev or a network interface name. Name for the device within the container. Examples lxc-device -n p1 add /dev/video0 Creates a /dev/video0 device in container p1 based on the matching device on the host. lxc-device -n p1 add eth0 eth1 Moves eth0 from the host as eth1 in p1. &seealso; Author Stéphane Graber stgraber@ubuntu.com lxc-2.0.0/doc/lxc-clone.sgml.in0000644061062106075000000002170212701247216013156 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-clone 1 lxc-clone clone a new container from an existing one. lxc-clone -s -K -M -H -B backingstore -L fssize -p lxcpath -P newlxcpath -R -o orig -n new -- hook arguments lxc-clone -s -K -M -H -B backingstore -L fssize -p lxcpath -P newlxcpath -R orig new -- hook arguments Description lxc-clone Creates a new container as a clone of an existing container. Two types of clones are supported: copy and snapshot. A copy clone copies the root filessytem from the original container to the new. A snapshot filesystem uses the backing store's snapshot functionality to create a very small copy-on-write snapshot of the original container. Snapshot clones require the new container backing store to support snapshotting. Currently this includes only aufs, btrfs, lvm, overlayfs and zfs. LVM devices do not support snapshots of snapshots. The backing store of the new container will be the same type as the original container, with one exception, overlay containers. aufs and overlayfs snapshots can be created of directory backed containers. This can be requested by using (for overlayfs) the -B overlayfs arguments. The names of the original and new container can be given (in that order) after all options, or can be specified with the -o and -n options, respectively. Options The new container's rootfs will be a snapshot of the original. This option can be specified when the backing store is LVM, btrfs or zfs, and must be specified when you want to snapshot using aufs or overlayfs. Do not change the hostname of the container (in the root filesystem). Use the same MAC address as the original container, rather than generating a new random one. Copy all mount hooks into the new container's directory, and update any lxcpaths and container names as needed. In the case of a block device backed container, a size for the new block device. By default, the new device will be made the same size as the original. The lxcpath of the original container. By default, the system wide configured lxcpath will be used. The lxcpath for the new container. By default the same lxcpath as the original will be used. Note that with btrfs snapshots, changing lxcpaths may not be possible, as subvolume snapshots must be in the same btrfs filesystem. Select a different backing store for the new container. By default the same as the original container's is used. Note that currently changing the backingstore is only supported for aufs and overlayfs snapshots of directory backed containers. Valid backing stores include dir (directory), aufs, btrfs, lvm, zfs, loop and overlayfs. Rename an existing container. orig is renamed new. The name of the original container to clone. The name of the new container to create. Clone hook If the container being cloned has one or more lxc.hook.clone specified, then the specified hooks will be called for the new container. The first 3 arguments passed to the clone hook will be the container name, a section ('lxc'), and the hook type ('clone'). Extra arguments passed lxc-clone will be passed to the hook program starting at argument 4. The LXC_ROOTFS_MOUNT environment variable gives the path under which the container's root filesystem is mounted. The configuration file pathname is stored in LXC_CONFIG_FILE, the new container name in LXC_NAME, the old container name in LXC_SRC_NAME, and the path or device on which the rootfs is located is in LXC_ROOTFS_PATH. Notes lxc-clone is deprecated in favor of lxc-copy. &seealso; Author Serge Hallyn serge.hallyn@ubuntu.com lxc-2.0.0/doc/lxc-destroy.sgml.in0000644061062106075000000000652212701247216013552 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-destroy 1 lxc-destroy destroy a container. lxc-destroy -n name -f -s Description lxc-destroy destroys the system object previously created by the lxc-create command. Options If a container is running, stop it first. If this option is not specified and the container is running, then lxc-destroy will be aborted. destroy the specified container including all its snapshots. &commonoptions; Diagnostic The container was not found The specified container for destruction was not found. It is probable it does not exists and was already destroyed.You can use the lxc-ls command to list the available containers on the system. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/see_also.sgml.in0000644061062106075000000000613412701247216013066 00000000000000 See Also lxc 7 , lxc-create 1 , lxc-copy 1 , lxc-destroy 1 , lxc-start 1 , lxc-stop 1 , lxc-execute 1 , lxc-console 1 , lxc-monitor 1 , lxc-wait 1 , lxc-cgroup 1 , lxc-ls 1 , lxc-info 1 , lxc-freeze 1 , lxc-unfreeze 1 , lxc-attach 1 , lxc.conf 5 lxc-2.0.0/doc/lxc-top.sgml.in0000644061062106075000000001145612701247216012665 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-top 1 lxc-top monitor container statistics lxc-top --help --delay delay --sort sortby --reverse Description lxc-top displays container statistics. The output is updated every delay seconds, and is ordered according to the sortby value given. lxc-top will display as many containers as can fit in your terminal. Press 'q' to quit. Press one of the sort key letters to sort by that statistic. Pressing a sort key letter a second time reverses the sort order. Options Amount of time in seconds to delay between screen updates. The default is 3 seconds. Sort the containers by name, cpu use, or memory use. The sortby argument should be one of the letters n,c,b,m,k to sort by name, cpu use, block I/O, memory, or kernel memory use respectively. The default is 'n'. Reverse the default sort order. By default, names sort in ascending alphabetical order and values sort in descending amounts (ie. largest value first). Example lxc-top --delay 1 --sort m Display containers, updating every second, sorted by memory use. Notes For performance reasons the kernel does not account kernel memory use unless a kernel memory limit is set. If a limit is not set, lxc-top will display kernel memory use as 0. If no containers are being accounted, the KMem column will not be displayed. A limit can be set by specifying lxc.cgroup.memory.kmem.limit_in_bytes = number in your container configuration file, see lxc.conf 5 . &seealso; Author Dwight Engen dwight.engen@oracle.com lxc-2.0.0/doc/lxc-start.sgml.in0000644061062106075000000001720312701247216013214 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-start 1 lxc-start run an application inside a container. lxc-start -n name -f config_file -c console_device -L console_logfile -d -F -p pid_file -s KEY=VAL -C --share-[net|ipc|uts] name|pid command Description lxc-start runs the specified command inside the container specified by name. It will setup the container according to the configuration previously defined with the lxc-create command or with the configuration file parameter. If no configuration is defined, the default isolation is used. If no command is specified, lxc-start will use the command defined in lxc.init_cmd or if not set, the default "/sbin/init" command to run a system container. Options Run the container as a daemon. As the container has no more tty, if an error occurs nothing will be displayed, the log file can be used to check the error. (This is the default mode) Run the container in the foreground. In this mode, the container console will be attached to the current tty and signals will be routed directly to the container. Create a file with the process id. Specify the configuration file to configure the virtualization and isolation functionalities for the container. This configuration file if present will be used even if there is already a configuration file present in the previously created container (via lxc-create). Specify a device to use for the container's console, for example /dev/tty8. If this option is not specified the current terminal will be used unless is specified. Specify a file to log the container's console output to. Assign value VAL to configuration variable KEY. This overrides any assignment done in config_file. If any file descriptors are inherited, close them. If this option is not specified, then lxc-start will exit with failure instead. Note: --daemon implies --close-all-fds. Inherit a network namespace from a name container or a pid. The network namespace will continue to be managed by the original owner. The network configuration of the starting container is ignored and the up/down scripts won't be executed. Inherit an IPC namespace from a name container or a pid. Inherit a UTS namespace from a name container or a pid. The starting LXC will not set the hostname, but the container OS may do it anyway. &commonoptions; Diagnostic The container is busy The specified container is already running an application. You should stop it before reuse this container or create a new one. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/lxc.sgml.in0000644061062106075000000004267612701247216012075 00000000000000 ]> @LXC_GENERATE_DATE@ lxc 7 Version @PACKAGE_VERSION@ lxc linux containers Quick start You are in a hurry, and you don't want to read this man page. Ok, without warranty, here are the commands to launch a shell inside a container with a predefined configuration template, it may work. @BINDIR@/lxc-execute -n foo -f @DOCDIR@/examples/lxc-macvlan.conf /bin/bash Overview The container technology is actively being pushed into the mainstream linux kernel. It provides the resource management through the control groups aka process containers and resource isolation through the namespaces. The linux containers, lxc, aims to use these new functionalities to provide a userspace container object which provides full resource isolation and resource control for an applications or a system. The first objective of this project is to make the life easier for the kernel developers involved in the containers project and especially to continue working on the Checkpoint/Restart new features. The lxc is small enough to easily manage a container with simple command lines and complete enough to be used for other purposes. Requirements The lxc relies on a set of functionalities provided by the kernel which needs to be active. Depending of the missing functionalities the lxc will work with a restricted number of functionalities or will simply fail. The following list gives the kernel features to be enabled in the kernel to have the full features container: * General setup * Control Group support -> Namespace cgroup subsystem -> Freezer cgroup subsystem -> Cpuset support -> Simple CPU accounting cgroup subsystem -> Resource counters -> Memory resource controllers for Control Groups * Group CPU scheduler -> Basis for grouping tasks (Control Groups) * Namespaces support -> UTS namespace -> IPC namespace -> User namespace -> Pid namespace -> Network namespace * Device Drivers * Character devices -> Support multiple instances of devpts * Network device support -> MAC-VLAN support -> Virtual ethernet pair device * Networking * Networking options -> 802.1d Ethernet Bridging * Security options -> File POSIX Capabilities The kernel version >= 2.6.32 shipped with the distros, will work with lxc, this one will have less functionalities but enough to be interesting. The helper script lxc-checkconfig will give you information about your kernel configuration. The control group can be mounted anywhere, eg: mount -t cgroup cgroup /cgroup. It is however recommended to use cgmanager, cgroup-lite or systemd to mount the cgroup hierarchy under /sys/fs/cgroup. Functional specification A container is an object isolating some resources of the host, for the application or system running in it. The application / system will be launched inside a container specified by a configuration that is either initially created or passed as parameter of the starting commands. How to run an application in a container ? Before running an application, you should know what are the resources you want to isolate. The default configuration is to isolate the pids, the sysv ipc and the mount points. If you want to run a simple shell inside a container, a basic configuration is needed, especially if you want to share the rootfs. If you want to run an application like sshd, you should provide a new network stack and a new hostname. If you want to avoid conflicts with some files eg. /var/run/httpd.pid, you should remount /var/run with an empty directory. If you want to avoid the conflicts in all the cases, you can specify a rootfs for the container. The rootfs can be a directory tree, previously bind mounted with the initial rootfs, so you can still use your distro but with your own /etc and /home Here is an example of directory tree for sshd: [root@lxc sshd]$ tree -d rootfs rootfs |-- bin |-- dev | |-- pts | `-- shm | `-- network |-- etc | `-- ssh |-- lib |-- proc |-- root |-- sbin |-- sys |-- usr `-- var |-- empty | `-- sshd |-- lib | `-- empty | `-- sshd `-- run `-- sshd and the mount points file associated with it: [root@lxc sshd]$ cat fstab /lib /home/root/sshd/rootfs/lib none ro,bind 0 0 /bin /home/root/sshd/rootfs/bin none ro,bind 0 0 /usr /home/root/sshd/rootfs/usr none ro,bind 0 0 /sbin /home/root/sshd/rootfs/sbin none ro,bind 0 0 How to run a system in a container ? Running a system inside a container is paradoxically easier than running an application. Why ? Because you don't have to care about the resources to be isolated, everything need to be isolated, the other resources are specified as being isolated but without configuration because the container will set them up. eg. the ipv4 address will be setup by the system container init scripts. Here is an example of the mount points file: [root@lxc debian]$ cat fstab /dev /home/root/debian/rootfs/dev none bind 0 0 /dev/pts /home/root/debian/rootfs/dev/pts none bind 0 0 More information can be added to the container to facilitate the configuration. For example, make accessible from the container the resolv.conf file belonging to the host. /etc/resolv.conf /home/root/debian/rootfs/etc/resolv.conf none bind 0 0 Container life cycle When the container is created, it contains the configuration information. When a process is launched, the container will be starting and running. When the last process running inside the container exits, the container is stopped. In case of failure when the container is initialized, it will pass through the aborting state. Configuration The container is configured through a configuration file, the format of the configuration file is described in lxc.conf 5 Creating / Destroying container (persistent container) A persistent container object can be created via the lxc-create command. It takes a container name as parameter and optional configuration file and template. The name is used by the different commands to refer to this container. The lxc-destroy command will destroy the container object. lxc-create -n foo lxc-destroy -n foo Volatile container It is not mandatory to create a container object before to start it. The container can be directly started with a configuration file as parameter. Starting / Stopping container When the container has been created, it is ready to run an application / system. This is the purpose of the lxc-execute and lxc-start commands. If the container was not created before starting the application, the container will use the configuration file passed as parameter to the command, and if there is no such parameter either, then it will use a default isolation. If the application is ended, the container will be stopped also, but if needed the lxc-stop command can be used to kill the still running application. Running an application inside a container is not exactly the same thing as running a system. For this reason, there are two different commands to run an application into a container: lxc-execute -n foo [-f config] /bin/bash lxc-start -n foo [-f config] [/bin/bash] lxc-execute command will run the specified command into the container via an intermediate process, lxc-init. This lxc-init after launching the specified command, will wait for its end and all other reparented processes. (to support daemons in the container). In other words, in the container, lxc-init has the pid 1 and the first process of the application has the pid 2. lxc-start command will run directly the specified command into the container. The pid of the first process is 1. If no command is specified lxc-start will run the command defined in lxc.init_cmd or if not set, /sbin/init . To summarize, lxc-execute is for running an application and lxc-start is better suited for running a system. If the application is no longer responding, is inaccessible or is not able to finish by itself, a wild lxc-stop command will kill all the processes in the container without pity. lxc-stop -n foo Connect to an available tty If the container is configured with the ttys, it is possible to access it through them. It is up to the container to provide a set of available tty to be used by the following command. When the tty is lost, it is possible to reconnect it without login again. lxc-console -n foo -t 3 Freeze / Unfreeze container Sometime, it is useful to stop all the processes belonging to a container, eg. for job scheduling. The commands: lxc-freeze -n foo will put all the processes in an uninteruptible state and lxc-unfreeze -n foo will resume them. This feature is enabled if the cgroup freezer is enabled in the kernel. Getting information about container When there are a lot of containers, it is hard to follow what has been created or destroyed, what is running or what are the pids running into a specific container. For this reason, the following commands may be useful: lxc-ls lxc-info -n foo lxc-ls lists the containers of the system. lxc-info gives information for a specific container. Here is an example on how the combination of these commands allows one to list all the containers and retrieve their state. for i in $(lxc-ls -1); do lxc-info -n $i done Monitoring container It is sometime useful to track the states of a container, for example to monitor it or just to wait for a specific state in a script. lxc-monitor command will monitor one or several containers. The parameter of this command accept a regular expression for example: lxc-monitor -n "foo|bar" will monitor the states of containers named 'foo' and 'bar', and: lxc-monitor -n ".*" will monitor all the containers. For a container 'foo' starting, doing some work and exiting, the output will be in the form: 'foo' changed state to [STARTING] 'foo' changed state to [RUNNING] 'foo' changed state to [STOPPING] 'foo' changed state to [STOPPED] lxc-wait command will wait for a specific state change and exit. This is useful for scripting to synchronize the launch of a container or the end. The parameter is an ORed combination of different states. The following example shows how to wait for a container if he went to the background. Setting the control group for container The container is tied with the control groups, when a container is started a control group is created and associated with it. The control group properties can be read and modified when the container is running by using the lxc-cgroup command. lxc-cgroup command is used to set or get a control group subsystem which is associated with a container. The subsystem name is handled by the user, the command won't do any syntax checking on the subsystem name, if the subsystem name does not exists, the command will fail. lxc-cgroup -n foo cpuset.cpus will display the content of this subsystem. lxc-cgroup -n foo cpu.shares 512 will set the subsystem to the specified value. Bugs The lxc is still in development, so the command syntax and the API can change. The version 1.0.0 will be the frozen version. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/examples/0000755061062106075000000000000012701247243011675 500000000000000lxc-2.0.0/doc/examples/lxc-phys.conf.in0000644061062106075000000000045412701247216014643 00000000000000# Container with network virtualized using a physical network device with name # 'eth0' lxc.utsname = gamma lxc.network.type = phys lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:ff lxc.network.ipv4 = 10.2.3.6/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 lxc-2.0.0/doc/examples/lxc-complex.conf.in0000644061062106075000000000127312701247216015327 00000000000000# Container with network a complex network mixing macvlan, veth and # physical network devices lxc.utsname = complex lxc.network.type = veth lxc.network.flags = up lxc.network.link = br0 lxc.network.hwaddr = 4a:49:43:49:79:bf lxc.network.ipv4 = 10.2.3.5/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 lxc.network.type = macvlan lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 lxc.network.type = phys lxc.network.flags = up lxc.network.link = dummy0 lxc.network.hwaddr = 4a:49:43:49:79:ff lxc.network.ipv4 = 10.2.3.6/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297 lxc-2.0.0/doc/examples/seccomp-v1.conf0000644061062106075000000000255212701247216014445 000000000000001 whitelist 0 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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 lxc-2.0.0/doc/examples/Makefile.am0000644061062106075000000000113212701247216013646 00000000000000if ENABLE_EXAMPLES pkgexamplesdir=$(docdir)/examples pkgexamples_DATA = \ lxc-macvlan.conf \ lxc-vlan.conf \ lxc-no-netns.conf \ lxc-empty-netns.conf \ lxc-phys.conf \ lxc-veth.conf \ lxc-complex.conf \ seccomp-v1.conf \ seccomp-v2-blacklist.conf \ seccomp-v2.conf endif noinst_DATA = \ lxc-macvlan.conf.in \ lxc-vlan.conf.in \ lxc-empty-netns.conf.in \ lxc-no-netns.conf.in \ lxc-phys.conf.in \ lxc-veth.conf.in \ lxc-complex.conf.in \ seccomp-v1.conf \ seccomp-v2-blacklist.conf \ seccomp-v2.conf EXTRA_DIST = \ seccomp-v1.conf \ seccomp-v2-blacklist.conf \ seccomp-v2.conf lxc-2.0.0/doc/examples/Makefile.in0000644061062106075000000004272612701247222013672 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/examples ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ $(top_srcdir)/config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = lxc-macvlan.conf lxc-vlan.conf lxc-no-netns.conf \ lxc-empty-netns.conf lxc-phys.conf lxc-veth.conf \ lxc-complex.conf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkgexamplesdir)" DATA = $(noinst_DATA) $(pkgexamples_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/lxc-complex.conf.in \ $(srcdir)/lxc-empty-netns.conf.in \ $(srcdir)/lxc-macvlan.conf.in $(srcdir)/lxc-no-netns.conf.in \ $(srcdir)/lxc-phys.conf.in $(srcdir)/lxc-veth.conf.in \ $(srcdir)/lxc-vlan.conf.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDIR = @BINDIR@ CAP_LIBS = @CAP_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CGMANAGER_CFLAGS = @CGMANAGER_CFLAGS@ CGMANAGER_LIBS = @CGMANAGER_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_CGROUP_PATTERN = @DEFAULT_CGROUP_PATTERN@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCDIR = @DOCDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ HAVE_DOXYGEN = @HAVE_DOXYGEN@ INCLUDEDIR = @INCLUDEDIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCALSTATEDIR = @LOCALSTATEDIR@ LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBDIR = @LUA_LIBDIR@ LUA_LIBS = @LUA_LIBS@ LUA_SHAREDIR = @LUA_SHAREDIR@ LUA_VERSION = @LUA_VERSION@ LXCBINHOOKDIR = @LXCBINHOOKDIR@ LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATECONFIG = @LXCTEMPLATECONFIG@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ LXC_DISTRO_SYSCONF = @LXC_DISTRO_SYSCONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ LXC_USERNIC_DB = @LXC_USERNIC_DB@ LXC_VERSION = @LXC_VERSION@ LXC_VERSION_ABI = @LXC_VERSION_ABI@ LXC_VERSION_BASE = @LXC_VERSION_BASE@ LXC_VERSION_BETA = @LXC_VERSION_BETA@ LXC_VERSION_MAJOR = @LXC_VERSION_MAJOR@ LXC_VERSION_MICRO = @LXC_VERSION_MICRO@ LXC_VERSION_MINOR = @LXC_VERSION_MINOR@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NIH_CFLAGS = @NIH_CFLAGS@ NIH_DBUS_CFLAGS = @NIH_DBUS_CFLAGS@ NIH_DBUS_LIBS = @NIH_DBUS_LIBS@ NIH_LIBS = @NIH_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ PYTHON = @PYTHON@ PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RUNTIME_PATH = @RUNTIME_PATH@ SBINDIR = @SBINDIR@ SECCOMP_CFLAGS = @SECCOMP_CFLAGS@ SECCOMP_LIBS = @SECCOMP_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ db2xman = @db2xman@ docdir = @docdir@ docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @ENABLE_EXAMPLES_TRUE@pkgexamplesdir = $(docdir)/examples @ENABLE_EXAMPLES_TRUE@pkgexamples_DATA = \ @ENABLE_EXAMPLES_TRUE@ lxc-macvlan.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-vlan.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-no-netns.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-empty-netns.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-phys.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-veth.conf \ @ENABLE_EXAMPLES_TRUE@ lxc-complex.conf \ @ENABLE_EXAMPLES_TRUE@ seccomp-v1.conf \ @ENABLE_EXAMPLES_TRUE@ seccomp-v2-blacklist.conf \ @ENABLE_EXAMPLES_TRUE@ seccomp-v2.conf noinst_DATA = \ lxc-macvlan.conf.in \ lxc-vlan.conf.in \ lxc-empty-netns.conf.in \ lxc-no-netns.conf.in \ lxc-phys.conf.in \ lxc-veth.conf.in \ lxc-complex.conf.in \ seccomp-v1.conf \ seccomp-v2-blacklist.conf \ seccomp-v2.conf EXTRA_DIST = \ seccomp-v1.conf \ seccomp-v2-blacklist.conf \ seccomp-v2.conf all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/examples/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): lxc-macvlan.conf: $(top_builddir)/config.status $(srcdir)/lxc-macvlan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-vlan.conf: $(top_builddir)/config.status $(srcdir)/lxc-vlan.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-no-netns.conf: $(top_builddir)/config.status $(srcdir)/lxc-no-netns.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-empty-netns.conf: $(top_builddir)/config.status $(srcdir)/lxc-empty-netns.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-phys.conf: $(top_builddir)/config.status $(srcdir)/lxc-phys.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-veth.conf: $(top_builddir)/config.status $(srcdir)/lxc-veth.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lxc-complex.conf: $(top_builddir)/config.status $(srcdir)/lxc-complex.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-pkgexamplesDATA: $(pkgexamples_DATA) @$(NORMAL_INSTALL) @list='$(pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgexamplesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgexamplesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgexamplesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgexamplesdir)" || exit $$?; \ done uninstall-pkgexamplesDATA: @$(NORMAL_UNINSTALL) @list='$(pkgexamples_DATA)'; test -n "$(pkgexamplesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgexamplesdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgexamplesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-pkgexamplesDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkgexamplesDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-pkgexamplesDATA install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-pkgexamplesDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lxc-2.0.0/doc/examples/lxc-no-netns.conf.in0000644061062106075000000000012512701247216015414 00000000000000# Container with non-virtualized network lxc.network.type = none lxc.utsname = delta lxc-2.0.0/doc/examples/seccomp-v2.conf0000644061062106075000000000122312701247216014440 000000000000002 whitelist trap # 'whitelist' would normally mean kill a task doing any syscall which is not # whitelisted below. By appending 'trap' to the line, we will cause a SIGSYS # to be sent to the task instead. 'errno 0' would mean don't allow the system # call but immediately return 0. 'errno 22' would mean return EINVAL immediately. [x86_64] open close read write mount umount2 # Since we are listing system calls by name, we can also ask to have them resolved # for another arch, i.e. for 32/64-bit versions. [x86] open close read write mount umount2 # Do note that this policy does not whitelist enough system calls to allow a # system container to boot. lxc-2.0.0/doc/examples/lxc-macvlan.conf.in0000644061062106075000000000043412701247216015277 00000000000000# Container with network virtualized using the macvlan device driver lxc.utsname = alpha lxc.network.type = macvlan lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 lxc-2.0.0/doc/examples/seccomp-v2-blacklist.conf0000644061062106075000000000051612701247216016412 000000000000002 blacklist # v2 allows comments after the second line, with '#' in first column, # blacklist will allow syscalls by default # if 'errno 0' was not appended to 'mknod' below, then the task would # simply be killed when it tried to mknod. 'errno 0' means do not allow # the container to mknod, but immediately return 0. mknod errno 0 lxc-2.0.0/doc/examples/lxc-veth.conf.in0000644061062106075000000000050712701247216014625 00000000000000# Container with network virtualized using a pre-configured bridge named br0 and # veth pair virtual network devices lxc.utsname = beta lxc.network.type = veth lxc.network.flags = up lxc.network.link = br0 lxc.network.hwaddr = 4a:49:43:49:79:bf lxc.network.ipv4 = 10.2.3.5/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597 lxc-2.0.0/doc/examples/lxc-empty-netns.conf.in0000644061062106075000000000017212701247216016140 00000000000000# Container with new network withtout network devices lxc.utsname = omega lxc.network.type = empty lxc.network.flags = up lxc-2.0.0/doc/examples/lxc-vlan.conf.in0000644061062106075000000000046112701247216014616 00000000000000# Container with network virtualized using the vlan device driver lxc.utsname = alpha lxc.network.type = vlan lxc.network.vlan.id = 1234 lxc.network.flags = up lxc.network.link = eth0 lxc.network.hwaddr = 4a:49:43:49:79:bd lxc.network.ipv4 = 10.2.3.4/24 lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596 lxc-2.0.0/doc/lxc-create.sgml.in0000644061062106075000000001745412701247216013332 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-create 1 lxc-create creates a container lxc-create -n name -f config_file -t template -B backingstore -- template-options Description lxc-create creates a system object where is stored the configuration information and where can be stored user information. The identifier name is used to specify the container to be used with the different lxc commands. The object is a directory created in @LXCPATH@ and identified by its name. The object is the definition of the different resources an application can use or can see. The more the configuration file contains information, the more the container is isolated and the more the application is jailed. If the configuration file config_file is not specified, the container will be created with the default isolation: processes, sysv ipc and mount points. Options Specify the configuration file to configure the virtualization and isolation functionalities for the container. 'template' is the short name of an existing 'lxc-template' script that is called by lxc-create, eg. busybox, debian, fedora, ubuntu or sshd. Refer to the examples in @LXCTEMPLATEDIR@ for details of the expected script structure. Alternatively, the full path to an executable template script can also be passed as a parameter. "none" can be used to force lxc-create to skip rootfs creation. 'backingstore' is one of 'dir', 'lvm', 'loop', 'btrfs', 'zfs', 'rbd', or 'best'. The default is 'dir', meaning that the container root filesystem will be a directory under @LXCPATH@/container/rootfs. This backing store type allows the optional --dir ROOTFS to be specified, meaning that the container rootfs should be placed under the specified path, rather than the default. (The 'none' backingstore type is an alias for 'dir'.) If 'btrfs' is specified, then the target filesystem must be btrfs, and the container rootfs will be created as a new subvolume. This allows snapshotted clones to be created, but also causes rsync --one-filesystem to treat it as a separate filesystem. If backingstore is 'lvm', then an lvm block device will be used and the following further options are available: --lvname lvname1 will create an LV named lvname1 rather than the default, which is the container name. --vgname vgname1 will create the LV in volume group vgname1 rather than the default, lxc. --thinpool thinpool1 will create the LV as a thin-provisioned volume in the pool named thinpool1 rather than the default, lxc. --fstype FSTYPE will create an FSTYPE filesystem on the LV, rather than the default, which is ext4. --fssize SIZE will create a LV (and filesystem) of size SIZE rather than the default, which is 1G. If backingstore is 'loop', you can use --fstype FSTYPE and --fssize SIZE as 'lvm'. The default values for these options are the same as 'lvm'. If backingstore is 'rbd', then you will need to have a valid configuration in ceph.conf and a ceph.client.admin.keyring defined. You can specify the following options : --rbdname RBDNAME will create a blockdevice named RBDNAME rather than the default, which is the container name. --rbdpool POOL will create the blockdevice in the pool named POOL, rather than the default, which is 'lxc'. If backingstore is 'best', then lxc will try, in order, btrfs, zfs, lvm, and finally a directory backing store. This will pass template-options to the template as arguments. To see the list of options supported by the template, you can run lxc-create -t TEMPLATE -h. &commonoptions; Diagnostic The container already exists As the message mention it, you try to create a container but there is a container with the same name. You can use the lxc-ls command to list the available containers on the system. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/lxc.system.conf.sgml.in0000644061062106075000000001203712701247216014330 00000000000000 ]> @LXC_GENERATE_DATE@ lxc.system.conf 5 lxc.system.conf LXC system configuration file Description The system configuration is located at @LXC_GLOBAL_CONF@ or ~/.config/lxc/lxc.conf for unprivileged containers. This configuration file is used to set values such as default lookup paths and storage backend settings for LXC. Configuration paths The location in which all containers are stored. The path to the default container configuration. Control Groups Comma separated list of cgroup controllers to setup. If none is specified, all available controllers will be used. Format string used to generate the cgroup path (e.g. lxc/%n). LVM Default LVM volume group name. Default LVM thin pool name. ZFS Default ZFS root name. lxc 1 , lxc.container.conf 5 , lxc.system.conf 5 , lxc-usernet 5 &seealso; Author Stéphane Graber stgraber@ubuntu.com lxc-2.0.0/doc/rootfs/0000755061062106075000000000000012701247243011373 500000000000000lxc-2.0.0/doc/rootfs/README0000644061062106075000000000027512701247216012177 00000000000000This directory must exist, even though it may be empty. It is used to temporary mount the rootfs of lxc in a private mount namespace only visible by the processes running in the container. lxc-2.0.0/doc/rootfs/Makefile.in0000644061062106075000000003647012701247222013367 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/rootfs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/config/acinclude.m4 \ $(top_srcdir)/config/tls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/src/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(READMEdir)" DATA = $(README_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APPARMOR_LIBS = @APPARMOR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDIR = @BINDIR@ CAP_LIBS = @CAP_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CGMANAGER_CFLAGS = @CGMANAGER_CFLAGS@ CGMANAGER_LIBS = @CGMANAGER_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIR = @DATADIR@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFAULT_CGROUP_PATTERN = @DEFAULT_CGROUP_PATTERN@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DOCDIR = @DOCDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ HAVE_DOXYGEN = @HAVE_DOXYGEN@ INCLUDEDIR = @INCLUDEDIR@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBDIR = @LIBDIR@ LIBEXECDIR = @LIBEXECDIR@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCALSTATEDIR = @LOCALSTATEDIR@ LOGPATH = @LOGPATH@ LTLIBOBJS = @LTLIBOBJS@ LUA_CFLAGS = @LUA_CFLAGS@ LUA_LIBDIR = @LUA_LIBDIR@ LUA_LIBS = @LUA_LIBS@ LUA_SHAREDIR = @LUA_SHAREDIR@ LUA_VERSION = @LUA_VERSION@ LXCBINHOOKDIR = @LXCBINHOOKDIR@ LXCHOOKDIR = @LXCHOOKDIR@ LXCINITDIR = @LXCINITDIR@ LXCPATH = @LXCPATH@ LXCROOTFSMOUNT = @LXCROOTFSMOUNT@ LXCTEMPLATECONFIG = @LXCTEMPLATECONFIG@ LXCTEMPLATEDIR = @LXCTEMPLATEDIR@ LXC_DEFAULT_CONFIG = @LXC_DEFAULT_CONFIG@ LXC_DISTRO_SYSCONF = @LXC_DISTRO_SYSCONF@ LXC_GENERATE_DATE = @LXC_GENERATE_DATE@ LXC_GLOBAL_CONF = @LXC_GLOBAL_CONF@ LXC_USERNIC_CONF = @LXC_USERNIC_CONF@ LXC_USERNIC_DB = @LXC_USERNIC_DB@ LXC_VERSION = @LXC_VERSION@ LXC_VERSION_ABI = @LXC_VERSION_ABI@ LXC_VERSION_BASE = @LXC_VERSION_BASE@ LXC_VERSION_BETA = @LXC_VERSION_BETA@ LXC_VERSION_MAJOR = @LXC_VERSION_MAJOR@ LXC_VERSION_MICRO = @LXC_VERSION_MICRO@ LXC_VERSION_MINOR = @LXC_VERSION_MINOR@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NIH_CFLAGS = @NIH_CFLAGS@ NIH_DBUS_CFLAGS = @NIH_DBUS_CFLAGS@ NIH_DBUS_LIBS = @NIH_DBUS_LIBS@ NIH_LIBS = @NIH_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PREFIX = @PREFIX@ PYTHON = @PYTHON@ PYTHONDEV_CFLAGS = @PYTHONDEV_CFLAGS@ PYTHONDEV_LIBS = @PYTHONDEV_LIBS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RUNTIME_PATH = @RUNTIME_PATH@ SBINDIR = @SBINDIR@ SECCOMP_CFLAGS = @SECCOMP_CFLAGS@ SECCOMP_LIBS = @SECCOMP_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYSCONFDIR = @SYSCONFDIR@ SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ db2xman = @db2xman@ docdir = @docdir@ docdtd = @docdtd@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ READMEdir = @LXCROOTFSMOUNT@ README_DATA = README all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/rootfs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/rootfs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-READMEDATA: $(README_DATA) @$(NORMAL_INSTALL) @list='$(README_DATA)'; test -n "$(READMEdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(READMEdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(READMEdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(READMEdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(READMEdir)" || exit $$?; \ done uninstall-READMEDATA: @$(NORMAL_UNINSTALL) @list='$(README_DATA)'; test -n "$(READMEdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(READMEdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(READMEdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-READMEDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-READMEDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-READMEDATA install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-READMEDATA \ uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lxc-2.0.0/doc/rootfs/Makefile.am0000644061062106075000000000005712701247216013351 00000000000000READMEdir=@LXCROOTFSMOUNT@ README_DATA=README lxc-2.0.0/doc/lxc.system.conf0000644061062106075000000000065712701247216012767 00000000000000# LVM: volume group to use for new containers lxc.bdev.lvm.vg = lxc # LVM: thin pool to use for new containers lxc.bdev.lvm.thin_pool = lxc # ZFS: Root path lxc.bdev.zfs.root = lxc # Path to the containers lxc.lxcpath = /var/lib/lxc/ # Path to the default configuration file lxc.default_config = /etc/lxc/default.conf # Pattern to use for the cgroup path lxc.cgroup.pattern = lxc/%n # List of cgroups to use lxc.cgroup.use = lxc-2.0.0/doc/lxc-autostart.sgml.in0000644061062106075000000002423712701247216014112 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-autostart 1 lxc-autostart start/stop/kill auto-started containers lxc-autostart -k -L -r -s -a -A -g groups -t timeout Description lxc-autostart processes containers with lxc.start.auto set. It lets the user start, shutdown, kill, restart containers in the right order, waiting the right time. Supports filtering by lxc.group or just run against all defined containers. It can also be used by external tools in list mode where no action will be performed and the list of affected containers (and if relevant, delays) will be shown. The -r, -s and -k options specify the action to perform. If none is specified, then the containers will be started. -a and -g are used to specify which containers will be affected. By default only containers without a lxc.group set will be affected. -t TIMEOUT specifies the maximum amount of time to wait for the container to complete the shutdown or reboot. Options Request a reboot of the container. Request a clean shutdown. If a -t timeout greater than 0 is given and the container has not shut down within this period, it will be killed as with the -k kill option. Rather than requesting a clean shutdown of the container, explicitly kill all tasks in the container. Rather than performing the action, just print the container name and wait delays until starting the next container. Wait TIMEOUT seconds before hard-stopping the container. Comma separated list of groups to select (defaults to those without a lxc.group - the NULL group). This option may be specified multiple times and the arguments concatenated. The NULL or empty group may be specified as a leading comma, trailing comma, embedded double comma, or empty argument where the NULL group should be processed. Groups are processed in the order specified on the command line. Multiple invocations of the -g option may be freely intermixed with the comma separated lists and will be combined in specified order. Ignore lxc.group and select all auto-started containers. Ignore the lxc.start.auto flag. Combined with -a, will select all containers on the system. Autostart and System Boot The lxc-autostart command is used as part of the LXC system service, when enabled to run on host system at bootup and at shutdown. It's used to select which containers to start in what order and how much to delay between each startup when the host system boots. Each container can be part of any number of groups or no group at all. Two groups are special. One is the NULL group, i.e. the container does not belong to any group. The other group is the "onboot" group. When the system boots with the LXC service enabled, it will first attempt to boot any containers with lxc.start.auto == 1 that is a member of the "onboot" group. The startup will be in order of lxc.start.order. If an lxc.start.delay has been specified, that delay will be honored before attempting to start the next container to give the current container time to begin initialization and reduce overloading the host system. After starting the members of the "onboot" group, the LXC system will proceed to boot containers with lxc.start.auto == 1 which are not members of any group (the NULL group) and proceed as with the onboot group. Startup Group Examples Start the "onboot" group first then the NULL group. This is the equivalent of: . Starts the "dns" group first, the "web" group second, then the NULL group followed by the "onboot" group. This is the equivalent of: or . &seealso; Author Stéphane Graber stgraber@ubuntu.com lxc-2.0.0/doc/lxc-attach.sgml.in0000644061062106075000000003240612701247216013325 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-attach 1 lxc-attach start a process inside a running container. lxc-attach -n name -a arch -e -s namespaces -R --keep-env --clear-env -- command Description lxc-attach runs the specified command inside the container specified by name. The container has to be running already. If no command is specified, the current default shell of the user running lxc-attach will be looked up inside the container and executed. This will fail if no such user exists inside the container or the container does not have a working nsswitch mechanism. Previous versions of lxc-attach simply attached to the specified namespaces of a container and ran a shell or the specified command without first allocating a pseudo terminal. This made them vulnerable to input faking via a TIOCSTI ioctl call after switching between userspace execution contexts with different privilege levels. Newer versions of lxc-attach will try to allocate a pseudo terminal master/slave pair on the host and attach any standard file descriptors which refer to a terminal to the slave side of the pseudo terminal before executing a shell or command. Note, that if none of the standard file descriptors refer to a terminal lxc-attach will not try to allocate a pseudo terminal. Instead it will simply attach to the containers namespaces and run a shell or the specified command. Options Specify the architecture which the kernel should appear to be running as to the command executed. This option will accept the same settings as the option in container configuration files, see lxc.conf 5 . By default, the current archictecture of the running container will be used. Do not drop privileges when running command inside the container. If this option is specified, the new process will not be added to the container's cgroup(s) and it will not drop its capabilities before executing. You may specify privileges, in case you do not want to elevate all of them, as a pipe-separated list, e.g. CGROUP|LSM. Allowed values are CGROUP, CAP and LSM representing cgroup, capabilities and restriction privileges respectively. (The pipe symbol needs to be escaped, e.g. CGROUP\|LSM or quoted, e.g. "CGROUP|LSM".) Warning: This may leak privileges into the container if the command starts subprocesses that remain active after the main process that was attached is terminated. The (re-)starting of daemons inside the container is problematic, especially if the daemon starts a lot of subprocesses such as cron or sshd. Use with great care. Specify the namespaces to attach to, as a pipe-separated list, e.g. NETWORK|IPC. Allowed values are MOUNT, PID, UTSNAME, IPC, USER and NETWORK. This allows one to change the context of the process to e.g. the network namespace of the container while retaining the other namespaces as those of the host. (The pipe symbol needs to be escaped, e.g. MOUNT\|PID or quoted, e.g. "MOUNT|PID".) Important: This option implies . When using and the mount namespace is not included, this flag will cause lxc-attach to remount /proc and /sys to reflect the current other namespace contexts. Please see the Notes section for more details. This option will be ignored if one tries to attach to the mount namespace anyway. Keep the current environment for attached programs. This is the current default behaviour (as of version 0.9), but is is likely to change in the future, since this may leak undesirable information into the container. If you rely on the environment being available for the attached program, please use this option to be future-proof. In addition to current environment variables, container=lxc will be set. Clear the environment before attaching, so no undesired environment variables leak into the container. The variable container=lxc will be the only environment with which the attached program starts. &commonoptions; Examples To spawn a new shell running inside an existing container, use lxc-attach -n container To restart the cron service of a running Debian container, use lxc-attach -n container -- /etc/init.d/cron restart To deactivate the network link eth1 of a running container that does not have the NET_ADMIN capability, use either the option to use increased capabilities, assuming the ip tool is installed: lxc-attach -n container -e -- /sbin/ip link delete eth1 Or, alternatively, use the to use the tools installed on the host outside the container: lxc-attach -n container -s NETWORK -- /sbin/ip link delete eth1 Compatibility Attaching completely (including the pid and mount namespaces) to a container requires a kernel of version 3.8 or higher, or a patched kernel, please see the lxc website for details. lxc-attach will fail in that case if used with an unpatched kernel of version 3.7 and prior. Nevertheless, it will succeed on an unpatched kernel of version 3.0 or higher if the option is used to restrict the namespaces that the process is to be attached to to one or more of NETWORK, IPC and UTSNAME. Attaching to user namespaces is supported by kernel 3.8 or higher with enabling user namespace. Notes The Linux /proc and /sys filesystems contain information about some quantities that are affected by namespaces, such as the directories named after process ids in /proc or the network interface information in /sys/class/net. The namespace of the process mounting the pseudo-filesystems determines what information is shown, not the namespace of the process accessing /proc or /sys. If one uses the option to only attach to the pid namespace of a container, but not its mount namespace (which will contain the /proc of the container and not the host), the contents of will reflect that of the host and not the container. Analogously, the same issue occurs when reading the contents of /sys/class/net and attaching to just the network namespace. To work around this problem, the flag provides the option to remount /proc and /sys in order for them to reflect the network/pid namespace context of the attached process. In order not to interfere with the host's actual filesystem, the mount namespace will be unshared (like lxc-unshare does) before this is done, essentially giving the process a new mount namespace, which is identical to the hosts's mount namespace except for the /proc and /sys filesystems. Previous versions of lxc-attach suffered a bug whereby a user could attach to a containers namespace without being placed in a writeable cgroup for some critical subsystems. Newer versions of lxc-attach will check whether a user is in a writeable cgroup for those critical subsystems. lxc-attach might thus fail unexpectedly for some users (E.g. on systems where an unprivileged user is not placed in a writeable cgroup in critical subsystems on login.). However, this behavior is correct and more secure. Security The and options should be used with care, as it may break the isolation of the containers if used improperly. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/lxc-unfreeze.sgml.in0000644061062106075000000000502712701247216013703 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-unfreeze 1 lxc-unfreeze thaw all the container's processes lxc-unfreeze -n name Description lxc-unfreeze will thaw all the processes previously frozen by the lxc-freeze command. &commonoptions; Diagnostic The container was not found The specified container was not created before with the lxc-create command. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/lxc-freeze.sgml.in0000644061062106075000000000527212701247216013342 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-freeze 1 lxc-freeze freeze all the container's processes lxc-freeze -n name Description lxc-freeze freezes all the processes running inside the container. The processes will be blocked until they are explicitly thawed by the lxc-unfreeze command. This command is useful for batch managers to schedule a group of processes. &commonoptions; Diagnostic The container was not found The specified container was not created before with the lxc-create command. &seealso; Author Daniel Lezcano daniel.lezcano@free.fr lxc-2.0.0/doc/lxc-snapshot.sgml.in0000644061062106075000000001236312701247216013720 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-snapshot 1 lxc-snapshot Snapshot an existing container. lxc-snapshot -n, --name name -c, --comment file lxc-snapshot -n, --name name -d, -destroy snapshot-name lxc-snapshot -n, --name name -L, --list -C, --showcomments lxc-snapshot -n, --name name -r, -restore snapshot-name -N, --newname newname Description lxc-snapshot creates, lists, and restores container snapshots. Snapshots are stored as snapshotted containers under the container's configuration path. For instance, if the container's configuration path is /var/lib/lxc and the container is c1, then the first snapshot will be stored as container snap0 under the path /var/lib/lxc/c1/snaps. If /var/lib/lxcsnaps, as used by LXC 1.0, already exists, then it will continue to be used. Options Associate the comment in comment_file with the newly created snapshot. Destroy the named snapshot. If the named snapshot is ALL, then all snapshots will be destroyed. List existing snapshots. Show snapshot comments in the snapshots listings. Restore the named snapshot, meaning a full new container is created which is a copy of the snapshot. When restoring a snapshot, the last optional argument if not given explicitly via --newname is the name to use for the restored container. If the newname is identical to the original name of the container, then the original container will be destroyed and the restored container will take its place. Note that deleting the original snapshot is not possible in the case of aufs, overlayfs or zfs backed snapshots. &commonoptions; &seealso; Author Serge Hallyn serge.hallyn@ubuntu.com lxc-2.0.0/doc/lxc-ls.sgml.in0000644061062106075000000001473412701247216012503 00000000000000 ]> @LXC_GENERATE_DATE@ lxc-ls 1 lxc-ls list the containers existing on the system lxc-ls -1 --active --frozen --running --stopped -f -F format -g groups --nesting=NUM --filter=regex Description lxc-ls list the containers existing on the system. Options Show one entry per line. (default when /dev/stdout isn't a tty) List only active containers (same as --frozen --running). List only frozen containers. List only running containers. List only stopped containers. Use a fancy, column-based output. Comma separated list of column to show in the fancy output. The list of accepted and default fields is listed in --help. Comma separated list of groups the container must have to be displayed. The parameter may be passed multiple times. Show nested containers. The number of nesting levels to be shown can be specified by passing a number as argument. The regular expression passed to lxc-ls will be applied to the container name. The format is a POSIX extended regular expression. It can also be given as additional argument without explicitly using . Examples lxc-ls --fancy list all the containers, listing one per line along with its name, state, ipv4 and ipv6 addresses. lxc-ls --active -1 list active containers and display the list in one column. &commonoptions; &seealso; History Written originally as a shell script by Daniel Lezcano and Serge Hallyn. Later reimplemented and extended in Python by Stéphane Graber and then reimplemented and extended in C by Christian Brauner. Author Christian Brauner christian.brauner@mailbox.org, Stéphane Graber stgraber@ubuntu.com lxc-2.0.0/doc/api/0000755061062106075000000000000012701247243010630 500000000000000lxc-2.0.0/doc/api/Doxyfile0000644061062106075000000030211312701247216012256 00000000000000# Doxyfile 1.8.5 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "LXC" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is included in # the documentation. The maximum height of the logo should not exceed 55 pixels # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = . # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese- # Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi, # Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en, # Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a # new page for each member. If set to NO, the documentation of a member will be # part of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined # locally in source files will be included in the documentation. If set to NO # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO these classes will be included in the various overviews. This option has # no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO the members will appear in declaration order. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the # todo list. This list is created by putting \todo commands in the # documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the # test list. This list is created by putting \test commands in the # documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES the list # will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. Do not use file names with spaces, bibtex cannot handle them. See # also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO doxygen will only warn about wrong or incomplete parameter # documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. INPUT = \ ../../src/lxc/lxccontainer.h \ ../../src/lxc/lxclock.h \ ../../src/lxc/attach_options.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = *.h # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES, then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to NO can help when comparing the output of multiple runs. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( # YES) or a normal table of contents ( NO) in the .chm file. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /