--- /dev/null
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if init_script == 'systemd'
+ systemd_service = custom_target(
+ 'lxcfs.service',
+ input : 'systemd/lxcfs.service.in',
+ output : 'lxcfs.service',
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ install: true,
+ install_dir: '/lib/systemd/system')
+elif init_script == 'upstart'
+ install_data('upstart/lxcfs.conf', install_dir : join_paths(sysconfdir, 'init'))
+elif init_script == 'openrc'
+ install_data('sysvinit/lxcfs', install_dir : join_paths(sysconfdir, 'rc.d/init.d/lxcfs'))
+elif init_script == 'sysvinit'
+ install_data('sysvinit/lxcfs', install_dir : join_paths(sysconfdir, 'rc.d/init.d/lxcfs'))
+endif
Documentation=man:lxcfs(1)
[Service]
-ExecStart=/usr/bin/lxcfs @LXCFSTARGETDIR@
+ExecStart=/usr/bin/lxcfs {{LXCFSTARGETDIR}}
KillMode=process
Restart=on-failure
-ExecStopPost=-/bin/fusermount -u @LXCFSTARGETDIR@
+ExecStopPost=-/bin/fusermount -u {{LXCFSTARGETDIR}}
Delegate=yes
ExecReload=/bin/kill -USR1 $MAINPID
%endif
Summary: Linux Containers File System
-Name: @PACKAGE@
-Version: @PACKAGE_VERSION@
+Name: {{PROJECT}}
+Version: {{PROJECT_VERSION}}
Release: 1%{?dist}
URL: https://linuxcontainers.org/lxcfs/downloads/
Source0: %{name}-%{version}.tar.gz
)
conf = configuration_data()
+conf.set_quoted('PROJECT', meson.project_name())
conf.set_quoted('PROJECT_URL', 'https://linuxcontainers.org/lxcfs/introduction/')
-conf.set('PROJECT_VERSION', meson.project_version(),
+conf.set_quoted('PROJECT_VERSION', meson.project_version(),
description : 'Numerical project version (used where a simple number is expected)')
project_source_root = meson.current_source_dir()
project_build_root = meson.current_build_dir()
cc = meson.get_compiler('c')
meson_build_sh = find_program('tools/meson-build.sh')
+if run_command('python3', '-c', 'import jinja2').returncode() != 0
+ error('python3 jinja2 missing')
+endif
+
+meson_render_jinja2 = find_program('tools/meson-render-jinja2.py')
+
want_tests = get_option('tests')
possible_cc_flags = [
add_project_arguments('-include', 'config.h', language : 'c')
+test_programs = []
subdir('tests')
public_programs = []
c_args : '-DRELOADTEST -DDEBUG')
endif
-if init_script == 'systemd'
- systemd_service_data = configuration_data()
- systemd_service_data.set_quoted('LXCFSTARGETDIR', join_paths(localstatedir, 'lib/lxcfs'))
- systemd_service = configure_file(
- configuration : systemd_service_data,
- input : 'config/init/systemd/lxcfs.service.in',
- output : 'lxcfs.service')
- install_data(join_paths(project_build_root, 'lxcfs.service'), install_dir : '/lib/systemd/system')
-elif init_script == 'upstart'
- install_data('config/init/upstart/lxcfs.conf', install_dir : join_paths(sysconfdir, 'init'))
-elif init_script == 'openrc'
- install_data('config/init/sysvinit/lxcfs', install_dir : join_paths(sysconfdir, 'rc.d/init.d/lxcfs'))
-elif init_script == 'sysvinit'
- install_data('config/init/sysvinit/lxcfs', install_dir : join_paths(sysconfdir, 'rc.d/init.d/lxcfs'))
-endif
-
-lxcfs_spec_data = configuration_data()
-lxcfs_spec_data.set('PACKAGE_VERSION', meson.project_version())
-lxcfs_spec_data.set('PACKAGE', meson.project_name())
-lxcfs_spec_data = configure_file(
- configuration : lxcfs_spec_data,
- input : 'lxcfs.spec.in',
- output : 'lxcfs.spec')
+lxcfs_spec = custom_target(
+ 'lxcfs.spec',
+ build_by_default : true,
+ input : 'lxcfs.spec.in',
+ output : 'lxcfs.spec',
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
subdir('share')
+subdir('config/init')
status = [
'@0@ @1@'.format(meson.project_name(), meson.project_version()),
-lxc.hook.mount = @LXCFSSHAREDIR@/lxc.mount.hook
-lxc.hook.post-stop = @LXCFSSHAREDIR@/lxc.reboot.hook
+lxc.hook.mount = {{LXCFSSHAREDIR}}/lxc.mount.hook
+lxc.hook.post-stop = {{LXCFSSHAREDIR}}/lxc.reboot.hook
LXC_ROOTFS_MOUNT=$(readlink -f "${LXC_ROOTFS_MOUNT}")
# /proc files
-if [ -d @LXCFSTARGETDIR@/proc/ ]; then
- for entry in @LXCFSTARGETDIR@/proc/*; do
+if [ -d {{LXCFSTARGETDIR}}/proc/ ]; then
+ for entry in {{LXCFSTARGETDIR}}/proc/*; do
DEST=$(basename "$entry")
[ -e "${LXC_ROOTFS_MOUNT}/proc/${DEST}" ] || continue
mount -n --bind "$entry" "${LXC_ROOTFS_MOUNT}/proc/${DEST}"
fi
# /sys/devices/system/cpu
-if [ -d @LXCFSTARGETDIR@/sys/devices/system/cpu ] ; then
- if [ -f @LXCFSTARGETDIR@/sys/devices/system/cpu/uevent ]; then
- mount -n --bind @LXCFSTARGETDIR@/sys/devices/system/cpu "${LXC_ROOTFS_MOUNT}/sys/devices/system/cpu"
+if [ -d {{LXCFSTARGETDIR}}/sys/devices/system/cpu ] ; then
+ if [ -f {{LXCFSTARGETDIR}}/sys/devices/system/cpu/uevent ]; then
+ mount -n --bind {{LXCFSTARGETDIR}}/sys/devices/system/cpu "${LXC_ROOTFS_MOUNT}/sys/devices/system/cpu"
else
- for entry in @LXCFSTARGETDIR@/sys/devices/system/cpu/*; do
+ for entry in {{LXCFSTARGETDIR}}/sys/devices/system/cpu/*; do
DEST=$(basename "$entry")
[ -e "${LXC_ROOTFS_MOUNT}/sys/devices/system/cpu/${DEST}" ] || continue
mount -n --bind "$entry" "${LXC_ROOTFS_MOUNT}/sys/devices/system/cpu/${DEST}"
fi
# Allow nesting lxcfs
-if [ -d "${LXC_ROOTFS_MOUNT}@LXCFSTARGETDIR@/" ]; then
- mount -n --bind @LXCFSTARGETDIR@ "${LXC_ROOTFS_MOUNT}@LXCFSTARGETDIR@/"
+if [ -d "${LXC_ROOTFS_MOUNT}{{LXCFSTARGETDIR}}/" ]; then
+ mount -n --bind {{LXCFSTARGETDIR}} "${LXC_ROOTFS_MOUNT}{{LXCFSTARGETDIR}}/"
fi
# no need for lxcfs cgroups if we have cgroup namespaces
# /sys/fs/cgroup files
if [ -d "${LXC_ROOTFS_MOUNT}/sys/fs/cgroup" ]; then
- if [ -d @LXCFSTARGETDIR@/cgroup ]; then
+ if [ -d {{LXCFSTARGETDIR}}/cgroup ]; then
# Cleanup existing mounts
for entry in "${LXC_ROOTFS_MOUNT}/sys/fs/cgroup"/*; do
DEST=$(basename "$entry")
done
# Mount the new entries
- for entry in @LXCFSTARGETDIR@/cgroup/*; do
+ for entry in {{LXCFSTARGETDIR}}/cgroup/*; do
DEST=$(basename "$entry")
if [ "$DEST" = "name=systemd" ]; then
DEST="systemd"
# SPDX-License-Identifier: LGPL-2.1-or-later
-lxcfs_conf_data = configuration_data()
-lxcfs_conf_data.set('LXCFSSHAREDIR', lxcfssharedir)
-lxcfs_conf_data = configure_file(
- configuration : lxcfs_conf_data,
- input : '00-lxcfs.conf.in',
- output : '00-lxcfs.conf',
- install: true,
- install_dir: lxcconfdir)
+lxcfs_conf_data = custom_target(
+ '00-lxcfs.conf',
+ input : '00-lxcfs.conf.in',
+ output : '00-lxcfs.conf',
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : lxcconfdir)
-lxcfs_hook_mount_data = configure_file(
- configuration : conf,
- input : 'lxc.mount.hook.in',
- output : 'lxc.mount.hook',
- install: true,
- install_dir: lxcfssharedir)
+lxcfs_hook_mount_data = custom_target(
+ 'lxc.mount.hook',
+ input : 'lxc.mount.hook.in',
+ output : 'lxc.mount.hook',
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : lxcfssharedir)
-lxcfs_hook_reboot_data = configure_file(
- configuration : configuration_data(),
- input : 'lxc.reboot.hook.in',
- output : 'lxc.reboot.hook',
- install: true,
- install_dir: lxcfssharedir)
+lxcfs_hook_reboot_data = custom_target(
+ 'lxc.reboot.hook',
+ input : 'lxc.reboot.hook.in',
+ output : 'lxc.reboot.hook',
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : lxcfssharedir)
}
TESTCASE="setup"
-lxcfs="@LXCFS_BUILD_ROOT@/lxcfs"
+lxcfs="{{LXCFS_BUILD_ROOT}}/lxcfs"
if [ -x ${lxcfs} ]; then
if [ -n "${LD_LIBRARY_PATH:-}" ]; then
- export LD_LIBRARY_PATH="@LXCFS_BUILD_ROOT@:${LD_LIBRARY_PATH}"
+ export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}:${LD_LIBRARY_PATH}"
else
- export LD_LIBRARY_PATH="@LXCFS_BUILD_ROOT@"
+ export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}"
fi
echo "=> Spawning ${lxcfs} ${LXCFSDIR}"
${lxcfs} -p ${pidfile} ${LXCFSDIR} &
LXCFSPID=$!
else
UNSHARE=0
- LXCFSPID=$(cat "@RUNTIME_PATH@/lxcfs.pid")
+ LXCFSPID=$(cat "{{RUNTIME_PATH}}/lxcfs.pid")
echo "=> Re-using host lxcfs"
rmdir $LXCFSDIR
export LXCFSDIR=/var/lib/lxcfs
# SPDX-License-Identifier: LGPL-2.1-or-later
-test_main = configure_file(
+test_programs += custom_target(
+ 'main.sh',
+ build_by_default : want_tests != false,
input : 'main.sh.in',
output : 'main.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_cgroup',
+ build_by_default : want_tests != false,
input : 'test_cgroup.in',
output : 'test_cgroup',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_confinement.sh',
+ build_by_default : want_tests != false,
input : 'test_confinement.sh.in',
output : 'test_confinement.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_meminfo_hierarchy.sh',
+ build_by_default : want_tests != false,
input : 'test_meminfo_hierarchy.sh.in',
output : 'test_meminfo_hierarchy.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_proc',
+ build_by_default : want_tests != false,
input : 'test_proc.in',
output : 'test_proc',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_read_proc.sh',
+ build_by_default : want_tests != false,
input : 'test_read_proc.sh.in',
output : 'test_read_proc.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_readdir',
+ build_by_default : want_tests != false,
input : 'test_readdir.in',
output : 'test_readdir',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_reload.sh',
+ build_by_default : want_tests != false,
input : 'test_reload.sh.in',
output : 'test_reload.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_main = configure_file(
+test_programs += custom_target(
+ 'test_sigusr2.sh',
+ build_by_default : want_tests != false,
input : 'test_sigusr2.sh.in',
output : 'test_sigusr2.sh',
- configuration : conf)
+ command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
-test_read = executable(
+test_programs += executable(
'test-read',
'test-read.c',
include_directories: config_include,
install: false,
build_by_default : want_tests != false)
-test_syscalls = executable(
+test_programs += executable(
'test-syscalls',
'test_syscalls.c',
include_directories: config_include,
'../src/cpuset_parse.c',
'../src/cpuset_parse.h')
-test_cpusetrange = executable(
+test_programs += executable(
'test-cpusetrange',
test_cpusetrange_sources,
include_directories: config_include,
trap cleanup EXIT HUP INT TERM
-lxcfs="@LXCFS_BUILD_ROOT@/lxcfs" $d &
+lxcfs="{{LXCFS_BUILD_ROOT}}/lxcfs" $d &
pid=$!
# put ourselves into x1
fi
echo "==> Testing /proc/cpuinfo"
-@LXCFS_BUILD_ROOT@/tests/test-read $DIR/proc/cpuinfo 3 >/dev/null
+{{LXCFS_BUILD_ROOT}}/tests/test-read $DIR/proc/cpuinfo 3 >/dev/null
echo "==> Testing /proc/stat"
-@LXCFS_BUILD_ROOT@/tests/test-read $DIR/proc/stat 3 >/dev/null
+{{LXCFS_BUILD_ROOT}}/tests/test-read $DIR/proc/stat 3 >/dev/null
echo "==> Testing /proc/meminfo"
-@LXCFS_BUILD_ROOT@/tests/test-read $DIR/proc/meminfo 3 >/dev/null
+{{LXCFS_BUILD_ROOT}}/tests/test-read $DIR/proc/meminfo 3 >/dev/null
exit 0
[ $(id -u) -eq 0 ]
cmdline=$(realpath $0)
-topdir=@LXCFS_BUILD_ROOT@
+topdir={{LXCFS_BUILD_ROOT}}
testdir=`mktemp -t -d libs.XXX`
installdir=`mktemp -t -d libs.XXX`
pidfile=$(mktemp)
-libdir=${installdir}/@LIBDIR@
+libdir=${installdir}/{{LIBDIR}}
bindir=${installdir}/usr/bin
lxcfspid=-1
FAILED=1
trap cleanup EXIT HUP INT TERM
echo "==> Installing lxcfs to temporary path"
-cd @LXCFS_BUILD_ROOT@
+cd {{LXCFS_BUILD_ROOT}}
DESTDIR=${installdir} meson install
if [ -n "${LD_LIBRARY_PATH:-}" ]; then
export LD_LIBRARY_PATH="${libdir}:${LD_LIBRARY_PATH}"
[ ! -f /tmp/lxcfs-iwashere ]
rm -f ${libdir}/liblxcfs.so* ${libdir}/liblxcfs.la
-cp @LXCFS_BUILD_ROOT@/liblxcfstest.so ${libdir}/liblxcfs.so
+cp {{LXCFS_BUILD_ROOT}}/liblxcfstest.so ${libdir}/liblxcfs.so
kill -USR1 ${lxcfspid}
sleep 1
--- /dev/null
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+import ast
+import os
+import re
+import sys
+
+import jinja2
+
+def parse_config_h(filename):
+ # Parse config.h file generated by meson.
+ ans = {}
+ for line in open(filename):
+ m = re.match(r'#define\s+(\w+)\s+(.*)', line)
+ if not m:
+ continue
+ a, b = m.groups()
+ if b and b[0] in '0123456789"':
+ b = ast.literal_eval(b)
+ ans[a] = b
+ return ans
+
+def render(filename, defines):
+ text = open(filename).read()
+ template = jinja2.Template(text, trim_blocks=True, undefined=jinja2.StrictUndefined)
+ return template.render(defines)
+
+if __name__ == '__main__':
+ defines = parse_config_h(sys.argv[1])
+ output = render(sys.argv[2], defines)
+ with open(sys.argv[3], 'w') as f:
+ f.write(output)
+ info = os.stat(sys.argv[2])
+ os.chmod(sys.argv[3], info.st_mode)