Here I will present some of the works I do.
The design is still in progress and more are coming
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";
#!/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 /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
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*"); }
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"); }
GCC_USED_VERSION="`gcc-config --get-current-profile --nocolor`" BINUTILS_USED_VERSION="`eselect binutils show`"
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"); }
bundle agent gentoo { methods: gentoo:: "any" usebundle => gentoo_portage_bashrc("01_tools_versions"); }
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"
#!/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
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"); }
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
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...
#!/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
#!/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 +cpuflag_fpu +cpuflag_mmx +cpuflag_sse +cpuflag_sse2 +cpuflag_ss +cpuflag_ht +cpuflag_tm +cpuflag_pbe +cpuflag_syscall +cpuflag_nx ..[SNIP].. +cpuflag_flexpriority
#!/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
grep flags /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic...
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"); }
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"; }
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"; }