Montjoie's land
Gentoo, CFEngine, SELinux and other stuff for compulsive compiler

Welcome to montjoie's land

Here I will present some of the works I do.
The design is still in progress and more are coming

Managing Gentoo features with CFEngine3

For beginning, we will begins by managing the FEATURES variable of make.conf
So we need to locate where is make.conf

bundle agent gentoo
{
        classes:
                gentoo::
                        "_etc_portage_make_conf"        expression => fileexists("/etc/portage/make.conf");
                        "_etc_make_conf"                expression => fileexists("/etc/make.conf");
        vars:
                gentoo._etc_portage_make_conf.!_etc_make_conf::
                        "path_make_conf"                string => "/etc/portage/make.conf";
                gentoo._etc_make_conf.!_etc_portage_make_conf::
                        "path_make_conf"                string => "/etc/make.conf";
        reports:
                _etc_make_conf._etc_portage_make_conf::
                        "PANIC: Two make.conf present, you need to check and remove /etc/make.conf.";
                _etc_make_conf.!_etc_portage_make_conf::
                        "DEPRECATED: /etc/make.conf is a deprecated location";
gentoo.cf
With that we detect the presence of make.conf and check that only one exists.

Now we need a way to get all currents features
We will use a module for that
#!/bin/bash
#arg1 is path to make.conf

if [ $# -le 0 ];then
	echo "ERROR: Not enought argument to $0"
	exit 1
fi

if [ ! -e "$1" -o -d "$1" ];then
	echo "ERROR: Cannot found $1"
	exit 1
fi

FEATURES=`grep '^FEATURES=' $1 | cut -d\" -f2`

if [ -z "$FEATURES" ];then
	echo "+gentoo_features_none"
	exit 0
fi

GOT_ONE=0
for g_feature in $FEATURES
do
	echo "+gentoo_features_$g_feature"
	if [ $GOT_ONE -eq 0 ];then
		all_features=\"$g_feature\"
	else
		all_features=$all_features,\"$g_feature\"
	fi
	GOT_ONE=1
done
echo "@gentoo_features_list={$all_features}"
echo "+gentoo_features_read"
modules/gentoo_features2

On my computer I got this for example
./modules/gentoo_features2 /etc/portage/make.conf
+gentoo_features_splitdebug
+gentoo_features_userfetch
+gentoo_features_userpriv
+gentoo_features_webrsync-gpg
@gentoo_features_list={"splitdebug","userfetch","userpriv","webrsync-gpg"}
+gentoo_features_read
So we create classes for each feature, a classe if something is found or not and slist with all features found.

And so here is the bundle for adding a feature
bundle agent gentoo_features_add(path_make_conf, features_to_add)
{
        vars:
                gentoo_features_read::
                        "gentoo_features_list_final"    slist => {
                                "$(features_to_add)",
                                "@(gentoo_features2.gentoo_features_list)"
                        };
                        "gentoo_features_list_unique"   slist => unique("gentoo_features_list_final");
                        "gentoo_features_sort"          slist => sort("gentoo_features_list_unique", lex);
                        "gentoo_features_final"         string => join(" ", "gentoo_features_sort");
                        "make_conf[FEATURES]"           string => "\"$(gentoo_features_final)\"";
        classes:
                "modules_gentoo_features_ng_success" expression => usemodule("gentoo_features2", "$(path_make_conf)");
        files:
                "$(path_make_conf)"
                        edit_line => set_line_based("gentoo_features_add.make_conf", "=", "\s*=\s*", ".*", "\s*#\s*");
}
gentoo_helper.cf

So if you want to add the userfetch, you will use:
bundle agent gentoo
{
        classes:
		"modules_gentoo_features_ng_success" expression => usemodule("gentoo_features2", "$(path_make_conf)");
        methods:
                gentoo.gentoo_features_read.!gentoo_features_userfetch::
                        "any" usebundle => gentoo_features_add("$(path_make_conf)", "userfetch");
}

Get which GCC compiled a specific package

Something Gentoo miss is the hability to get which gcc compiled a specific package
So it is time to handle that. We will use the portage bashrc.

So we need that CFEngine deploy it
GCC_USED_VERSION="`gcc-config --get-current-profile --nocolor`"
BINUTILS_USED_VERSION="`eselect binutils show`"
/var/cfengine/masterfiles/gentoo/01_tools_versions
bundle edit_line gentoo_bashrc(bashrc_module)
{
        insert_lines:
                ". /etc/portage/bashrc.d/$(bashrc_module)";
}

bundle agent gentoo_portage_bashrc(bashrc_module)
{
	files:
		gentoo::
			"/etc/portage/bashrc.d/"
				create => "true",
				perms => mog("750", "root", "portage"),
				comment => "Ensure that /etc/portage/bashrc.d/ exists and can hold $(bashrc_module)";
			"/etc/portage/bashrc"
				edit_line => gentoo_bashrc("$(bashrc_module)"),
				create => "true",
				perms => mog("640", "root", "portage");
                        "/etc/portage/bashrc.d/$(bashrc_module)"
                                copy_from => local_dcp("$(def.inputdir)/gentoo/$(bashrc_module)"),
                                perms => mog("640", "root", "portage");

}

gentoo_helper.cf
bundle agent gentoo
{
        methods:
		gentoo::
			"any" usebundle => gentoo_portage_bashrc("01_tools_versions");
}
gentoo.cf
The file /etc/portage/bashrc is sourced at each usage of emerge and so we add two variables to the environment
You will later find GCC_USED_VERSION and BINUTILS_USED_VERSION in /var/db/pkg/xxx/xxx/environment.bz2 .
Example: which gcc has compiled net-misc/ntp ?
bzgrep GCC /var/db/pkg/net-misc/ntp-4.2.8-r1/environment.bz2 
declare -- GCC_USED_VERSION="armv7a-hardfloat-linux-gnueabi-4.8.3"

Checking ebuilds with GPG

One of the great missing features of gentoo is the signing of ebuild and the automatic checking of theses signatures. Signing of ebuilds have beginining (See the mailing list conversations about ebuild GPG signing and the documentation about Signing manifest). But for the moment, there are no way to automaticly check it.

Just for the statistics, 13730 Manifests out of 18320 in the portage tree are signed at the moment of writing.
The ratio of signed manifests is slowy growing.

So for checking thoses signatures, there are two custom methods,

Checking Manifests GPG signatures with webrsync-gpg

The first easy way is to use webrsync for syncing portage tree.
The portage tree archive used by webrsync is signed by the Gentoo Linux Release Engineering.
So what we need to enable gpg check of the portage tree received by webrsync with CFEngine ? For enabling some FEATURES, we will use the module presented here (TODO link).
Same thing for adding/removing GPG keys, we will use a module.
#!/bin/sh
# add key $2(without 0x) to homedir $1
# also set class tool_dont_have_gpg or tool_have_gpg

#TODO specify gpg servers
#TODO timeout

MODULE_CLASS="`basename $0`"

if [ -z "$1" -o -z "$2" ];then
	echo "+${MODULE_CLASS}_error"
	exit 1
fi

if [ ! -x /usr/bin/gpg ];then
	echo "+tool_dont_have_gpg"
	exit 0
fi
echo "+tool_have_gpg"

HOMEDIR="$1"
KEYSERVERS="subkeys.pgp.net keys.gnupg.net"
KEYID="$2"
HOMEDIR_CANON=`echo $HOMEDIR | tr "/+-" _`

CACHEDIR="/var/cache/cfengine/"
GPGOPTS="--batch --no-tty --no-permission-warning"

CACHEFILE="$CACHEDIR/${HOMEDIR_CANON}.gpg"

generate_cache() {
	gpg $GPGOPTS --homedir $HOMEDIR -k --with-colons > $CACHEFILE
	if [ $? -ne 0 ];then
		echo "+${MODULE_CLASS}_error"
		exit 0
	fi
}

#Clean outdated cache
if [ -e "$CACHEFILE" ];then
	if [ ! -e "${HOMEDIR}/pubring.gpg" ];then
		rm "$CACHEFILE"
	else
		STAT_CACHE="`stat --format=%Y $CACHEFILE`"
		STAT_PUBRING="`stat --format=%Y ${HOMEDIR}/pubring.gpg`"
		if [ $STAT_PUBRING -gt $STAT_CACHE ];then
			rm "$CACHEFILE"
		fi
	fi
fi

if [ ! -e "$CACHEFILE" ];then
	generate_cache
fi

if [ ! -e "$CACHEFILE" ];then
	echo "+${MODULE_CLASS}_error"
	exit 0
fi

if [ -z "`grep $KEYID $CACHEFILE`" ];then
	if [ "$3" != 'remove' ];then
		GPG_GETKEY_SUCCESS=0
		for gpgsrv in $KEYSERVERS
		do
			gpg $GPGOPTS --homedir $HOMEDIR --keyserver $gpgsrv --recv-keys $KEYID
			if [ $? -eq 0 ];then
				GPG_GETKEY_SUCCESS=1
				break;
			fi
		done
		if [ $GPG_GETKEY_SUCCESS -eq 0 ];then
			echo "+${MODULE_CLASS}_error"
			exit 1
		fi
		generate_cache
		echo "+${MODULE_CLASS}_${HOMEDIR_CANON}_$KEYID"
	fi
else
	if [ "$3" = 'remove' ];then
		gpg $GPGOPTS --yes --homedir $HOMEDIR --delete-key $KEYID
		if [ $? -ne 0 ];then
			echo "+${MODULE_CLASS}_error"
			exit 0
		fi
		generate_cache
		exit 0
	fi
	echo "+${MODULE_CLASS}_${HOMEDIR_CANON}_$KEYID"
fi
exit 0
modules/gpg
With this module we add/remove gpg key on a specfifc gpg keystore. And now, assemble all this stuff in a bundle.
bundle agent gentoo_gpg
{
	methods:
		#GPG keys found at http://www.gentoo.org/proj/en/releng/index.xml
		gentoo_features_webrsync_gpg::
			"any" usebundle => gpg_helper("/etc/portage/gpg/", "DB6B8C1F96D8BF6D", "add");
			"any" usebundle => gpg_helper("/etc/portage/gpg/", "BB572E0E2D182910", "add");
			"any" usebundle => gpg_helper("/etc/portage/gpg/", "9E6438C817072058", "add");
			"any" usebundle => gpg_helper("/etc/portage/gpg/", "239C75C4", "remove");
		gentoo::
			"any" usebundle => gentoo_pkg("app-crypt/gnupg", "yes");
			"any" usebundle => gentoo_portage_bashrc("10_gpg");

	files:
		gentoo::
			"/etc/portage/gpg/"
				create => "true",
				perms => mog("750", "root", "portage");
}
gentoo_gpg.cf
But I dislike this methods because the signing of the tree is done automaticly, so I use the next method.

Checking Manifests GPG signatures at merging time

This methods simply checks GPG signatures on the "setup" phase of emerge.
HAVE_GPG=0
if [ ! -x /usr/bin/gpg ];then
	ewarn "Cannot check gpg signatures of manifest, gpg tool not found"
else
	HAVE_GPG=1
fi

#FEATURES x-gpg, adding a feature need to patch /usr/lib/portage/pym/portage/const.py ?
#if has x-checkportagegpg ${FEATURES} ; then
#	einfo "Need to check gpg"
#fi


GPG_DIR='/etc/portage/manifest_gpg'
GPGOPT="--homedir $GPG_DIR --keyserver-options timeout=5 --no-permission-warning"
GPGSRV='subkeys.pgp.net keys.gnupg.net'
#TODO set GPG_FATAL to 1 to make gpg check mandatory
GPG_FATAL=1

if [ "$EBUILD_PHASE" = 'setup' -a ${HAVE_GPG} -eq 1 ] ; then
	#How to ckeck in /usr/local/portage ?? I do not found a variable with full path to ebuild, so the hack with FILESDIR
	MANIFEST_TO_CHECK="`echo ${FILESDIR}/Manifest | sed 's,/files/,/,'`"
	if [ -e "$MANIFEST_TO_CHECK" ] ; then
		if [ -z "`grep 'PGP SIGN' $MANIFEST_TO_CHECK`" ] ; then
			einfo "No GPG signature in $MANIFEST_TO_CHECK"
		else
			if [ ! -e "$GPG_DIR" ];then
				mkdir -p $GPG_DIR
				chmod 700 $GPG_DIR
				chown root:portage $GPG_DIR
			fi
			GPG_OUT=`mktemp`
			LC_ALL=C gpg $GPGOPT --batch --verify $MANIFEST_TO_CHECK 2>$GPG_OUT
			if [ $? -ne 0 ] ; then
				KEYID="`grep ID $GPG_OUT | sed 's,.*ID ,,'`"
				if [ -z "$KEYID" ];then
					rm $GPG_OUT
					die "No keyid found"
					exit 1
				fi
				einfo "Found GPG keyID $KEYID"
				GPG_GETKEY_SUCCESS=0
				for gpgsrv in $GPGSRV
				do
					gpg $GPGOPT --keyserver $gpgsrv --recv-keys $KEYID
					if [ $? -ne 0 ] ;then
						ewarn "Cannot get gpg key with $gpgsrv"
					else
						GPG_GETKEY_SUCCESS=1
						break
					fi
				done
				if [ $GPG_GETKEY_SUCCESS -eq 0 ];then
					if [ $GPG_FATAL -eq 1 ];then
						rm $GPG_OUT
						die "Cannot get key from all gpg servers"
					else
						eerror "Cannot get key from all gpg servers"
					fi
				fi
				gpg $GPGOPT --batch --verify $MANIFEST_TO_CHECK 2>$GPG_OUT
				if [ $? -ne 0 ] ;then
					if [ $GPG_FATAL -eq 1 ];then
						rm $GPG_OUT
						die "GPG signature is invalid"
					else
						eerror "GPG signature is invalid"
					fi
				else
					einfo "Found valid GPG signature for $MANIFEST_TO_CHECK"
				fi
			else
				einfo "Found valid GPG signature for $MANIFEST_TO_CHECK"
			fi
			rm $GPG_OUT
		fi
	else
		ewarn "No Manifest found, cannot check gpg signatures ($MANIFEST_TO_CHECK)"
	fi
fi
10_gpg
Enabling this checking is done on the previous gentoo_gpg bundle.
Since portage source /etc/portage/bashrc, we create a bashrc.d/10_gpg and source it.
Et voila, you coud see something like:
emerge -b1 sys-apps/texinfo
Calculating dependencies... done!

>>> Verifying ebuild manifests

>>> Emerging (1 of 1) sys-apps/texinfo-4.13-r2

 * texinfo-4.13.tar.lzma SHA256 SHA512 WHIRLPOOL size ;-) ...    [ ok ]
 * Found valid GPG signature for /usr/portage/sys-apps/texinfo/Manifest
>>> Unpacking source...

Checking your hardware automatically

All my physical machines have to be monitored.
You can monitor many things, hard drive health, temperatures etc...
For doing this, first you need to get informations, if the host is a virtual machine and for some test, which cpu flags are available.
All those informations will be given by modules

Detecting if the host is a virtual machine or not

This module detect VMware, Xen, lxc/cgroup and QEMU.
The strategy is to check hardware vendor name in PCI/SCSI hardware name and/or presence of device files.
#!/bin/sh

if [ -e /proc/xen -a ! -e /proc/bus/pci ];then
	echo "+virtual_machine"
	echo "+virtual_xen"
	exit 0
fi

if [ -e /proc/cpuinfo ];then
	if [ ! -z "`grep QEMU /proc/cpuinfo`" ];then
		echo "+virtual_machine"
		echo "+virtual_qemu"
		exit 0
	fi
	if [ ! -z "`grep '^flags.*hypervisor' /proc/cpuinfo`" ];then
		echo "+virtual_machine"
	fi
fi

if [ -e /proc/scsi/scsi ];then
	if [ ! -z "`grep VMware /proc/scsi/scsi`" ];then
		echo "+virtual_machine"
		echo "+virtual_vmware"
		exit 0
	fi
	if [ ! -z "`grep VBOX /proc/scsi/scsi`" ];then
		echo "+virtual_machine"
		echo "+virtual_virtualbox"
		exit 0
	fi
fi

which lspci 2> /dev/null > /dev/null
if [ $? -eq 0 ];then
	if [ ! -e /var/cache/cfengine/ ];then
		mkdir -p /var/cache/cfengine/
	fi
	lspci > /var/cache/cfengine/lspci
	if [ $? -ne 0 ];then
		echo "ERROR: lspci"
	fi
	if [ ! -z "`grep VirtualBox /var/cache/cfengine/lspci`" ];then
		echo "+virtual_machine"
		echo "+virtual_virtualbox"
		exit 0
	fi
	if [ ! -z "`grep VMware /var/cache/cfengine/lspci`" ];then
		echo "+virtual_machine"
		echo "+virtual_vmware"
		exit 0
	fi
fi

#BSD
if [ ! -e /proc ];then
	if [ ! -z "`sysctl hw |grep QEMU`" ];then
		echo "+virtual_machine"
		echo "+virtual_qemu"
		exit 0
	fi
fi

#LXC
if [ -e /proc/1/cgroup ];then
	if [ ! -z "`grep lxc /proc/1/cgroup`" ];then
		echo "+virtual_machine"
		echo "+virtual_lxc"
		exit 0
	fi
fi

echo "+hw_physical"

exit 0
modules/detect_vm

Checking cpu flag

This tasks is easy under Linux, you have just to check /proc/cpuinfo. But under BSD systems, I do not have found an easy way.
#!/bin/sh
#Check the presence of all cpu flags

if [ ! -e /proc/cpuinfo ];then
        exit 0
fi

if [ -e /proc ];then
        if [ -z "`grep -E '^flags|^Features' /proc/cpuinfo`" ];then
                echo "ERROR: $0 Cannot detect cpuflags"
                exit 1
        fi
        ALLFLAGS=`grep -E '^flags|^Features' /proc/cpuinfo | cut -d\: -f2 | sort | uniq`
else
#BSD
#FreeBSD ? grep Features /var/run/dmesg.boot
#OpenBSD grep -i nx /var/run/dmesg.boot
#cp0: FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,CX16,NXE,LONG
#ARM ^Features:
        if [ -e /var/run/dmesg.boot ];then
                ALLFLAGS=`grep 'cpu0:.*FPU' /var/run/dmesg.boot | cut -d\  -f2 | tr [A-Z] [a-z] | tr \, \ `
        else
                echo "ERROR: $0 Cannot detect cpuflags"
                exit 1
        fi
fi

for cpuflag in $ALLFLAGS
do
        echo "+cpuflag_$cpuflag"
done

exit 0
modules/cpuflag
Example for my CPU:
./modules/cpuflag 
+cpuflag_fpu
+cpuflag_mmx
+cpuflag_sse
+cpuflag_sse2
+cpuflag_ss
+cpuflag_ht
+cpuflag_tm
+cpuflag_pbe
+cpuflag_syscall
+cpuflag_nx
..[SNIP]..
+cpuflag_flexpriority

Getting more hardware informations

#!/bin/sh

MODULE_CLASS="`basename $0`"

if [ -e /dev/watchdog ];then
	echo +hw_watchdog
fi

if [ ! -e /proc/acpi -a -e /proc/cpuinfo ];then
        if [ ! -z "`grep 'Hardware.*BCM2708' /proc/cpuinfo`" ];then
                echo "+hw_raspberrypi"
        fi
fi

if [ -e /proc/cpuinfo ];then
	if [ ! -z "`grep '^Hardware[[:space:]]*:[[:space:]]*sun7i' /proc/cpuinfo`" ];then
		echo "+hw_cubieboard2"
	fi
	if [ ! -z "`grep '^Hardware[[:space:]]*:[[:space:]]Allwinner[[:space:]]sun7i' /proc/cpuinfo`" ];then
		echo "+hw_cubieboard2"
	fi
fi

if [ -e /proc/scsi/scsi ];then
	if [ ! -z "`grep ^Host /proc/scsi/scsi`"  ];then
		echo "+hw_have_disk"
	else
		echo "+hw_have_no_disk"
	fi
fi

if [ -e /dev/rtc0 ];then
	echo "+hw_have_rtc"
fi

if [ -e /dev/nvidia0 -o -e /dev/nvidiactl ];then
	echo "+hw_have_nvidia_gpu"
fi

if [ -e /proc/swaps ];then
	if [ ! -z "`grep -v ^Filename /proc/swaps`" ];then
		echo "+hw_have_swap"
	else
		echo "+hw_have_no_swap"
	fi
fi

CACHEDIR='/var/cache/cfengine/'
if [ ! -e "$CACHEDIR" ];then
	echo "ERROR: $CACHEDIR does not exist"
	echo "+${MODULE_CLASS}__error"
	exit 1
fi

if [ -e /sys/class/hwmon/hwmon0 ];then
	echo "+hw_have_sensors"
	if [ -x /usr/bin/sensors ];then
		SENSORS_CACHE='/var/cache/cfengine/sensors'
		sensors > $SENSORS_CACHE
		if [ $? -eq 0 ];then
			if [ ! -z "`grep '°C' $SENSORS_CACHE`" ];then
				echo "+hw_have_sensors_temp"
			fi
			if [ ! -z "`grep 'RPM' $SENSORS_CACHE`" ];then
				echo "+hw_have_sensors_fan"
			fi
			if [ ! -z "`grep 'Voltage' $SENSORS_CACHE`" ];then
				echo "+hw_have_sensors_volt"
			fi
		else
			echo "ERROR: $0 sensors"
		fi
	else
		echo "WARNING: $0 no sensors binary"
	fi
fi

SMARTCTL='/usr/sbin/smartctl'
if [ -e "${SMARTCTL}" ];then
	SMARTCTL_CACHE='/var/cache/cfengine/smartctl'
	smartctl --scan-open > $SMARTCTL_CACHE
	RET=$?
	if [ $RET -eq 0 ];then
		if [ ! -z "`grep -iE 'aborted matching pattern /dev/discs/disc' $SMARTCTL_CACHE`" ];then
			RET=1
		else
			if [ ! -z "`grep -v '^/' $SMARTCTL_CACHE`" ];then
				echo "ERROR: $0 `head -n1 $SMARTCTL_CACHE`"
				RET=1
			fi
		fi
	fi
	if [ $RET -eq 0 ];then
		DISKLIST="@smartdisklist={"
		GOT_ONE=0
		while read line
		do
			DISKNAME="`echo $line | cut -d\  -f1 | cut -d/ -f3`"
			if [ ! -z "$DISKNAME" ];then
				if [ "$GOT_ONE" -ge 1 ];then
					DISKLIST="${DISKLIST},"
				fi
				DISKLIST="$DISKLIST\"$DISKNAME\""
				GOT_ONE=1
			fi
		done < $SMARTCTL_CACHE
		if [ $GOT_ONE -ge 1 ];then
			DISKLIST="${DISKLIST}}"
			echo "$DISKLIST"
			echo "+hw_have_smart_disk"
		fi
	else
		echo "ERROR: $0 smartctl"
	fi
fi

if [ -e /proc/net/dev ];then
	IFACE_CACHE='/var/cache/cfengine/iface_list'
	grep ':' /proc/net/dev | sed 's,^[[:space:]]*\([a-z0-9][a-z0-9]*\):.*,\1,' | grep -vE '^tun[0-9]|^lo$|^br[0-9]|^sit[0-9]' > $IFACE_CACHE
	if [ ! -z "`cat $IFACE_CACHE`" ];then
		echo "+hw_have_network_interfaces"
		IFACE_LIST="@hw_ifacelist={"
		GOT_ONE=0
		while read iface
		do
			echo "+hw_have_net_$iface"
			if [ "$GOT_ONE" -ge 1 ];then
				IFACE_LIST="${IFACE_LIST},"
			fi
			IFACE_LIST="${IFACE_LIST}\"$iface\""
			GOT_ONE=1
		done < $IFACE_CACHE
		IFACE_LIST="${IFACE_LIST}}"
		echo $IFACE_LIST
	fi
fi

if [ -e /proc/acpi ];then
	echo "+hw_acpi"
fi

if [ -e /sys/devices/system/cpu/cpufreq -o -e /sys/bus/platform/drivers/cpufreq-dt -o -e /sys/devices/system/cpu/cpu0/cpufreq ];then
	echo "+hw_cpufreq"
else
	echo "+hw_no_cpufreq"
fi

exit 0
modules/detect_hw

MCE

With recent hardware comes MCE (Machine Check Exception)
MCE permits to detect some hardware errors, like processor getting too hot or bad memory banks.
You can check if your processor support it by the presence of the flag mce in /proc/cpuflag
grep flags /proc/cpuinfo
flags  : fpu vme de pse tsc msr pae mce cx8 apic...
If you have such flag, you need app-admin/mcelog for recording and decoding MCE recording

Deploying mcelog

So I deploy mcelog only on a physical system with the MCE flag present.
bundle agent mcelog
{
        classes:
                "detect_vm_success" expression => usemodule("detect_vm", "");
                !virtual_machine::
                        "cpuflag_success" expression => usemodule("cpuflag", "");
                restart_mcelog.!mcelog_restarted::
                        "restart_mcelog_success" expression => usemodule("restarter", "mcelog restart");
        methods:
                gentoo.cpuflag_mce.!virtual_machine::
                        "any" usebundle => gentoo_pkg("app-admin/mcelog", "yes");
                        "any" usebundle => gentoo_rc("mcelog", "default", "yes", "yes");

}
mcelog.cf

Deploying smartmontools

All moderns hard-drive support SMART which is a technology for monitoring their status.
So on non-virtual machine I deploy sys-apps/smartmontools
Then the configuration for automatic short test is generated
bundle edit_line smart_self_check(disk)
{
	insert_lines:
	"/dev/$(disk) -s S/../../1/10";
}

bundle agent smartd
{
	classes:
		"etc_smartd_conf" expression => fileexists("/etc/smartd.conf");
		"detect_vm_success" expression => usemodule("detect_vm", "");
		"module_hw_success" expression => usemodule("detect_hw", "");
		restart_smartd.!smartd_restarted::
			"restart_smartd_success" expression => usemodule("restarter", "smartd restart");
	methods:
		gentoo.detect_vm_success.!virtual_machine.!hw_raspberrypi.hw_have_disk::
			"any" usebundle => gentoo_pkg("sys-apps/smartmontools", "yes");
			"any" usebundle => gentoo_rc("smartd", "default", "yes", "yes");
			"any" usebundle => gentoo_use("caps", "/", "yes", "sys-apps/smartmontools", "yes");
		gentoo.virtual_machine::
			"any" usebundle => gentoo_pkg("sys-apps/smartmontools", "no");
	files:
		etc_smartd_conf::
			"/etc/smartd.conf"
			perms => mog("640", "root", "root");
		etc_smartd_conf.hw_have_disk::
			"/etc/smartd.conf"
				edit_line => smart_self_check($(detect_hw.smartdisklist)),
				classes => if_repaired("restart_smartd");
	processes:
		etc_smartd_conf.hw_have_disk::
			"/usr/sbin/smartd"
				restart_class => "restart_smartd";
}

smartd.cf

Handling Gentoo global USE flags

Handling Gentoo USE flags for specific package

Managing SELinux with CFEngine

Securing a Gentoo part 1: Cleaning users

bundle agent clean_users
{
	classes:
		"etc_passwd_uucp" expression => userexists("uucp");
		"etc_passwd_news" expression => userexists("news");
		"etc_passwd_proxy" expression => userexists("proxy");
		"etc_passwd_gopher" expression => userexists("gopher");
	commands:
		etc_passwd_uucp::
			"/usr/sbin/userdel uucp";
		etc_passwd_news::
			"/usr/sbin/userdel news";
		etc_passwd_proxy::
			"/usr/sbin/userdel proxy";
		etc_passwd_gopher::
			"/usr/sbin/userdel gopher";
}

Securing a Gentoo part 2: Removing default services

Securing a Gentoo part 3: Securing access

CFEngine: gentoo: Handling packages and services

Deploying postfix with CFEngine

CFEngine: postfix: Minimal postfix in satellite mode

CFEngine: postfix: Real Postfix server

CFEngine: Managing xymon

CFEngine: xymon: checking NTP

CFEngine: xymon: checking SMART

CFEngine: xymon: checking gentoo

CFEngine: xymon: checking libs

CFEngine: xymon: checking postfix

CFEngine: xymon: checking logrotate

CFEngine: xymon: checking logs

CFEngine: xymon: checking batchs and cron

CFEngine: xymon: checking sensors