summaryrefslogtreecommitdiff
blob: 4958fbcbbc7b8d978d4078da15f883efac0f73f4 (plain)
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
#!/sbin/openrc-run
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

CONTAINER=${SVCNAME#*.}

LXC_PATH=`lxc-config lxc.lxcpath`

lxc_get_configfile() {
	if [ -f "${LXC_PATH}/${CONTAINER}.conf" ]; then
		echo "${LXC_PATH}/${CONTAINER}.conf"
	elif [ -f "${LXC_PATH}/${CONTAINER}/config" ]; then
		echo "${LXC_PATH}/${CONTAINER}/config"
	else
		eerror "Unable to find a suitable configuration file."
		eerror "If you set up the container in a non-standard"
		eerror "location, please set the CONFIGFILE variable."
		return 1
	fi
}

[ $CONTAINER != $SVCNAME ] && CONFIGFILE=${CONFIGFILE:-$(lxc_get_configfile)}

lxc_get_var() {
	awk 'BEGIN { FS="[ \t]*=[ \t]*" } $1 == "'$1'" { print $2; exit }' ${CONFIGFILE}
}

lxc_get_net_link_type() {
		# gentoo bugfix 909640, drop commented lines before awk
		grep -v '^#' ${CONFIGFILE} | awk 'BEGIN { FS="[ \t]*=[ \t]*"; _link=""; _type="" }
		$1 == "lxc.network.type" {_type=$2;}
		$1 == "lxc.network.link" {_link=$2;}
		match($1, /lxc\.net\.[[:digit:]]+\.type/) {_type=$2;}
		match($1, /lxc\.net\.[[:digit:]]+\.link/) {_link=$2;}
		{if(_link != "" && _type != ""){
			printf("%s:%s\n", _link, _type );
			_link=""; _type="";
		}; }'
}

checkconfig() {
	if [ ${CONTAINER} = ${SVCNAME} ]; then
		eerror "You have to create an init script for each container:"
		eerror " ln -s lxc /etc/init.d/lxc.container"
		return 1
	fi

	# no need to output anything, the function takes care of that.
	[ -z "${CONFIGFILE}" ] && return 1

	utsname=$(lxc_get_var lxc.uts.name)
	if [ -z "$utsname" ] ; then
		utsname=$(lxc_get_var lxc.utsname)
	fi

	if [ "${CONTAINER}" != "${utsname}" ]; then
	    eerror "You should use the same name for the service and the"
	    eerror "container. Right now the container is called ${utsname}"
	    return 1
	fi
}

depend() {
	# be quiet, since we have to run depend() also for the
	# non-muxed init script, unfortunately.
	checkconfig 2>/dev/null || return 0

	config ${CONFIGFILE}
	need localmount
	use lxcfs

	local _x _if
	for _x in $(lxc_get_net_link_type); do
		_if=${_x%:*}
		case "${_x##*:}" in
			# when the network type is set to phys, we can make use of a
			# network service (for instance to set it up before we disable
			# the net_admin capability), but we might also  not set it up
			# at all on the host and leave the net_admin capable service
			# to take care of it.
			phys)	use net.${_if} ;;
			*)	need net.${_if} ;;
		esac
	done
}

start() {
	checkconfig || return 1
	rm -f /var/log/lxc/${CONTAINER}.log

	rootpath=$(lxc_get_var lxc.rootfs)

	# Check the format of our init and the chroot's init, to see
	# if we have to use linux32 or linux64; always use setarch
	# when required, as that makes it easier to deal with
	# x32-based containers.
	case $(scanelf -BF '%a#f' ${rootpath}/sbin/init) in
		EM_X86_64)	setarch=linux64;;
		EM_386)		setarch=linux32;;
	esac

	ebegin "Starting LXC container ${CONTAINER}"
	env -i ${setarch} $(which lxc-start) -n ${CONTAINER} -f ${CONFIGFILE} -d -o /var/log/lxc/${CONTAINER}.log
	sleep 1

	# lxc-start -d will _always_ report a correct startup, even if it
	# failed, so rather than trust that, check that the cgroup exists.
	# fix for LXC 3.1	

	STATE="$(lxc-info -s -H ${CONTAINER})"
	[ "$STATE" = "RUNNING" ]
	
	eend $?
}

stop() {
	checkconfig || return 1

	STATE="$(lxc-info -s -H ${CONTAINER})"
	
	if ! [ "$STATE" = "RUNNING" ]; then
	    ewarn "${CONTAINER} doesn't seem to be started."
	    return 0
	fi

	# 30s should be enough to shut everything down
	# lxc-stop will return back anyway as soon as successful shutdown
	# after 30s, lxc-stop sends SIGKILL (dirty shotdown)
	ebegin "Stopping LXC container ${CONTAINER}"
	lxc-stop -t 30 -n ${CONTAINER}
	eend $?
}