Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
f8d0243a
Commit
f8d0243a
authored
Jan 14, 2014
by
lxc@zitta.fr
Committed by
Stéphane Graber
Jan 14, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gentoo: Initial template
Signed-off-by:
gza
<
lxc@zitta.fr
>
Acked-by:
Stéphane Graber
<
stgraber@ubuntu.com
>
parent
c8ad5f46
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
840 additions
and
9 deletions
+840
-9
.gitignore
.gitignore
+1
-0
configure.ac
configure.ac
+10
-9
Makefile.am
templates/Makefile.am
+1
-0
lxc-gentoo.in
templates/lxc-gentoo.in
+828
-0
No files found.
.gitignore
View file @
f8d0243a
...
...
@@ -34,6 +34,7 @@ templates/lxc-cirros
templates/lxc-debian
templates/lxc-download
templates/lxc-fedora
templates/lxc-gentoo
templates/lxc-openmandriva
templates/lxc-opensuse
templates/lxc-oracle
...
...
configure.ac
View file @
f8d0243a
...
...
@@ -632,22 +632,23 @@ AC_CONFIG_FILES([
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-ubuntu
templates/lxc-ubuntu-cloud
templates/lxc-opensuse
templates/lxc-busybox
templates/lxc-centos
templates/lxc-fedora
templates/lxc-gentoo
templates/lxc-openmandriva
templates/lxc-opensuse
templates/lxc-oracle
templates/lxc-altlinux
templates/lxc-sshd
templates/lxc-archlinux
templates/lxc-alpine
templates/lxc-plamo
templates/lxc-sshd
templates/lxc-ubuntu
templates/lxc-ubuntu-cloud
src/Makefile
src/lxc/Makefile
...
...
templates/Makefile.am
View file @
f8d0243a
...
...
@@ -10,6 +10,7 @@ templates_SCRIPTS = \
lxc-debian
\
lxc-download
\
lxc-fedora
\
lxc-gentoo
\
lxc-openmandriva
\
lxc-opensuse
\
lxc-oracle
\
...
...
templates/lxc-gentoo.in
0 → 100644
View file @
f8d0243a
#!/bin/bash
#
# LXC template for gentoo
#
# Author: Guillaume Zitta <lxc@zitta.fr>
#
# 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
#
# Ensure strict root's umask doesen't render the VM unusable
umask
022
################################################################################
# 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
=
$(
arch
)
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
&&
\
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 SEPERATORS, 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
)
\
||
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
-
-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
}
"
-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"
if
[
-n
"
${
nettun
}
"
]
;
then
mkdir
-m
755
"
${
partialfs
}
/net"
mknod
-m
666
"
${
partialfs
}
/net/tun"
c 10 200
fi
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
}
################################################################################
# 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_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 SEPERATORS, THIS IS *VERY* BAD!
\n
"
"
${
name
}
"
[[
-n
"
${
rootfs
//\/
}
"
]]
\
||
die 8
"
\$
rootfs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, THIS IS *VERY* BAD!
\n
"
"
${
rootfs
}
"
[[
-n
"
${
cachefs
//\/
}
"
]]
\
||
die 8
"
\$
cachefs (%s) IS EMPTY OR MADE OF ONLY DIRECTORY SEPERATORS, 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
-
-C
"
${
cachefs
}
"
.
|
tar
-x
-p
-f
-
-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
# 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"
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 additionnal 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
}
"
\
||
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
=
"
"
#I'll drink champagne the day we do templates in python
#let's do some drity bash things
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 finaly 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"'
>>
"
$CACHE
/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
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
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
"hostnale=%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
>>
"
${
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 gived 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
"
}
################################################################################
# lxc configuration files
################################################################################
container_conf
()
{
printf
"container_configuration(): making lxc configuration file...
\n
"
#at this point if there
conf_file
=
"
${
path
}
/config"
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
conf_lxc_cap_drop
=
"sys_module mac_admin mac_override mknod sys_time"
conf_sysfs
=
"lxc.mount.entry=sys sys sysfs defaults 0 0"
#more aggressive configuration, for your safety. But less things may work
if
[
-n
"
${
more_secure
}
"
]
;
then
conf_lxc_cap_drop
=
"
${
conf_lxc_cap_drop
}
audit_control audit_write dac_read_search fsetid ipc_owner linux_immutable setfcap sys_admin sys_boot sys_pacct sys_ptrace sys_rawio sys_resource sys_tty_config syslog"
conf_sysfs
=
"# disabled for security, see http://blog.bofh.it/debian/id_413
#lxc.mount.entry=sys sys sysfs defaults 0 0"
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
}
# console access
lxc.tty =
${
tty
}
lxc.pts = 1024
# set the hostname
lxc.utsname =
${
name
}
${
conf_rootfs_line
}
${
portage_mount
}
${
conf_sysfs
}
# this part is based on 'linux capabilities', see: man 7 capabilities
# eg: you may also wish to drop 'cap_net_raw' (though it breaks ping)
#
# WARNING: the security vulnerability reported for 'cap_net_admin' at
# http://mainisusuallyafunction.blogspot.com/2012/11/attacking-hardened-linux-systems-with.html
# via JIT spraying (the BPF JIT module disabled on most systems was used
# in the example, but others are suggested vulnerable) meant that users
# with root in a container, that capability and kernel module may escape
# the container. ALWAYS be extremely careful granting any process root
# within a container, use a minimal configuration at all levels -
# including the kernel - and multiple layers of security on any system
# where security is a priority. note that not only LXC but PAX (and
# others?) were vulnerable to this issue.
#
# conservative: lxc.cap.drop = sys_module mknod mac_override sys_boot
# aggressive follows. (leaves open: chown dac_override fowner ipc_lock kill lease net_admin net_bind_service net_broadcast net_raw setgid setuid sys_chroot)
# lxc.cap.drop = audit_control audit_write dac_read_search fsetid ipc_owner linux_immutable mac_admin mac_override mknod setfcap sys_admin sys_boot sys_module sys_pacct sys_ptrace sys_rawio sys_resource sys_time sys_tty_config syslog
lxc.cap.drop =
${
conf_lxc_cap_drop
}
${
conf_mounts
}
# deny access to all devices by default, explicitly grant some permissions
#
# format is [c|b] [major|*]:[minor|*] [r][w][m]
# ^ ^ ^
# char/block -' \`- device number \`-- read, write, mknod
#
# first deny all...
lxc.cgroup.devices.deny = a
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rw
lxc.cgroup.devices.allow = c 1:5 rw
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rw
lxc.cgroup.devices.allow = c 1:8 r
# /dev/pts/*
lxc.cgroup.devices.allow = c 136:* rw
lxc.cgroup.devices.allow = c 5:2 rw
# /dev/tty{0,1}
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
# /dev/tty
lxc.cgroup.devices.allow = c 5:0 rwm
# /dev/console
lxc.cgroup.devices.allow = c 5:1 rwm
EOF
if
[
-n
"
${
nettun
}
"
]
;
then
cat
<<-
EOF
>> "
${
conf_file
}
"
# /dev/net/tun
lxc.cgroup.devices.allow = c 10:200 rwm
EOF
fi
printf
" => done.
\n
"
}
usage
()
{
cat
<<
EOF
$1
-h|--help [-a|--arch <arch>] [-v|--variant <variant>] [-P|--private-portage] [--portage-dir <protagedir>] [-t|--tarball <stage3file>]
[-F|--flush-cache] [-c|--cache-only] [-u|--user <username>] [-w|--password <password>] [-S|--auth-key <keyfile>]
[-s|--more-secure] [-m|--mirror <gentoomirror>] [--tty <number>] [--nettun]
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
more-secure: does some additional security agressive settings (may prevent things to run) (currently: '
${
more_secure
}
')
mirror: gentoo mirror for download (currently: '
${
mirror
}
')
tty: number of tty (6 max) (currently: '
${
tty
}
')
nettun: enable creation of /dev/net/tun (for private container VPN) (currently: '
${
nettun
}
')
EOF
exit
0
}
#some overridable defaults
set_default_arch
mirror
=
"http://distfiles.gentoo.org"
user
=
"root"
password
=
"toor"
tty
=
0
options
=
$(
getopt
-o
hp:n:a:FcPv:t:S:u:w:sm:
-l
help
,rootfs:,path:,name:,arch:,flush-cache,cache-only,private-portage,variant:,portage-dir:,tarball:,auth_key:,user:,autologin,password:,more-secure,mirror:,tty:,nettun
--
"
$@
"
)
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
;
shitf 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
|
--more-secure
)
more_secure
=
1
;
shift
1
;;
-m
|
--mirror
)
mirror
=
$2
;
shift
2
;;
--nettun
)
nettun
=
1
;
shift
1
;;
--tty
)
[[
$2
-lt
6
]]
&&
tty
=
$2
;
shift
2
;;
--autologin
)
autologin
=
1
;
shift
1
;;
--
)
shift
1
;
break
;;
*
)
break
;;
esac
done
cacheroot
=
"@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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment