
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://www.funtoo.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.funtoo.org/api.php?action=feedcontributions&amp;user=Golodhrim&amp;feedformat=atom</id>
		<title>Funtoo Linux - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://www.funtoo.org/api.php?action=feedcontributions&amp;user=Golodhrim&amp;feedformat=atom"/>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Special:Contributions/Golodhrim"/>
		<updated>2013-05-23T11:41:09Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.20.6</generator>

	<entry>
		<id>http://www.funtoo.org/wiki/ZFS_rootfs_over_encrypted_container</id>
		<title>ZFS rootfs over encrypted container</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/ZFS_rootfs_over_encrypted_container"/>
				<updated>2013-04-24T23:08:28Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial will show you how to install Funtoo on ZFS (rootfs) over an encrypted container.&lt;br /&gt;
&lt;br /&gt;
This tutorial is meant to be an &amp;quot;overlay&amp;quot; over the [[Funtoo_Linux_Installation|Regular Funtoo Installation]]. Follow the normal installation and only use this guide for steps 2, 3, and 8.&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|'''Since ZFS was really designed for 64 bit systems, we are only recommending and supporting 64 bit platforms and installations. We will not be supporting 32 bit platforms'''!}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting up your environment ==&lt;br /&gt;
In order for us to install Funtoo on ZFS, you will need an environment that provides the ZFS userspace tools. We will be downloading two things, System Rescue CD 3.1.2, and the ZFS SRM (System Rescue Module). This is just a file that when combined with System Rescue CD, gives you ZFS functionality.&lt;br /&gt;
&lt;br /&gt;
[https://sourceforge.net/projects/systemrescuecd/files/sysresccd-x86/3.1.2/systemrescuecd-x86-3.1.2.iso/download Download System Rescue CD 3.1.2]&lt;br /&gt;
&lt;br /&gt;
[http://jonathanvasquez.com/files/sysresccd/ Download the ZFS System Rescue Module]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name: SystemRescueCd-x86-3.1.2 (350 MiB)&lt;br /&gt;
Release Date: 2012-12-05&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
md5sum 3c1ddfe5f26bb2f979a2ed9dfb504ee3&lt;br /&gt;
sha1sum 217cf7a81380d894b2433c59451787c16bc0af2f&lt;br /&gt;
sha256sum ec0a995875e64ff9816a043737e5cbbb689b7f596b48679116f0a779f3dce673&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you place the ISO on your USB flash drive, extract the modules from the tarball, and place the .srm and .md5 at the root of your USB filesystem. Further instructions can be found [[Creating_System_Rescue_CD_Modules#Using_the_prebuilt_srm|here]]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will now start to partition the system. Open up a terminal, and type in the following (We will assume it's a fresh drive for simplicity).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating partitions ==&lt;br /&gt;
We will be creating two partitions, /boot, and the remaining disk space will be for ZFS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(All commands will be ran as root).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fdisk (MBR Style) ===&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (ZFS over encrypted container):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
Command: ##i##t ↵&lt;br /&gt;
Partition number: ##i##2 ↵&lt;br /&gt;
Hex code (type L to list codes): ##i##bf ↵&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes&lt;br /&gt;
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors&lt;br /&gt;
Units = sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disk identifier: 0x3e954df7&lt;br /&gt;
   Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;
/dev/sda1            2048      514047      256000   83  Linux&lt;br /&gt;
/dev/sda2          514048  1953525167   976505560   bf  Solaris&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gdisk (GPT Style) ===&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
Hex Code: ##i##↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (BIOS Boot Partition):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+32M ↵&lt;br /&gt;
Hex Code: ##i##EF02 ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|Only make the above BIOS Boot Partition if you are using GRUB 2 on GPT. If you are using the extlinux bootloader, this partition is not necessary. The below instructions continue as if you did not create this partition and assumes you are using extlinux as the bootloader.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2(/3)''' (ZFS over encrypted container):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
Hex Code: ##i##bf01 ↵&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
Disk /dev/sda: 1953525168 sectors, 931.5 GiB&lt;br /&gt;
Logical sector size: 512 bytes&lt;br /&gt;
Disk identifier (GUID): C0C1E56A-B24F-492F-95DB-2E227676F228&lt;br /&gt;
Partition table holds up to 128 entries&lt;br /&gt;
First usable sector is 34, last usable sector is 1953525134&lt;br /&gt;
Partitions will be aligned on 2048-sector boundaries&lt;br /&gt;
Total free space is 2014 sectors (1007.0 KiB)&lt;br /&gt;
Number  Start (sector)    End (sector)  Size       Code  Name&lt;br /&gt;
   1            2048          514047   250.0 MiB   8300  Linux filesystem&lt;br /&gt;
   2          514048      1953525134   931.3 GiB   BF01  Solaris /usr &amp;amp; Mac ZFS&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Format your boot volume ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkfs.ext2 /dev/sda1&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the crypto container ===&lt;br /&gt;
Be aware that this step will take a lot of time, 1-2 days might be possible depending on your disksize. The bs part in the next commands is important, so that you don't know about the actual disksize and the disk get's filled up to the end with data for the cryptocontainer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##dd if=/dev/zero of=/dev/sda2 bs=100M&lt;br /&gt;
# ##i##dd if=/dev/urandom of=/dev/sda2 bs=100M&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next we will create the cryptocontainer in the before prepared partition and mount the container after that:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cryptsetup -c aes-xts-plain64 luksFormat /dev/sda2&lt;br /&gt;
# ##i##cryptsetup luksOpen /dev/sda2 enc-root&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This opens the cryptocontainer in '''/dev/mapper/enc-root''', what will from now on the device for our ZFS pool.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the zpool ===&lt;br /&gt;
We will first create the pool. The pool will be named `rpool` and the disk will be aligned to 4096 (using ashift=12)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool create -f -o ashift=12 -o cachefile= -O compression=on -m none -R /mnt/funtoo rpool /dev/mapper/enc-root&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the zfs datasets ===&lt;br /&gt;
We will now create some datasets. For this installation, we will create a small but future proof amount of datasets. We will have a dataset for the OS (/), and your swap. We will also show you how to create some optional datasets: /home, /var, /usr/src, and /usr/portage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Create some empty containers for organization purposes, and make the dataset that will hold /&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/ROOT&lt;br /&gt;
# ##i##zfs create -o mountpoint=/ rpool/ROOT/funtoo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Optional, but recommended datasets: /home, /root &lt;br /&gt;
# ##i##zfs create -o mountpoint=/home rpool/HOME&lt;br /&gt;
# ##i##zfs create -o mountpoint=/root rpool/HOME/root&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Optional datasets: /usr/src, /var&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/FUNTOO&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/src rpool/FUNTOO/src&lt;br /&gt;
# ##i##zfs create -o mountpoint=/var rpool/FUNTOO/var&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Creating a separate portage dataset (optional) ====&lt;br /&gt;
Creating a separate portage dataset could be useful if you would like to keep your portage tree, distfiles (source code files), and packages (your compiled binaries if you have FEATURES=&amp;quot;buildpkg&amp;quot; enabled) in a safe place (or if you want to back up this directory up easily).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This requires a few extra steps because we can't just do a regular emerge --sync when we initially chroot. We will need to download a portage snapshot tarball and extract it into the directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The required steps for getting and extracting the snapshot will be shown later on in the guide once you chroot into the environment. For now just create the datasets:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage -o compression=off rpool/FUNTOO/portage&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage/distfiles -o compression=off rpool/FUNTOO/distfiles&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create your swap dataset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Make your swap +1G greater than your RAM. An 8G machine would have 9G of RAM (This is kinda big though).'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 9G rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Format your swap dataset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkswap -f /dev/zvol/rpool/swap&lt;br /&gt;
# ##i##swapon /dev/zvol/rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alright that finishes the creation of the zpool and zfs datasets. Check to make sure everything appears fine:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Copy the zpool.cache file to your new environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkdir -p /mnt/funtoo/etc/zfs&lt;br /&gt;
# ##i##cp /etc/zfs/zpool.cache /mnt/funtoo/etc/zfs&lt;br /&gt;
You might also need to copy your zdev.conf file:&lt;br /&gt;
# ##i##cp /etc/zfs/zdev.conf /mnt/funtoo/etc/zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Make an empty mtab file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##touch /mnt/funtoo/etc/mtab&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we will continue to install funtoo.&lt;br /&gt;
&lt;br /&gt;
== Installing Funtoo ==&lt;br /&gt;
[[Funtoo_Linux_Installation|Download and install the Funtoo stage3 and continue installation as normal.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then chroot into your new funtoo environment:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mount your boot drive&lt;br /&gt;
# ##i##mount /dev/sda1 /mnt/funtoo/boot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bind the kernel related directories&lt;br /&gt;
# ##i##for i in proc dev sys; do mount --bind /$i ./$i; done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Copy network settings&lt;br /&gt;
# ##i##cp /etc/resolv.conf etc/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
chroot into your new funtoo environment&lt;br /&gt;
# ##i##env -i HOME=/root TERM=$TERM chroot . bash -l&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Syncing your portage tree ===&lt;br /&gt;
==== If you didn't create a separate portage dataset, then just sync your portage tree as normal. ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== If you did create a separate portage dataset, let's now get the portage snapshot set up. ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Change into your /usr directory&lt;br /&gt;
# ##i##cd /usr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download and extract the portage snapshot&lt;br /&gt;
# ##i##wget http://ftp.osuosl.org/pub/funtoo/funtoo-current/snapshots/portage-latest.tar.xz&lt;br /&gt;
# ##i##tar xf portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Change into your portage directory and checkout the funtoo branch&lt;br /&gt;
# ##i##cd portage&lt;br /&gt;
# ##i##git checkout funtoo.org&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now sync your portage tree&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kernel Configuration ==&lt;br /&gt;
Tested with kernel 2.6.32, 3.2.34, 3.6.9, 3.7.1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you get up to the kernel, make sure that you disable the CFQ scheduler, and turnon No-op (It's the default one once you disable all schedulers). The reason for this is because ZFS has itsown scheduler and the CFQ one conflicts with it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to your kernel config, and make sure you have the following: (there should be a /usr/src/linux symlink as well)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ZLIB_INFLATE/DEFLATE must be compiled into the kernel (not as a module).&lt;br /&gt;
&amp;gt; ZLIB_INFLATE [=y], ZLIB_DEFLATE [=y]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
General setup ---&amp;gt;&lt;br /&gt;
&amp;gt; [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support&lt;br /&gt;
&amp;gt; () Initramfs source file(s)&lt;br /&gt;
[*] Enable loadable module support ---&amp;gt;&lt;br /&gt;
[*] Module unloadingEnable the block layer ---&amp;gt;&lt;br /&gt;
IO Schedulers ---&amp;gt;&lt;br /&gt;
&amp;lt; &amp;gt; Deadline I/O scheduler&lt;br /&gt;
&amp;lt; &amp;gt; CFQ I/O schedulerDefault I/O scheduler (No-op)&lt;br /&gt;
Device Drivers ---&amp;gt;&lt;br /&gt;
&amp;gt; Generic Driver Options ---&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; [*] Maintain a devtmpfs filesystem to mount at /dev&lt;br /&gt;
&amp;gt;&amp;gt; [*] Automount devtmpfs at /dev, after the kernel mounted the rootfs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cryptographic API ---&amp;gt;&lt;br /&gt;
&amp;gt; &amp;lt;*&amp;gt; XTS support&lt;br /&gt;
&amp;gt; -*- AES cipher algorithms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* All other drivers required to see your PATA/SATA drives must be compiled in.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue and compile/install your kernel:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##make bzImage&lt;br /&gt;
# ##i##make modules_install&lt;br /&gt;
# ##i##cp arch/x86_64/boot/bzImage /boot/bzImage-&amp;lt;Kernel-version&amp;gt;&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the ZFS userspace tools ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -av zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check to make sure that the zfs tools are working, the zpool.cache file that you copied before should be displayed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If everything worked, continue.&lt;br /&gt;
&lt;br /&gt;
== Bliss Initramfs Creator ==&lt;br /&gt;
Make sure you compile sys-apps/busybox and sys-fs/cryptsetup with the static flag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##echo &amp;quot;sys-apps/busybox static&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/busybox&lt;br /&gt;
# ##i##echo &amp;quot;sys-fs/cryptsetup static&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/cryptsetup&lt;br /&gt;
# ##i##echo &amp;quot;sys-libs/e2fsprogs-libs static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/e2fsprogs-libs&lt;br /&gt;
# ##i##echo &amp;quot;dev-libs/popt static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/popt&lt;br /&gt;
# ##i##echo &amp;quot;sys-apps/util-linux static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/util-linux&lt;br /&gt;
# ##i##emerge -avt sys-apps/busybox sys-fs/cryptsetup&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone my creator which is located at: git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##git clone git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
# ##i##cd Bliss-Initramfs-Creator&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run the script as root, and place the initrd into /boot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##./createInit&lt;br /&gt;
Choose Option 2 ZFS+LUKS&lt;br /&gt;
# ##i##mv initrd-&amp;lt;kernel_name&amp;gt;.img /boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;kernel_name&amp;gt;''' is the name of what you selected in the initramfs creator, and the name of the outputted file.&lt;br /&gt;
&lt;br /&gt;
Once you do this just go to your bootloader config, and add it in there.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 kernel name is: bzImage-3.7.1-ALL&lt;br /&gt;
 initramfs name is: initrd-3.7.1-ALL.img&lt;br /&gt;
 pool root is: rpool/ROOT/funtoo&lt;br /&gt;
 encrypted root is: /dev/sda2&lt;br /&gt;
&lt;br /&gt;
== Installing Extlinux ==&lt;br /&gt;
To install extlinux first merge syslinux&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt syslinux&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
next prepare your /boot folder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##install -d /boot/extlinux&lt;br /&gt;
# ##i##extlinux --install /boot/extlinux&lt;br /&gt;
# ##i##cd /boot&lt;br /&gt;
# ##i##ln -s . boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally install Extlinux for your Boot Record&lt;br /&gt;
&lt;br /&gt;
=== MBR ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/mbr.bin of=/dev/sda&lt;br /&gt;
# ##i##cp /usr/share/syslinux/menu.c32 /boot/extlinux/&lt;br /&gt;
# ##i##touch /boot/extlinux/extlinux.conf&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GPT ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##sgdisk /dev/sda --attributes=1:set:2&lt;br /&gt;
# ##i##sgdisk /dev/sda --attributes=1:show&lt;br /&gt;
1:2:1 (legacy BIOS bootable)&lt;br /&gt;
# ##i##dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&lt;br /&gt;
# ##i##cp /usr/share/syslinux/menu.c32 /boot/extlinux/&lt;br /&gt;
# ##i##touch /boot/extlinux/extlinux.conf&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Config Extlinux ===&lt;br /&gt;
Open '''/boot/extlinux/extlinux.conf''' with your favorite editor and add the following to it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
TIMEOUT 30&lt;br /&gt;
UI menu.c32&lt;br /&gt;
&lt;br /&gt;
MENU TITLE Funtoo Boot Menu&lt;br /&gt;
MENU COLOR title        1;37;40&lt;br /&gt;
MENU COLOR border       30;40&lt;br /&gt;
MENU COLOR unsel        37;40&lt;br /&gt;
&lt;br /&gt;
LABEL funtoo bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  MENU LABEL Funtoo Linux bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  KERNEL /bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  INITRD /initrd-&amp;lt;Kernel-Version&amp;gt;.img&lt;br /&gt;
  APPEND enc_root=/dev/sda2 pool_root=rpool/ROOT/funtoo&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Final configuration ==&lt;br /&gt;
=== Add the zfs tools to openrc ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##rc-update add zfs boot&lt;br /&gt;
# ##i##rc-update add zfs-shutdown shutdown&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add filesystems to /etc/fstab ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##nano /etc/fstab&lt;br /&gt;
# &amp;lt;fs&amp;gt;                  &amp;lt;mountpoint&amp;gt;    &amp;lt;type&amp;gt;          &amp;lt;opts&amp;gt;          &amp;lt;dump/pass&amp;gt;&lt;br /&gt;
/dev/sda1               /boot           ext2            defaults        1 2&lt;br /&gt;
/dev/zvol/rpool/swap    none            swap            sw              0 0&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Clean up and reboot ===&lt;br /&gt;
We are almost done, we are just going to clean up and unmount whatever we mounted and get out.&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Delete the stage3/portage tarballs you downloaded earlier so they don't take up space.&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##rm stage3-latest.tar.xz&lt;br /&gt;
# ##i##rm /usr/portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
Set your root password&lt;br /&gt;
# ##i##passwd&lt;br /&gt;
&amp;gt;&amp;gt; Enter your password, you won't see what you are writing (for security reasons), but it is there!&lt;br /&gt;
&lt;br /&gt;
Get out of the chroot environment&lt;br /&gt;
# ##i##exit&lt;br /&gt;
&lt;br /&gt;
Unmount all the kernel filesystem stuff and boot&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
# ##i##umount proc dev sys boot&lt;br /&gt;
&lt;br /&gt;
Turn off the swap&lt;br /&gt;
# ##i##swapoff /dev/zvol/rpool/swap&lt;br /&gt;
&lt;br /&gt;
Export the zpool&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##zpool export -f rpool&lt;br /&gt;
&lt;br /&gt;
Reboot&lt;br /&gt;
# ##i##reboot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and that should be enough to get your system to boot on ZFS.&lt;br /&gt;
&lt;br /&gt;
== Extra: After reboot ==&lt;br /&gt;
After you restart your machine and your inside your desktop, continue to set up anything you need in terms of /etc configurations. Once you have everything the way you like it, take a snapshot of your system. You will be using this snapshot to revert back to this state if anything ever happens to your system down the road. The snapshots are cheap, and almost instant. To take the snapshot of your rootfs, type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs snapshot rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To see if your snapshot was taken, type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs list -t snapshot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your machine ever fails and you need to get back to this state, just type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs rollback rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enjoy your new install on ZFS :)&lt;br /&gt;
&lt;br /&gt;
== Getting back into your ZFS pool in case of emergency ==&lt;br /&gt;
If you ever need to get back into your ZFS pool in case of an emergency (missing rebuild of modules, unable to boot, etc) reboot your box with the System Rescue USB you created earlier, then issue the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##depmod&lt;br /&gt;
# ##i##cryptsetup luksOpen /dev/sda2 enc-root&lt;br /&gt;
# ##i##zpool import -f -o cachefile= -R /mnt/funtoo rpool&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should be able to mount the system like we did earlier in this Guide [[ZFS_rootfs_over_encrypted_container#Installing_Funtoo|(chroot instructions)]], fix your problem and enjoy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Filesystems]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Linux_Kernels</id>
		<title>Funtoo Linux Kernels</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Linux_Kernels"/>
				<updated>2013-03-17T16:16:46Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: /* Second step: Grabbing a configuration file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This Section will give you an overview of kernels used in funtoo.&lt;br /&gt;
&lt;br /&gt;
Funtoo Linux provides a number of new kernels for your use. This is the official page for all Funtoo Linux kernel information. &lt;br /&gt;
&lt;br /&gt;
Some points of interest:&lt;br /&gt;
&lt;br /&gt;
* Most Funtoo Linux kernels support the handy &amp;lt;tt&amp;gt;[[#Binary USE|binary]]&amp;lt;/tt&amp;gt; USE flag, described below.&lt;br /&gt;
* Funtoo Linux offers quality kernels from other Linux Distributions, like &amp;lt;tt&amp;gt;ubuntu-server&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;debian-sources&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* A detailed [[#Kernel Features and Stability|Kernel Features and Stability]] table can be found below.&lt;br /&gt;
* Advanced users may want to take a look at [[Additional Kernel Resources]].&lt;br /&gt;
* There is a quick'n dirty howto to compile your own [[kernel]] with initramfs the funtoo way.&lt;br /&gt;
&lt;br /&gt;
== Overview of Kernels ==&lt;br /&gt;
&lt;br /&gt;
=== sysrescue-std-sources ===&lt;br /&gt;
&lt;br /&gt;
This kernel is from the [http://www.sysresccd.org SystemRescueCD project], and is based on Fedora 14/15, plus some other patches related to booting from a live CD. It is a quality kernel, and is generally pretty stable. It is not suitable for production servers but is a good choice for Funtoo Linux desktops. The [[Funtoo Linux Installation]] Guide recommends this kernel for general users. Note however,  that by design all audio functions are removed from SystemRescue,  ie no sound when using this kernel.&lt;br /&gt;
&lt;br /&gt;
=== vanilla-sources ===&lt;br /&gt;
&lt;br /&gt;
This will install the &amp;quot;vanilla&amp;quot; (unmodified) Linux kernel sources. Current recommended version is 3.x. Funtoo Linux fully supports Linux 3.x. The advantages of this kernel include recent improvements to [[Linux Containers]], a very modern networking stack with lots of bug fixes, and high reliability for desktops and servers. The downside is that this kernel must be manually configured by the user and does not have built-in &amp;lt;tt&amp;gt;genkernel&amp;lt;/tt&amp;gt; support via the &amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt; USE flag at this time.&lt;br /&gt;
&lt;br /&gt;
=== openvz-rhel6-stable ===&lt;br /&gt;
&lt;br /&gt;
This is a RHEL6-based kernel with OpenVZ support. This kernel is now the preferred kernel for production OpenVZ deployments. It requires gcc-4.4.5 to build, which it will use automatically without the user needing to use &amp;lt;tt&amp;gt;gcc-config&amp;lt;/tt&amp;gt;. We use this version of gcc since this is the version of gcc used by Red Hat to build this kernel.&lt;br /&gt;
&lt;br /&gt;
=== openvz-rhel5-stable ===&lt;br /&gt;
&lt;br /&gt;
This kernel is based on the latest Red Hat Enterprise Linux 5.6 kernel, and contains additional OpenVZ (virtual containers) patches from the [[OpenVZ on Funtoo Linux|OpenVZ]] project. It is a very stable and reliable kernel, and is recommended for use in production environments. The only major downside to this kernel is that it is based on Linux 2.6.18 -- some parts of the kernel are out-of-date, and it is not compatible with modern versions of udev. However, it is pretty trivial to downgrade udev to an earlier version on Funtoo Linux and this kernel has a track-record of being rock-solid. When stability is paramount, you put up with the udev downgrade, use this kernel, and can enjoy hundreds of days of uptime. For more information on how to use this kernel with Funtoo Linux, see the [[RHEL5 Kernel HOWTO]].&lt;br /&gt;
&lt;br /&gt;
=== ubuntu-server ===&lt;br /&gt;
&lt;br /&gt;
This is the kernel from Ubuntu Server. Version &amp;lt;tt&amp;gt;2.6.32.32.62&amp;lt;/tt&amp;gt; is the same version used in Ubuntu Server 10.04 LTS, and version &amp;lt;tt&amp;gt;2.6.35.28.50&amp;lt;/tt&amp;gt; is the one used in Ubuntu Server 10.10 (currently masked). In our testing of &amp;lt;tt&amp;gt;2.6.32.32.62&amp;lt;/tt&amp;gt;, it has been very reliable and offers very good performance. One exception, which is common among 2.6.32-based kernels, is that it's recommended that you emerge &amp;lt;tt&amp;gt;broadcom-netxtreme2&amp;lt;/tt&amp;gt; if you have any Broadcom-based NICs, as the in-kernel drivers have compatibility issues with certain models. This kernel is a very good option if you want a relatively modern server kernel and do not need [[OpenVZ]] support. We use gcc-4.4.5 to build this kernel. It will use gcc-4.4.5 automatically, without requiring the user to use &amp;lt;tt&amp;gt;gcc-config&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== debian-sources ===&lt;br /&gt;
&lt;br /&gt;
This is the Debian kernel. '''These ebuilds now support the &amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt; USE flag.''' Daniel has added a special &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt; command which can be used to list all available official Debian kernel configurations, and generate them from the Debian files included with the kernel. This kernel has optional [[OpenVZ]] support, but it is much better to use &amp;lt;tt&amp;gt;openvz-rhel6-stable&amp;lt;/tt&amp;gt; if you want a production-quality OpenVZ installation. For more information about how to use &amp;lt;tt&amp;gt;debian-sources&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt;, see [[#Using Debian-Sources with Genkernel|Using debian-sources with Genkernel]] below.&lt;br /&gt;
&lt;br /&gt;
=== debian-sources-lts ===&lt;br /&gt;
&lt;br /&gt;
This is the Debian long-term stable kernel. '''These ebuilds now support the &amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt; USE flag.''' Daniel has added a special &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt; command which can be used to list all available official Debian kernel configurations, and generate them from the Debian files included with the kernel.&lt;br /&gt;
&lt;br /&gt;
== Binary USE ==&lt;br /&gt;
&lt;br /&gt;
Many of the kernel ebuilds in Funtoo Linux support the very useful &amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt; USE flag. By enabling this USE flag and emerging the kernel, the ebuild will automatically build a binary kernel image, initramfs and kernel modules and install them to &amp;lt;tt&amp;gt;/boot&amp;lt;/tt&amp;gt;. The binary kernel image and initramfs can be used to boot your Funtoo Linux system without requiring any additional configuration. This is a great way to get a Funtoo Linux system up and running quickly. Here's how to do it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# echo &amp;quot;sys-kernel/openvz-rhel5-stable binary&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use&lt;br /&gt;
# emerge openvz-rhel5-stable&lt;br /&gt;
# nano -w /etc/boot.conf&lt;br /&gt;
# boot-update&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More information can be found in the [[Funtoo Linux Installation]] Guide.&lt;br /&gt;
&lt;br /&gt;
== Funtoo Linux Genkernel ==&lt;br /&gt;
&lt;br /&gt;
Funtoo Linux contains a forked/enhanced version of genkernel with the following new capabilities:&lt;br /&gt;
&lt;br /&gt;
* genkernel can use a build directory that is separate from the kernel source directory. This is enabled using the new &amp;lt;tt&amp;gt;--build-dst&amp;lt;/tt&amp;gt; option.&lt;br /&gt;
* &amp;lt;tt&amp;gt;--build-src&amp;lt;/tt&amp;gt; is a new option that is equivalent to the &amp;lt;tt&amp;gt;--kerneldir&amp;lt;/tt&amp;gt; option.&lt;br /&gt;
* &amp;lt;tt&amp;gt;--fullname&amp;lt;/tt&amp;gt; can be used to specify the entire name of the kernel and initramfs images -- everything after &amp;lt;tt&amp;gt;kernel-&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;initramfs-&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;--firmware-src&amp;lt;/tt&amp;gt; - a new option that works identically to &amp;lt;tt&amp;gt;--firmware-dir&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* &amp;lt;tt&amp;gt;--firmware-dst&amp;lt;/tt&amp;gt; - a new capability - you can now define where genkernel installs firmware.&lt;br /&gt;
* Genkernel uses Funtoo Linux &amp;lt;tt&amp;gt;lvm2&amp;lt;/tt&amp;gt; rather than building its own.&lt;br /&gt;
* Some compile fixes.&lt;br /&gt;
&lt;br /&gt;
== Kernel Features and Stability ==&lt;br /&gt;
&lt;br /&gt;
This page provides an overview of kernel features and stability information:&lt;br /&gt;
&lt;br /&gt;
{| {{table}} &lt;br /&gt;
!Kernel Name&lt;br /&gt;
!Version&lt;br /&gt;
!USE flags&lt;br /&gt;
!Stability&lt;br /&gt;
!Extra Features&lt;br /&gt;
!Req'd udev&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#vanilla-sources|vanilla-sources]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|3.1.5&lt;br /&gt;
|N/A&lt;br /&gt;
|'''Excellent''' - recommended for desktops and servers.&lt;br /&gt;
|N/A&lt;br /&gt;
|Any&lt;br /&gt;
|Recommended for modern networking stack, hardware and [[Linux Containers]] support. This kernel must be manually configured by the user.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#sysrescue-std-sources|sysrescue-std-sources]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.35.210&lt;br /&gt;
|&amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt;&lt;br /&gt;
|''Good'' - recommended for desktops&lt;br /&gt;
|N/A&lt;br /&gt;
|Any&lt;br /&gt;
|Nvidia card users: binary use flag installs nouveau drivers. Not compatible with nvidia-drivers.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#openvz-rhel6-stable|openvz-rhel6-stable]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.32.042.044.11&lt;br /&gt;
|&amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt;&lt;br /&gt;
|'''Excellent''' - recommended for production servers&lt;br /&gt;
|N/A&lt;br /&gt;
|Any&lt;br /&gt;
|This kernel is built with gcc-4.4.5. &amp;lt;tt&amp;gt;emerge broadcom-netxtreme2&amp;lt;/tt&amp;gt; for reliable BCM5709+ support (integrated NIC)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#openvz-rhel5-stable|openvz-rhel5-stable]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.18.028.095.1&lt;br /&gt;
|&amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt;&lt;br /&gt;
|'''Excellent''' - recommended for production servers&lt;br /&gt;
|OpenVZ&lt;br /&gt;
|=sys-fs/udev-146*&lt;br /&gt;
|Broadcom &amp;lt;tt&amp;gt;bnx2&amp;lt;/tt&amp;gt; driver module bundled with kernel appears to be OK. This kernel is built with gcc-4.1.2. Enabling the &amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt; USE flag will cause gcc-4.1.2 to be emerged and used for building the kernel.&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#ubuntu-server|ubuntu-server]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.32.32.62&lt;br /&gt;
|&amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt;&lt;br /&gt;
|'''Excellent''' - recommended for production servers (still in extended testing)&lt;br /&gt;
| N/A&lt;br /&gt;
|Any&lt;br /&gt;
|This kernel is built with gcc-4.4.5. &amp;lt;tt&amp;gt;emerge broadcom-netxtreme2&amp;lt;/tt&amp;gt; for reliable BCM5709+ support (integrated NIC)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#ubuntu-server|ubuntu-server]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.35.28.50&lt;br /&gt;
|&amp;lt;tt&amp;gt;binary&amp;lt;/tt&amp;gt;&lt;br /&gt;
|''not yet tested''&lt;br /&gt;
| N/A&lt;br /&gt;
|Any&lt;br /&gt;
|This kernel is built with gcc-4.4.5. &amp;lt;tt&amp;gt;emerge broadcom-netxtreme2&amp;lt;/tt&amp;gt; for reliable BCM5709+ support (integrated NIC)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[[#debian-sources|debian-sources]]&amp;lt;/tt&amp;gt;&lt;br /&gt;
|2.6.32.30&lt;br /&gt;
|&amp;lt;tt&amp;gt;openvz&amp;lt;/tt&amp;gt;&lt;br /&gt;
|''Good'' - still being evaluated by Funtoo&lt;br /&gt;
|OpenVZ (optional)&lt;br /&gt;
|Any&lt;br /&gt;
|See [[#Using debian-sources with Genkernel]], below.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Using Debian-Sources with Genkernel ==&lt;br /&gt;
&lt;br /&gt;
{{ fancyimportant|Debian-sources is now fully compatible with ''binary'' USE flag and recommended for desktop users. The below example is valid for manual installation. At least 12G of /var/tmp required to build &lt;br /&gt;
}}&lt;br /&gt;
This section describes how to build a binary kernel with &amp;lt;tt&amp;gt;debian-sources&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;genkernel&amp;lt;/tt&amp;gt;, and it also explains how to use Funtoo Linux's &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt; tool to list and create official Debian kernel configurations.&lt;br /&gt;
&lt;br /&gt;
=== First step: emerging the required packages ===&lt;br /&gt;
&lt;br /&gt;
The first step is to emerge:&lt;br /&gt;
&lt;br /&gt;
# The Debian sources&lt;br /&gt;
# Genkernel itself&lt;br /&gt;
&lt;br /&gt;
This is achieved with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# emerge sys-kernel/debian-sources sys-kernel/genkernel&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the Debian kernel sources are deployed, you should find a directory named '''linux-debian-''version''''' (e.g. linux-debian-2.6.32.30) under '''/usr/src'''. Update your the '''linux''' symlink to point on this directory:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd /usr/src&lt;br /&gt;
# rm linux&lt;br /&gt;
# ln -s linux-debian-2.6.32.30 linux&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternatively, emerge the debian-sources with USE=&amp;quot;symlink&amp;quot;&lt;br /&gt;
=== Second step: Grabbing a configuration file ===&lt;br /&gt;
&lt;br /&gt;
If is now time to download the kernel configuration file. For this tutorial we will use a configuration file for AMD64 (several others architectures like MIPS or SPARC64 are available.)  To view a complete list of available kernel configurations, type &amp;lt;tt&amp;gt;./config-extract -l&amp;lt;/tt&amp;gt; in the Debian kernel source directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ninja1 linux-debian-2.6.32.30 # ./config-extract -l&lt;br /&gt;
&lt;br /&gt;
====== standard featureset ======&lt;br /&gt;
&lt;br /&gt;
       alpha: alpha-generic, alpha-legacy, alpha-smp&lt;br /&gt;
       amd64&lt;br /&gt;
       armel: iop32x, ixp4xx, kirkwood, orion5x, versatile&lt;br /&gt;
        hppa: parisc, parisc-smp, parisc64, parisc64-smp&lt;br /&gt;
        i386: 486, 686, 686-bigmem, amd64&lt;br /&gt;
        ia64: itanium, mckinley&lt;br /&gt;
        m68k: amiga, atari, bvme6000, mac, mvme147, mvme16x&lt;br /&gt;
        mips: 4kc-malta, 5kc-malta, r4k-ip22, r5k-ip32, sb1-bcm91250a, sb1a-bcm91480b&lt;br /&gt;
      mipsel: 4kc-malta, 5kc-malta, r5k-cobalt, sb1-bcm91250a, sb1a-bcm91480b&lt;br /&gt;
     powerpc: powerpc, powerpc-smp, powerpc64&lt;br /&gt;
        s390: s390x, s390x-tape&lt;br /&gt;
         sh4: sh7751r, sh7785lcr&lt;br /&gt;
       sparc: sparc64, sparc64-smp&lt;br /&gt;
     sparc64: sparc64, sparc64-smp&lt;br /&gt;
&lt;br /&gt;
====== vserver featureset ======&lt;br /&gt;
&lt;br /&gt;
       amd64&lt;br /&gt;
        i386: 686, 686-bigmem&lt;br /&gt;
        ia64: itanium, mckinley&lt;br /&gt;
     powerpc: powerpc, powerpc64&lt;br /&gt;
        s390&lt;br /&gt;
       sparc&lt;br /&gt;
     sparc64&lt;br /&gt;
&lt;br /&gt;
====== xen featureset ======&lt;br /&gt;
&lt;br /&gt;
       amd64&lt;br /&gt;
        i386&lt;br /&gt;
&lt;br /&gt;
====== openvz featureset ======&lt;br /&gt;
&lt;br /&gt;
       amd64&lt;br /&gt;
        i386&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type &amp;lt;tt&amp;gt;config-extract -h&amp;lt;/tt&amp;gt; for extended usage information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ninja1 linux-debian-2.6.32.30 # ./config-extract -h&lt;br /&gt;
This work is free software.&lt;br /&gt;
&lt;br /&gt;
Copyright 2011 Funtoo Technologies. You can redistribute and/or modify it under&lt;br /&gt;
the terms of the GNU General Public License version 3 as published by the Free&lt;br /&gt;
Software Foundation. Alternatively you may (at your option) use any other&lt;br /&gt;
license that has been publicly approved for use with this program by Funtoo&lt;br /&gt;
Technologies (or its successors, if any.)&lt;br /&gt;
&lt;br /&gt;
usage: config-extract [options] arch [featureset] [subarch]&lt;br /&gt;
&lt;br /&gt;
  -h  --help        print this usage and exit&lt;br /&gt;
  -l  --list        list all available kernel configurations&lt;br /&gt;
  -o  --outfile     specify kernel config outfile --&lt;br /&gt;
                    defaults to .config in current directory&lt;br /&gt;
  [featureset]      defaults to &amp;quot;none&amp;quot; if not specified&lt;br /&gt;
  [subarch]         defaults to the only one available; otherwise required&lt;br /&gt;
&lt;br /&gt;
This program was written by Daniel Robbins for Funtoo Linux, for the purpose of&lt;br /&gt;
easily and conveniently extracting Debian kernel configurations. To see a nice&lt;br /&gt;
list of all available kernel configurations, use the --list option.&lt;br /&gt;
&lt;br /&gt;
Debian's kernel configs are specified internally in arch_featureset_flavor&lt;br /&gt;
format, such as: &amp;quot;amd64_openvz_amd64&amp;quot;. The featureset typically describes an&lt;br /&gt;
optional kernel configuration such as &amp;quot;xen&amp;quot; or &amp;quot;openvz&amp;quot;, while the flavor in&lt;br /&gt;
Debian terminology typically refers to the sub-architecture of the CPU.&lt;br /&gt;
&lt;br /&gt;
When using this command, you must specify an arch. A featureset of &amp;quot;none&amp;quot; is&lt;br /&gt;
assumed unless you specify one, and by default this program will pick the only&lt;br /&gt;
available subarch if there is only one to choose from. If not, you will need to&lt;br /&gt;
pick one (and the program will remind you to do this.)&lt;br /&gt;
&lt;br /&gt;
The kernel configuration will be written to &amp;quot;.config&amp;quot; in the current directory,&lt;br /&gt;
or the location you specified using the -o/--outfile option.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's use &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt; to create a kernel configuration for an amd64 system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cd linux&lt;br /&gt;
# ./config-extract amd64&lt;br /&gt;
Wrote amd64_none_amd64 kernel configuration to /usr/src/linux-debian-2.6.32.30/.config.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt; also allows you to extract special Debian featuresets, such as settings for Xen and [[OpenVZ]] kernels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ./config-extract amd64 openvz&lt;br /&gt;
Wrote amd64_openvz_amd64 kernel configuration to /usr/src/linux-debian-2.6.32.30/.config.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''It is necessary to name the kernel configuration file something other than &amp;quot;.config&amp;quot; to avoid errors with genkernel.'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After using &amp;lt;tt&amp;gt;config-extract&amp;lt;/tt&amp;gt;, run &amp;lt;tt&amp;gt;make oldconfig&amp;lt;/tt&amp;gt; and accept all default options by hitting Enter at all prompts.&lt;br /&gt;
&lt;br /&gt;
=== Third step: Building and installing the kernel ===&lt;br /&gt;
&lt;br /&gt;
This is simply achieved by:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# genkernel --kernel-config=config-2.6.32-5-amd64 all&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* --kernel-config: use the given configfile. If you only give a filename here, it is searched for in your current working dir. You can also use a relative or an absolute path leading to your configfile here (for example: &amp;quot;--kernel-config=/usr/src/linux/configfile&amp;quot;).&lt;br /&gt;
* all: rebuild the kernel image and the initramfs ramdisk image (aside of kernel modules, the ramdisk image contains tools such as BusyBox and some generic startup scripts, depending on options you use on the command line several additional tools like lvm or raid volume management can be incorporated as well).&lt;br /&gt;
&lt;br /&gt;
{{ fancyimportant|Unless explicitly stated via ''--no-clean'' or ''--no-mrproper'', Genkernel will do a '''make mrproper''' in the kernel source tree, thus cleaning a previous build '''and removing the previous kernel configuration file''' in it. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you use Genkernel to rebuild a Linux kernel on SPARC64, remember to either:&lt;br /&gt;
* Set '''sparc64-unknown-linux-gnu-''' in ''General setup --&amp;gt; Cross-compiler tool prefix'' &lt;br /&gt;
* Put '''--kernel-cross-compile=sparc64-unknown-linux-gnu-''' on the Genkernel command line&lt;br /&gt;
&lt;br /&gt;
Once the kernel has been compiled and the ram disk has been generated, the kernel image plus its companion files (initramfs image and System.map) are placed in the /boot directory. You can use your favourite tool to update your bootloader configuration files.&lt;br /&gt;
&lt;br /&gt;
[[Category:Internals]]&lt;br /&gt;
[[Category:Funtoo features]]&lt;br /&gt;
[[Category:Kernel]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-03T16:51:47Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: update warning about shellscript and #-sign&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|A note aside, the scripts are real shell scripts, so parts beginning with a '''#''' are comments and parts without are the shell script commands that are executed!}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Finally here are some examples to which questions came up, hope you find them helpful for your first own tries... :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 1 minute :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  testtime=`date +%H%M`&lt;br /&gt;
  whenjobs --set --type int test=${testtime}&lt;br /&gt;
  whenjobs --set --type int runtime=0016&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == 0017 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  echo `date` &amp;gt;\&amp;gt; ~/test.log &lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == runtime&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  whenjobs --get runtime &amp;gt;\&amp;gt; ~/test.log&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above whenjobs have the need to run each day at a specific time, so we show you here two ways of doing it.&lt;br /&gt;
&lt;br /&gt;
First we define a variable test for whenjobs based on the date with the HHMM output what would for example result in 0017 for 12:17am and 1428 for 2:28pm. then in the first when expression we test if our variable equals 0017 and if yes it runs, the second version is to define a second variable called runtime and then do like the second test does a test for it based on comparing both variables.&lt;br /&gt;
&lt;br /&gt;
But now enough with that long doc, happy whenjobing for all of you... :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Labs]]&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T02:18:23Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding categories&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Finally here are some examples to which questions came up, hope you find them helpful for your first own tries... :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 1 minute :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  testtime=`date +%H%M`&lt;br /&gt;
  whenjobs --set --type int test=${testtime}&lt;br /&gt;
  whenjobs --set --type int runtime=0016&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == 0017 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  echo `date` &amp;gt;\&amp;gt; ~/test.log &lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == runtime&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  whenjobs --get runtime &amp;gt;\&amp;gt; ~/test.log&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above whenjobs have the need to run each day at a specific time, so we show you here two ways of doing it.&lt;br /&gt;
&lt;br /&gt;
First we define a variable test for whenjobs based on the date with the HHMM output what would for example result in 0017 for 12:17am and 1428 for 2:28pm. then in the first when expression we test if our variable equals 0017 and if yes it runs, the second version is to define a second variable called runtime and then do like the second test does a test for it based on comparing both variables.&lt;br /&gt;
&lt;br /&gt;
But now enough with that long doc, happy whenjobing for all of you... :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Labs]]&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T02:16:13Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Finally here are some examples to which questions came up, hope you find them helpful for your first own tries... :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 1 minute :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  testtime=`date +%H%M`&lt;br /&gt;
  whenjobs --set --type int test=${testtime}&lt;br /&gt;
  whenjobs --set --type int runtime=0016&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == 0017 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  echo `date` &amp;gt;\&amp;gt; ~/test.log &lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == runtime&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  whenjobs --get runtime &amp;gt;\&amp;gt; ~/test.log&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above whenjobs have the need to run each day at a specific time, so we show you here two ways of doing it.&lt;br /&gt;
&lt;br /&gt;
First we define a variable test for whenjobs based on the date with the HHMM output what would for example result in 0017 for 12:17am and 1428 for 2:28pm. then in the first when expression we test if our variable equals 0017 and if yes it runs, the second version is to define a second variable called runtime and then do like the second test does a test for it based on comparing both variables.&lt;br /&gt;
&lt;br /&gt;
But now enough with that long doc, happy whenjobing for all of you... :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Funtoo Labs]]&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:56:12Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: finish pre version of doc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
Finally here are some examples to which questions came up, hope you find them helpful for your first own tries... :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 1 minute :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  testtime=`date +%H%M`&lt;br /&gt;
  whenjobs --set --type int test=${testtime}&lt;br /&gt;
  whenjobs --set --type int runtime=0016&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == 0017 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  echo `date` &amp;gt;\&amp;gt; ~/test.log &lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
when test == runtime&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  whenjobs --get runtime &amp;gt;\&amp;gt; ~/test.log&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above whenjobs have the need to run each day at a specific time, so we show you here two ways of doing it.&lt;br /&gt;
&lt;br /&gt;
First we define a variable test for whenjobs based on the date with the HHMM output what would for example result in 0017 for 12:17am and 1428 for 2:28pm. then in the first when expression we test if our variable equals 0017 and if yes it runs, the second version is to define a second variable called runtime and then do like the second test does a test for it based on comparing both variables.&lt;br /&gt;
&lt;br /&gt;
But now enough with that long doc, happy whenjobing for all of you... :)&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:45:08Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;vertical-align:top;&amp;quot;| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:36:03Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:31:58Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Basic available Whentools functions =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! function&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| whentools.mailto [~only_on_failure:true] [~from:from_address] email_address result&lt;br /&gt;
| This built-in post function sends the result of the script by email to the given email address.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~only_on_failure:true&amp;quot; flag is set, then it is only sent out if the script failed.&lt;br /&gt;
&lt;br /&gt;
If the optional &amp;quot;~from&amp;quot; flag is set, then the from address is set accordingly.  This is sometimes needed when sending mail.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;result&amp;quot; parameter is passed implicitly by the daemon. You do not need to add it.&lt;br /&gt;
&lt;br /&gt;
Here are some examples of using the mailto function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;ex.1&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
   # shell script 1&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.2&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~only_on_failure:true &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 2&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
let from = &amp;quot;me@example.com&amp;quot;&lt;br /&gt;
let to_addr = &amp;quot;you@example.com&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job &amp;quot;ex.3&amp;quot;&lt;br /&gt;
post (Whentools.mailto ~from to_addr)&lt;br /&gt;
every 10 seconds :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script 3&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.max n&lt;br /&gt;
| This built-in pre function ensures that a maximum of n instances of the job are running.&lt;br /&gt;
&lt;br /&gt;
It checks the list of running jobs, and if n or more instances are already running, then it returns &amp;quot;false&amp;quot;, which ensures that the new job is not started.&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.one ()&lt;br /&gt;
| This built-in pre function ensures that only one instance of the job is running.  It is the same as calling: Whentools.max 1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable name string&lt;br /&gt;
| Set variable name to the string&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_bool name b&lt;br /&gt;
| Set variable name to the boolean value b&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_int name i&lt;br /&gt;
| Set variable name to the integer value i&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_string name s&lt;br /&gt;
| Set variable name to the string value &amp;lt;s&amp;gt;.  This is the same as Whentools.set_variable&lt;br /&gt;
|-&lt;br /&gt;
| Whentools.set_variable_float name f&lt;br /&gt;
| Set variable name to the floating point value f&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For the preinfo passed to the pre functions and results for the post functions have a view in the manpage.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:18:17Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding post/pre function description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== OCAML expressions ====&lt;br /&gt;
&lt;br /&gt;
You can also use OCAML expressions in the code. they are useful for factoring common code or strings, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let prefix = &amp;quot;daily_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;virus_scan&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
job (prefix ^ &amp;quot;disk_check&amp;quot;)&lt;br /&gt;
every day :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== initial value of variables =====&lt;br /&gt;
&lt;br /&gt;
Variables are empty until they first get set, you can set a default starting value for a variable if you like with the following code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
let () =&lt;br /&gt;
  Whentools.set_variable &amp;quot;variable&amp;quot; &amp;quot;value&amp;quot;;&lt;br /&gt;
  Whentools.set_variable_int &amp;quot;counter&amp;quot; 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pre functions =====&lt;br /&gt;
&lt;br /&gt;
You can let arrange to run a '''pre''' function before a job runs. This function may decide to not run the job. One possible usage for that is the that you only want to have one job at time from the same job to run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;only one&amp;quot;&lt;br /&gt;
pre (Whentools.one ())&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Post functions =====&lt;br /&gt;
&lt;br /&gt;
The same is for stuff after a job has run. This is handled by the '''post''' function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;talk to me after finished&amp;quot;&lt;br /&gt;
post (Whentools.mailto &amp;quot;you@example.com&amp;quot;)&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:04:54Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding job names&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:03:13Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;br /&gt;
&lt;br /&gt;
==== Job names ====&lt;br /&gt;
&lt;br /&gt;
If you like to give a job a unique name use the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntax lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
job &amp;quot;JOBNAME&amp;quot;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/syntax&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T01:00:21Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The shell scripts run with its current directory set to an temporary directory, that is cleaned up automacically after the job exists. So you don't have to worry about cleaning them up later. If you would like to store some values permanently, save the files to a well-known directory, eg. $HOME, '''/var''' etc.&lt;br /&gt;
&lt;br /&gt;
All shell scripts are executed as the ordinary user. They have no special privileges.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:57:16Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding shell script section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== shell scripts ====&lt;br /&gt;
&lt;br /&gt;
The code between '''&amp;lt;&amp;lt; ... &amp;gt;&amp;gt;''' is a simple shell script and is executed using $SHELL. If $SHELL is not set, it is executed with '''/bin/sh'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! available variable&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| $JOBNAME&lt;br /&gt;
| The name of the job. If the job has been named explicitly, then that name is available through this variable, else it will be some implicit name like '''job$1'''.&lt;br /&gt;
|-&lt;br /&gt;
| $JOBSERIAL&lt;br /&gt;
| The serial number of the job. This is simply a variable that increments each time a job is run, and is unique to that run of the job.&lt;br /&gt;
|-&lt;br /&gt;
| $HOME, $LOGNAME etc&lt;br /&gt;
| these are available as normal&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:50:55Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt; expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:49:04Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
==== Periodic expressions ====&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== When expressions ====&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr \|\| expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:47:20Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: updating when expressions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
For periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For dependent jobs you need to use the when-statements with the following syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when &amp;lt;expr&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;expr&amp;gt;''' is a when expression. But don't forget the colon between periods expression or when expression and the shell script.&lt;br /&gt;
&lt;br /&gt;
All in all you can say, that a when-expression is a job which runs, when the described conditions become true.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
!&lt;br /&gt;
! &amp;lt;expr&amp;gt;&lt;br /&gt;
! meaning&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;amp;&amp;amp; expr&lt;br /&gt;
| boolean &amp;quot;and&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| ! expr&lt;br /&gt;
| boolean negative of expr&lt;br /&gt;
|-&lt;br /&gt;
| expr \|\| expr&lt;br /&gt;
| boolean &amp;quot;or&amp;quot; of the two sub-expressions&lt;br /&gt;
|&lt;br /&gt;
| expr + expr&lt;br /&gt;
| for numeric sub-expression, this performs addition, for strings it performs string concatenation, else it returns an error.&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr - expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;lt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr * expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr == expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr / expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt;= expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| expr mod expr&lt;br /&gt;
| evaluates sub-expressions and if both are numeric uses operator on them else returns error (infix operator)&lt;br /&gt;
|-&lt;br /&gt;
| expr &amp;gt; expr&lt;br /&gt;
| evaluates sub-expressions and compares them with the operator&lt;br /&gt;
|&lt;br /&gt;
| len expr&lt;br /&gt;
| returns the length of the string in expr&lt;br /&gt;
|-&lt;br /&gt;
| variable&lt;br /&gt;
| returns the value of named variable&lt;br /&gt;
| &lt;br /&gt;
| prev variable&lt;br /&gt;
| returns previous value of named variable&lt;br /&gt;
|-&lt;br /&gt;
| changes variable&lt;br /&gt;
| same as !(prev variabel == variable)&lt;br /&gt;
| &lt;br /&gt;
| increases variable&lt;br /&gt;
| same as prev variable &amp;lt; variable&lt;br /&gt;
|-&lt;br /&gt;
| decreases variable&lt;br /&gt;
| prev variable &amp;gt; variable&lt;br /&gt;
| &lt;br /&gt;
| reloaded ()&lt;br /&gt;
| do not use it, it does not what you want (manpage warning)&lt;br /&gt;
|-&lt;br /&gt;
| false&lt;br /&gt;
| constant equals always false&lt;br /&gt;
| &lt;br /&gt;
| true&lt;br /&gt;
| constant equals always true&lt;br /&gt;
|-&lt;br /&gt;
| &amp;quot;any string&amp;quot;&lt;br /&gt;
| empty string in boolean = false, else equals true&lt;br /&gt;
| &lt;br /&gt;
| N&lt;br /&gt;
| any integer, boolean 0=false, non-zero=true&lt;br /&gt;
|-&lt;br /&gt;
| N. | .N | N.N | N.NeN&lt;br /&gt;
| and floating point number, boolean 0=false, non-zero=true&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:23:21Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
For Periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:22:02Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: adding period settings&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
For Periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
!&lt;br /&gt;
! Special &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|&lt;br /&gt;
| X seconds&lt;br /&gt;
| runs every X seconds&lt;br /&gt;
|-&lt;br /&gt;
| minute&lt;br /&gt;
| runs every minute&lt;br /&gt;
| &lt;br /&gt;
| X minutes&lt;br /&gt;
| runs every X minutes&lt;br /&gt;
|-&lt;br /&gt;
| hour&lt;br /&gt;
| runs every hour&lt;br /&gt;
| &lt;br /&gt;
| X hours&lt;br /&gt;
| runs every X hours&lt;br /&gt;
|-&lt;br /&gt;
| day&lt;br /&gt;
| runs every day, at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X days&lt;br /&gt;
| runs every X days, at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| week&lt;br /&gt;
| runs every week, on a Thursday at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X weeks&lt;br /&gt;
| runs every X weeks, on a Thursday at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| month&lt;br /&gt;
| runs every month, on the 1st at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X months&lt;br /&gt;
| runs every X month, on the 1st at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| year&lt;br /&gt;
| runs every year, on the 1/1 at midnight UTC&lt;br /&gt;
| &lt;br /&gt;
| X years&lt;br /&gt;
| runs every X years, on the 1/1 at midnight UTC&lt;br /&gt;
|-&lt;br /&gt;
| decade&lt;br /&gt;
| runs every 10 years&lt;br /&gt;
| &lt;br /&gt;
| X decades&lt;br /&gt;
| runs every X decades&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| runs every 100 years&lt;br /&gt;
| &lt;br /&gt;
| X centuries&lt;br /&gt;
| runs every X centuries&lt;br /&gt;
|-&lt;br /&gt;
| millenium&lt;br /&gt;
| runs every 1000 years&lt;br /&gt;
| &lt;br /&gt;
| X millenia&lt;br /&gt;
| runs every X mellenia&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-02T00:08:43Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
For Periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|-&lt;br /&gt;
| X seconds&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T23:52:26Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: starting periods&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics. We will now start with a periodic call, like if we would like to check out load everyage every 10 minutes we would do it like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The power of whenjobs comes in game when you would like to base on a variable you set somewhere else:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
when load &amp;gt;= 6 :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  mail -s &amp;quot;ALERT: high load average: $load&amp;quot; MAILADDRESS &amp;lt; /dev/null&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That part will notify a user via email when his load average is greater or equal to 6, as when statements are &amp;quot;edge-triggered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The '''--type''' switch above for setting a variable can be one of '''bool, int, float, string or unit'''&lt;br /&gt;
&lt;br /&gt;
For Periodic expressions you have to use the following syntax&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocmal&amp;quot;&amp;gt;&lt;br /&gt;
every &amp;lt;period&amp;gt; :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # shell script&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where '''&amp;lt;period&amp;gt;''' is one of the following period expressions:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! &amp;lt;period&amp;gt;&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| second&lt;br /&gt;
| runs every second&lt;br /&gt;
|-&lt;br /&gt;
| X seconds&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T23:38:25Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: testing syntaxhighlight&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
just save your script now and whenjobs will upload it automatically for you.&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So far we are now fine with getting to the scripts, next let us add some basics:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
every 10 minutes :&lt;br /&gt;
&amp;lt;&amp;lt;&lt;br /&gt;
  # Get the current load average.&lt;br /&gt;
  load=`awk '{print $1}' /proc/loadavg`&lt;br /&gt;
  whenjobs --set --type float load=$load&lt;br /&gt;
&amp;gt;&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T23:02:28Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: update 3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process. First we need to edit our whenjobs-script. This can be done by two ways:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Version A) (manual way, not recommended)&lt;br /&gt;
# ##i##EDITOR ~/.whenjobs/jobs.ml&lt;br /&gt;
Edit the file with the scripts you want to use and save it, but after that you need to upload it so that whenjobs knows about it&lt;br /&gt;
# ##i##whenjobs --upload&lt;br /&gt;
Version B) (automatically by whenjobs, recommended)&lt;br /&gt;
# ##i##whenjobs -e  | --edit&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:57:13Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: update 2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;br /&gt;
&lt;br /&gt;
The user management for whenjobs is done with a single file located at '''/etc/whenjobs.users.conf''' just add a user to that file by a commaseperated list like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
root,user1,user2,user3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where user1-user3 have to be system-usernames as they are checked. please do not add any other lines to that file, as there is atm now way for comments in the file and adding other lines will break so far the usage and you won't be able to start the daemon later. ATM there is no initscript, but we are working on one and that initscript will then use that file in the same way. :)&lt;br /&gt;
&lt;br /&gt;
=== whenjobs commands ===&lt;br /&gt;
&lt;br /&gt;
There are some basic commands for whenjobs you should be aware of before we get to explain the script syntax for whenjobs. this part will explain them.&lt;br /&gt;
&lt;br /&gt;
To edit/list a job script use&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs -e | --edit&lt;br /&gt;
# ##i##whenjobs -l | --list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in the above case we added both the short and long version in one line so please use either the '''-e''' or the '''--edit''' version as there is no piping done at that part. We will use the same syntax for further examples if there are multiple ways of calling the function we need.&lt;br /&gt;
&lt;br /&gt;
Another import part is to set or get variables we want to set or set in whenjobs, that can be done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
to get a variable:&lt;br /&gt;
# ##i##whenjobs --get variable&lt;br /&gt;
to set a variable or multiple varibles:&lt;br /&gt;
# ##i##whenjobs --set variable=value [variable=value ...]&lt;br /&gt;
and to display all set variables:&lt;br /&gt;
# ##i##whenjobs --variables&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another important function in whenjobs is the way to start, stop and request the status of the per-user daemon.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
# ##i##whenjobs --daemon-stop&lt;br /&gt;
# ##i##whenjobs --daemon-status&lt;br /&gt;
# ##i##whenjobs --daemon-restart&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally we have the ability to inspect running jobs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --jobs&lt;br /&gt;
# ##i##whenjobs --cancel serial&lt;br /&gt;
# ##i##whenjobs --start &amp;quot;name&amp;quot;&lt;br /&gt;
# ##i##whenjobs --tail serial&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How to get started with whenjobs now ===&lt;br /&gt;
&lt;br /&gt;
First edit the above mentioned '''whenjobs.users.conf''' file if not already done and start a daemon on a per-user basis with&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##whenjobs --daemon-start&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thats all for starting whenjobs and now we have time to write some whenjobs-scripts. We will use here some basic examples nothing for real time usage but it should be able to give you the impression on how to write your own scripts and use the variables in the later process.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:35:46Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: update 1&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already. Whenjobs give users a simpler syntax for jobs to run and with funtoo improvements a good way of user-management for whenjobs, that way we fixed the default behaviour of whenjobs to not been able to run as root and let us execute the daemon on a userbasis by default.&lt;br /&gt;
&lt;br /&gt;
=== Question for help and testing ===&lt;br /&gt;
&lt;br /&gt;
With this tutorial we like to ask users to help us and test whenjobs. We would like to get your feedback to [http://bugs.funtoo.org/browse/FL-338 FL-338]. So please test and report there what you think and what you think should be improved.&lt;br /&gt;
&lt;br /&gt;
== How to install whenjobs ==&lt;br /&gt;
&lt;br /&gt;
The installation of whenjobs is really easy, just merge them and you would get all that is needed for a first testrun and later perhaps also a production usage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i## emerge -avt whenjobs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's what is needed for installing whenjobs, nothing big so far.&lt;br /&gt;
&lt;br /&gt;
== How to get started ==&lt;br /&gt;
&lt;br /&gt;
As mentioned above we added a user-management and whenjobs has a changed syntax compared to normal cronjobs so we will discuss all these parts now. :)&lt;br /&gt;
&lt;br /&gt;
=== user management ===&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:26:37Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [http://www.redhat.com RedHat Linux]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:26:01Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [http://bugs.funtoo.org/browse/FL-316 whenjobs], [http://bugs.funtoo.org/browse/FL-337 initscript], [http://bugs.funtoo.org/browse/FL-338 User Feedback] and [http://bugs.funtoo.org/browse/FL-351 this document].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [[http://www.redhat.com|RedHat Linux]]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:24:59Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [[http://bugs.funtoo.org/browse/FL-316 whenjobs]], [[http://bugs.funtoo.org/browse/FL-337 initscript]], [[http://bugs.funtoo.org/browse/FL-338 User Feedback]] and [[http://bugs.funtoo.org/browse/FL-351 this document]].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [[http://www.redhat.com|RedHat Linux]]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:23:47Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: First update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;br /&gt;
&lt;br /&gt;
{{fancywarning|This document is a work in progress, as we are still investigating whenjobs for funtoo usage. For information about it see Funtoo tickets about [[http://bugs.funtoo.org/browse/FL-316|whenjobs]], [[http://bugs.funtoo.org/browse/FL-337|initscript]], [[http://bugs.funtoo.org/browse/FL-338|User Feedback]] and [[http://bugs.funtoo.org/browse/FL-351|this document]].}}&lt;br /&gt;
&lt;br /&gt;
Whenjobs are written by Richard Jones from [[http://www.redhat.com|RedHat Linux]]. They are designed to be a cron daemon replacement with some improvements over normal cron-jobs. Further more we from Funtoo Linux added some improvements to them already.&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Whenjobs</id>
		<title>Whenjobs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Whenjobs"/>
				<updated>2013-02-01T22:10:45Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Created page with &amp;quot;== What are whenjobs ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What are whenjobs ==&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-31T21:34:49Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Meeting&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|form=Event Calendar Item|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-29T21:58:53Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Meeting&lt;br /&gt;
}}&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|form=Event Calendar Item|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:Event_Calendar_Item</id>
		<title>Template:Event Calendar Item</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:Event_Calendar_Item"/>
				<updated>2013-01-29T21:56:20Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Event Calendar Item&amp;quot; template.&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
{| style=&amp;quot;width:100%;&amp;quot;! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; |Event:&lt;br /&gt;
| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot;|{{{event}}}&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | Start:&lt;br /&gt;
| {{{start|}}}&lt;br /&gt;
! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | End:&lt;br /&gt;
| {{{end|}}}&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align: left;&amp;quot;| Type:&lt;br /&gt;
| style=&amp;quot;text-align: left;&amp;quot;| {{{type|}}}&lt;br /&gt;
! style=&amp;quot;width: 80px; text-align: left; vertical-align: middle;&amp;quot; | Location:&lt;br /&gt;
| {{{location|}}}&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 110px; text-align: left; vertical-align: top;&amp;quot; | Description:&lt;br /&gt;
| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot; | {{{description|}}}&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; |&lt;br /&gt;
| style=&amp;quot;text-align: right;&amp;quot; colspan=&amp;quot;3&amp;quot; | [[Funtoo Events|Other events]]&lt;br /&gt;
|} __NOFACTBOX__ &lt;br /&gt;
[[Page has default form::Event Calendar Item| ]] &lt;br /&gt;
{{#subobject:&lt;br /&gt;
|Has event={{{event|}}}&lt;br /&gt;
|Has event start={{{start|}}}&lt;br /&gt;
|Has event end={{{end|}}}&lt;br /&gt;
|Has event type={{{type|}}}&lt;br /&gt;
|Has event location={{{location|}}}&lt;br /&gt;
|Has event icon={{#switch: {{{type|}}}|Meeting =File:Event-meeting-icon.png|Presentation=File:Event-presentation-icon.png|Talk=File:Event-talk-icon.png }}&lt;br /&gt;
|Has event color={{#switch: {{{type|}}}|Meeting=#E9AF32|Presentation=#A0D8F1|Talk=#BF381A|Party=#E07628 }}&lt;br /&gt;
|Has event description={{{description|}}} &lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-29T21:42:46Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Test&lt;br /&gt;
}}&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|form=Event Calendar Item|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-29T21:41:20Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Test&lt;br /&gt;
}}&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|Special:FormEdit/Event Calendar Item/Funtoo Events|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-29T21:33:26Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Test&lt;br /&gt;
}}&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|form=Event calendar item|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Events</id>
		<title>Funtoo Events</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Events"/>
				<updated>2013-01-29T21:29:28Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Created page with &amp;quot;{{Event Calendar Item |event=Start of Funtoo Events Calendar |start=2013/01/29 |type=Test }} This site is a WIP for events the Funtoo Community is invited to join and get a me...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Event Calendar Item&lt;br /&gt;
|event=Start of Funtoo Events Calendar&lt;br /&gt;
|start=2013/01/29&lt;br /&gt;
|type=Test&lt;br /&gt;
}}&lt;br /&gt;
This site is a WIP for events the Funtoo Community is invited to join and get a meet and greet with devs and other entusiast of Funtoo Linux. :)&lt;br /&gt;
&lt;br /&gt;
{{#ask:[[Has event::+]][[Has event start::+]]&lt;br /&gt;
|?Has event=title&lt;br /&gt;
|?Has event start&lt;br /&gt;
|?Has event end&lt;br /&gt;
|?Has event description=Description&lt;br /&gt;
|?Has event icon=icon&lt;br /&gt;
|?Has event color=color&lt;br /&gt;
|?Has event location         &lt;br /&gt;
|format=eventcalendar&lt;br /&gt;
|start=earliest&lt;br /&gt;
|defaultview=month&lt;br /&gt;
|limit=   &lt;br /&gt;
|link=subject&lt;br /&gt;
|legend=pane&lt;br /&gt;
|firstday=Sunday&lt;br /&gt;
|dayview=yes&lt;br /&gt;
|headers=show&lt;br /&gt;
|theme=vector}}&lt;br /&gt;
&lt;br /&gt;
{{#formlink:popup|form=Event Calendar Item|link text=Create event|link type=button}}&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Form:Event_Calendar_Item</id>
		<title>Form:Event Calendar Item</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Form:Event_Calendar_Item"/>
				<updated>2013-01-28T23:31:08Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Created page with &amp;quot;&amp;lt;noinclude&amp;gt; This is the &amp;quot;Event Calendar Item&amp;quot; form. To create a page with this form, enter the page name below; if a page with that name already exists, you will be sent to a ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Event Calendar Item&amp;quot; form.&lt;br /&gt;
To create a page with this form, enter the page name below;&lt;br /&gt;
if a page with that name already exists, you will be sent to a form to edit that page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{#forminput:form=Event Calendar Item}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;wikiPreview&amp;quot; style=&amp;quot;display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
{{{for template|Event Calendar Item}}}&lt;br /&gt;
{| class=&amp;quot;formtable&amp;quot;&lt;br /&gt;
! Event:&lt;br /&gt;
| {{{field|event|mandatory|size=85}}}&lt;br /&gt;
|-&lt;br /&gt;
! Start:&lt;br /&gt;
| {{{field|start|input type=datetimepicker}}}&lt;br /&gt;
|-&lt;br /&gt;
! End:&lt;br /&gt;
| {{{field|end|input type=datetimepicker}}}&lt;br /&gt;
|-&lt;br /&gt;
! Type:&lt;br /&gt;
| {{{field|type|input type=combobox|mandatory|values from property=Has event type}}}&lt;br /&gt;
|-&lt;br /&gt;
! Location:&lt;br /&gt;
| {{{field|location|input type=text with autocomplete|values from property=Has Location}}}&lt;br /&gt;
|-&lt;br /&gt;
! Description:&lt;br /&gt;
| {{{field|description|input type=textarea|rows=5|cols=65|autogrow}}}&lt;br /&gt;
|}&lt;br /&gt;
{{{end template}}}&lt;br /&gt;
&lt;br /&gt;
'''Free text:'''&lt;br /&gt;
&lt;br /&gt;
{{{standard input|free text|rows=10}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{{standard input|summary}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|minor edit}}} {{{standard input|watch}}}&lt;br /&gt;
&lt;br /&gt;
{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}}&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:Event_Calendar_Item</id>
		<title>Template:Event Calendar Item</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:Event_Calendar_Item"/>
				<updated>2013-01-28T22:43:20Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Event Calendar Item&amp;quot; template.&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
{| style=&amp;quot;width:100%;&amp;quot;! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; |Event:| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot;|{{{event}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | Start:| {{{start|}}}! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | End:| {{{end|}}}|-! style=&amp;quot;text-align: left;&amp;quot;| Type:| style=&amp;quot;text-align: left;&amp;quot;| {{{type|}}}! style=&amp;quot;width: 80px; text-align: left; vertical-align: middle;&amp;quot; | Location:| {{{location|}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: top;&amp;quot; | Description:| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot; | {{{description|}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; || style=&amp;quot;text-align: right;&amp;quot; colspan=&amp;quot;3&amp;quot; | [[Demo:Event calendar|Other events]]|} __NOFACTBOX__ [[Page has default form::Event calendar item| ]] {{#subobject:|Has event={{{event|}}}|Has event start={{{start|}}}|Has event end={{{end|}}}|Has event type={{{type|}}}|Has event location={{{location|}}}|Has event icon={{#switch: {{{type|}}}|Meeting =File:Event-meeting-icon.png|Presentation=File:Event-presentation-icon.png|Talk=File:Event-talk-icon.png }}|Has event color={{#switch: {{{type|}}}|Meeting=#E9AF32|Presentation=#A0D8F1|Talk=#BF381A|Party=#E07628 }}|Has event description={{{description|}}} }}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:Event_Calendar_Item</id>
		<title>Template:Event Calendar Item</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:Event_Calendar_Item"/>
				<updated>2013-01-28T22:42:10Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Event Calendar Item&amp;quot; template.&lt;br /&gt;
It should be called in the following format:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{Event Calendar Item&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Edit the page to see the template text.&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&lt;br /&gt;
{| style=&amp;quot;width:100%;&amp;quot;! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; |Event:| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot;|{{{event}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | Start:| {{{start|}}}! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; | End:| {{{end|}}}|-! style=&amp;quot;text-align: left;&amp;quot;| Type:| style=&amp;quot;text-align: left;&amp;quot;| {{{type|}}}! style=&amp;quot;width: 80px; text-align: left; vertical-align: middle;&amp;quot; | Location:| {{{location|}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: top;&amp;quot; | Description:| style=&amp;quot;text-align: left;&amp;quot; colspan=&amp;quot;3&amp;quot; | {{{description|}}}|-! style=&amp;quot;width: 110px; text-align: left; vertical-align: middle;&amp;quot; || style=&amp;quot;text-align: right;&amp;quot; colspan=&amp;quot;3&amp;quot; | [[Demo:Event calendar|Other events]]|} __NOFACTBOX__ [[Page has default form::Event calendar item| ]] {{#subobject:|Has event={{{event|}}}|Has event start={{{start|}}}|Has event end={{{end|}}}|Has event type={{{type|}}}|Has event location={{{location|}}}|Has event icon={{#switch: {{{type|}}}|Meeting =File:Event-meeting-icon.png|Presentation=File:Event-presentation-icon.png|Talk=File:Event-talk-icon.png }}|Has event color={{#switch: {{{type|}}}|Meeting=#E9AF32|Presentation=#A0D8F1|Talk=#BF381A|Party=#E07628 }}|Has event description={{{description|}}} }}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:Event_Calendar_Item</id>
		<title>Template:Event Calendar Item</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:Event_Calendar_Item"/>
				<updated>2013-01-28T22:41:38Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Created page with &amp;quot;&amp;lt;noinclude&amp;gt; This is the &amp;quot;Event Calendar Item&amp;quot; template. It should be called in the following format: &amp;lt;pre&amp;gt; {{Event Calendar Item }} &amp;lt;/pre&amp;gt; Edit the page to see the template te...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
This is the &amp;quot;Event Calendar Item&amp;quot; template.&lt;br /&gt;
It should be called in the following format:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{Event Calendar Item&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Edit the page to see the template text.&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:User_page</id>
		<title>Template:User page</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:User_page"/>
				<updated>2013-01-19T17:16:28Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{welcome|}}}&lt;br /&gt;
&lt;br /&gt;
== Biography ==&lt;br /&gt;
{{{biography|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== History using Linux ==&lt;br /&gt;
{{{history_linux|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== History on Funtoo ==&lt;br /&gt;
{{{history_funtoo|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Collaboration on Open Source projects ==&lt;br /&gt;
{{{oss_information|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Language Skills ==&lt;br /&gt;
{{{lang_skills|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Parts working on at the moment ==&lt;br /&gt;
{{{working_on|Nothing yet}}}&lt;br /&gt;
&lt;br /&gt;
== Parts worked on ==&lt;br /&gt;
{{{worked_on|Nothing yet}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== About real life ==&lt;br /&gt;
{{{real_life|Not disclosed}}}&lt;br /&gt;
__NOEDITSECTION__&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Template:User_page</id>
		<title>Template:User page</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Template:User_page"/>
				<updated>2013-01-19T17:11:44Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{{welcome|}}}&lt;br /&gt;
&lt;br /&gt;
== Biography ==&lt;br /&gt;
{{{biography|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== History using Linux ==&lt;br /&gt;
{{{history_linux|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== History on Funtoo ==&lt;br /&gt;
{{{history_funtoo|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Collaboration on Open Source projects ==&lt;br /&gt;
{{{oss_information|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== About real life ==&lt;br /&gt;
{{{real_life|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Language Skills ==&lt;br /&gt;
{{{lang_skills|Not disclosed}}}&lt;br /&gt;
&lt;br /&gt;
== Parts working on at the moment ==&lt;br /&gt;
{{{working_on|Nothing yet}}}&lt;br /&gt;
&lt;br /&gt;
== Parts worked on ==&lt;br /&gt;
{{{worked_on|Nothing yet}}}&lt;br /&gt;
__NOEDITSECTION__&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/User:Golodhrim</id>
		<title>User:Golodhrim</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/User:Golodhrim"/>
				<updated>2013-01-19T17:07:30Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Person&lt;br /&gt;
|Full name=Martin 'golodhrim' Scholz&lt;br /&gt;
|Email=golodhrim@funtoo.org&lt;br /&gt;
|Nick=golodhrim&lt;br /&gt;
|Geoloc=51.13379, 8.86179&lt;br /&gt;
|Location name=Ederbringhauen, Hessen, Germany&lt;br /&gt;
|Roles={{Role&lt;br /&gt;
|Role type=Staff&lt;br /&gt;
|Role desc=Core Community Manager&lt;br /&gt;
|Start date=2009/09/01&lt;br /&gt;
}}{{Role&lt;br /&gt;
|Role type=User&lt;br /&gt;
|Role desc=Just a User&lt;br /&gt;
|Start date=2009/01/01&lt;br /&gt;
|End date=2009/09/30&lt;br /&gt;
}}&lt;br /&gt;
|Maintains={{Ebuild&lt;br /&gt;
|Ebuild=www-servers/nginx&lt;br /&gt;
|Overlay=Funtoo-overlay&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=sys-process/whenjobs&lt;br /&gt;
|Overlay=Funtoo-overlay&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=dev-lua/linotify&lt;br /&gt;
|Overlay=Flora&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=net-im/prosody-modules&lt;br /&gt;
|Overlay=Flora&lt;br /&gt;
}}&lt;br /&gt;
|Blogs=&lt;br /&gt;
}}&lt;br /&gt;
{{User page&lt;br /&gt;
|fileextention=png&lt;br /&gt;
|welcome= == Mae Govannen randir == &lt;br /&gt;
pedo mellon a minno &lt;br /&gt;
(be greeted hiker)&lt;br /&gt;
|biography=studying Math and Chemstry for educational science right know, hopefully finish it that year and see where I move then... Normally I'm found online in jabber/xmpp network all the time. Next to it I hang around in [irc://irc.freenode.net/funtoo #funtoo], [irc://irc.freenode.net/funtoo-quebec #funtoo-quebec] and some others not related to funtoo...&lt;br /&gt;
|history_linux=I started my way to Linux by an advice of an teacher of mine with SuSE Linux 6.* stayed there until 9.0 and it was fun as long as you didn't update your system, this period hold for about 2 years, then I switched to debian and stayed there until Spring 2009, that was the time I gave Gentoo a try and it was fun at first to install it, but the war of releasing upgrades without a careful testing made it a hell and so I switched from gentoo to funtoo only after about a quarter year. Since then I stayed with funtoo.&lt;br /&gt;
|oss_information=working on some ConTeXt projects too, right now try to write an source ebuild for it...&lt;br /&gt;
|history_funtoo=using it since 2009 and beeing very happy with it, maintaining my private overlay with smaller ebuilds...&lt;br /&gt;
|real_life=&amp;lt;pre&amp;gt;$ man rl&lt;br /&gt;
&lt;br /&gt;
rl(1)                             The Real Life                             rl(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
       rl - reallife&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       rl [ Options ]&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       rl, short for reallife, refers to life in the real world.&lt;br /&gt;
&lt;br /&gt;
       rl would mean that you have a life next to Funtoo, Linux or hacking,&lt;br /&gt;
       what wouldn't affect all the devs, except for a little offtime they take&lt;br /&gt;
       for regenerating their internal batteries. Therefore &amp;quot;rl&amp;quot; has several&lt;br /&gt;
       options that can be used to explain what to do in rl mode.&lt;br /&gt;
&lt;br /&gt;
       The rl-mode can only be set in combination with a Geek or Hacker that you&lt;br /&gt;
       have in front of the computer screen.&lt;br /&gt;
&lt;br /&gt;
OPTIONS&lt;br /&gt;
       --eat, -e &amp;lt;MEAL&amp;gt; &amp;lt;TIME&amp;gt;&lt;br /&gt;
              Used to move the Geek or Hacker into the kitchen and let him prepare&lt;br /&gt;
              a meal specified by &amp;lt;MEAL&amp;gt; for the given daytime &amp;lt;TIME&amp;gt;, where &amp;lt;TIME&amp;gt;&lt;br /&gt;
              is in the form of mm/dd/yyyy-hh:mm. If &amp;lt;MEAL&amp;gt; and &amp;lt;TIME&amp;gt; isn't&lt;br /&gt;
              specified it means that the Geek/Hacker will grab the next phone,&lt;br /&gt;
              call the local Pizza or Doener delivery service and order a Pizza or&lt;br /&gt;
              Doener there, that he will consume as soon as it arrives.&lt;br /&gt;
&lt;br /&gt;
       --weekend, -we&lt;br /&gt;
              moves the Geek or Hacker into a two day lasting weekend where he is&lt;br /&gt;
              normaly not available on the PC, but it might happen that he has a&lt;br /&gt;
              connection to the internet from his cell-phone, so better take it&lt;br /&gt;
              away.&lt;br /&gt;
&lt;br /&gt;
       --suspend, --sleep, -s &amp;lt;TIME&amp;gt;&lt;br /&gt;
              moves the Geek or Hacker for &amp;lt;TIME&amp;gt; in seconds to sleep, if &amp;lt;TIME&amp;gt;&lt;br /&gt;
              isn't specified it defaults here to 10800 seconds what would be 3hrs.&lt;br /&gt;
&lt;br /&gt;
       --drink, -d &amp;lt;DRINK&amp;gt; &amp;lt;AMOUNT&amp;gt; &amp;lt;TIME&amp;gt;&lt;br /&gt;
              so that the Geek or Hacker doesn't die, he also sometimes need to drink.&lt;br /&gt;
              this moves him to get &amp;lt;AMOUNT&amp;gt; of &amp;lt;DRINK&amp;gt; at &amp;lt;TIME&amp;gt;. If you specified&lt;br /&gt;
              &amp;lt;DRINK&amp;gt; it is necessary that you also specify the &amp;lt;AMOUNT&amp;gt; else the&lt;br /&gt;
              command is abborted. When the drinking should happen at a special time&lt;br /&gt;
              add &amp;lt;TIME&amp;gt; in format mm/dd/yyyy-hh:mm to the command. If you just use&lt;br /&gt;
              the drink-option it will default to &amp;lt;DRINK&amp;gt;=coffee or Jolt-coke&lt;br /&gt;
              depending on what the Geek or Hacker sees first and &amp;lt;AMOUNT&amp;gt;=2-3 cups&lt;br /&gt;
              or cans and &amp;lt;TIME&amp;gt;=now.&lt;br /&gt;
&lt;br /&gt;
       --holiday, -away, -a &amp;lt;TIME&amp;gt;&lt;br /&gt;
              will move the Geek or Hacker away from the net for &amp;lt;TIME&amp;gt; and give him&lt;br /&gt;
              a recreational pause. He will come back after &amp;lt;TIME&amp;gt; to work with more&lt;br /&gt;
              power and even better ideas. &amp;lt;TIME&amp;gt; here is explicit needed and has to&lt;br /&gt;
              be given in format of days or weeks, so 14d will be equal to 2w.&lt;br /&gt;
&lt;br /&gt;
       --social_contact, -sc &amp;lt;PERSON&amp;gt; or &amp;lt;GROUP&amp;gt;&lt;br /&gt;
              that moves the Geek or Hacker away from the PC for a short period where&lt;br /&gt;
              a &amp;lt;PERSON&amp;gt; or &amp;lt;GROUP&amp;gt; comes over to visit him or he needs to move to&lt;br /&gt;
              them. The period of time he is away can vary from several hours to some&lt;br /&gt;
              days, so be patient if this option is set.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|lang_skills=I speak German as my native lang and learned English for 8 and French for 5 years at School. ATM I'm not really used to talk French any more as I hadn't had a opportunity to do so for the last years... So will give my best to also help our french users, feel free to ask. For places to meet me see at Biography...&lt;br /&gt;
|working_on= * working on [[flora]], the Funtoo Linux Overlay for User Contribution&lt;br /&gt;
* writing howto for [[nginx]]&lt;br /&gt;
* writing howto for [[wpa_supplicant]] &lt;br /&gt;
* writing an ebuild for ConTeXt-minimals source based, atm a low priority project...&lt;br /&gt;
|worked_on=* updated ebuild for dhcpcd-5.2.11&lt;br /&gt;
* tested sandbox 2.5 with metro&lt;br /&gt;
* starting to rewrite the quick install howto from Guy Fontaine to [[Funtoo_Quick_Install]]&lt;br /&gt;
* update Funtoo install guide with quick install guide&lt;br /&gt;
* writing guide for [[flora]], the Funtoo Linux Overlay for User Contribution&lt;br /&gt;
}}&lt;br /&gt;
== Boxes ==&lt;br /&gt;
* mordor -- Homeserver (x86_64 architecture) ~funtoo&lt;br /&gt;
* hobbigen -- Main PC (x86_64 architecture) ~funtoo will be there for a gentoo bug resolver&lt;br /&gt;
* lorien -- Laptop (x86_64 architecture) ~funtoo HP Compaq 6820s (died 2011)&lt;br /&gt;
* lorien -- Laptop (x86_64 architecture) ~funtoo experimental Dell Vostro 6830&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/User:Golodhrim</id>
		<title>User:Golodhrim</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/User:Golodhrim"/>
				<updated>2013-01-19T17:05:34Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Person&lt;br /&gt;
|Full name=Martin 'golodhrim' Scholz&lt;br /&gt;
|Email=golodhrim@funtoo.org&lt;br /&gt;
|Nick=golodhrim&lt;br /&gt;
|Geoloc=51.13379, 8.86179&lt;br /&gt;
|Location name=Ederbringhauen, Hessen, Germany&lt;br /&gt;
|Roles={{Role&lt;br /&gt;
|Role type=Staff&lt;br /&gt;
|Role desc=Core Community Manager&lt;br /&gt;
|Start date=2009/09/01&lt;br /&gt;
}}{{Role&lt;br /&gt;
|Role type=User&lt;br /&gt;
|Role desc=Just a User&lt;br /&gt;
|Start date=2009/01/01&lt;br /&gt;
|End date=2009/09/30&lt;br /&gt;
}}&lt;br /&gt;
|Maintains={{Ebuild&lt;br /&gt;
|Ebuild=www-servers/nginx&lt;br /&gt;
|Overlay=Funtoo-overlay&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=sys-process/whenjobs&lt;br /&gt;
|Overlay=Funtoo-overlay&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=dev-lua/linotify&lt;br /&gt;
|Overlay=Flora&lt;br /&gt;
}}{{Ebuild&lt;br /&gt;
|Ebuild=net-im/prosody-modules&lt;br /&gt;
|Overlay=Flora&lt;br /&gt;
}}&lt;br /&gt;
|Blogs=&lt;br /&gt;
}}&lt;br /&gt;
{{User page&lt;br /&gt;
|fileextention=png&lt;br /&gt;
|welcome= == Mae Govannen randir == &lt;br /&gt;
pedo mellon a minno &lt;br /&gt;
(be greeted hiker)&lt;br /&gt;
|nickname=golodhrim&lt;br /&gt;
|realname=Martin Scholz&lt;br /&gt;
|country=Germany&lt;br /&gt;
|birthdate=September 6th&lt;br /&gt;
|website=http://scholz-net.org/blog/&lt;br /&gt;
|biography=studying Math and Chemstry for educational science right know, hopefully finish it that year and see where I move then... Normally I'm found online in jabber/xmpp network all the time. Next to it I hang around in [irc://irc.freenode.net/funtoo #funtoo], [irc://irc.freenode.net/funtoo-quebec #funtoo-quebec] and some others not related to funtoo...&lt;br /&gt;
|history_linux=I started my way to Linux by an advice of an teacher of mine with SuSE Linux 6.* stayed there until 9.0 and it was fun as long as you didn't update your system, this period hold for about 2 years, then I switched to debian and stayed there until Spring 2009, that was the time I gave Gentoo a try and it was fun at first to install it, but the war of releasing upgrades without a careful testing made it a hell and so I switched from gentoo to funtoo only after about a quarter year. Since then I stayed with funtoo.&lt;br /&gt;
|oss_information=working on some ConTeXt projects too, right now try to write an source ebuild for it...&lt;br /&gt;
|history_funtoo=using it since 2009 and beeing very happy with it, maintaining my private overlay with smaller ebuilds...&lt;br /&gt;
|real_life=&amp;lt;pre&amp;gt;$ man rl&lt;br /&gt;
&lt;br /&gt;
rl(1)                             The Real Life                             rl(1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NAME&lt;br /&gt;
       rl - reallife&lt;br /&gt;
&lt;br /&gt;
SYNOPSIS&lt;br /&gt;
       rl [ Options ]&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
       rl, short for reallife, refers to life in the real world.&lt;br /&gt;
&lt;br /&gt;
       rl would mean that you have a life next to Funtoo, Linux or hacking,&lt;br /&gt;
       what wouldn't affect all the devs, except for a little offtime they take&lt;br /&gt;
       for regenerating their internal batteries. Therefore &amp;quot;rl&amp;quot; has several&lt;br /&gt;
       options that can be used to explain what to do in rl mode.&lt;br /&gt;
&lt;br /&gt;
       The rl-mode can only be set in combination with a Geek or Hacker that you&lt;br /&gt;
       have in front of the computer screen.&lt;br /&gt;
&lt;br /&gt;
OPTIONS&lt;br /&gt;
       --eat, -e &amp;lt;MEAL&amp;gt; &amp;lt;TIME&amp;gt;&lt;br /&gt;
              Used to move the Geek or Hacker into the kitchen and let him prepare&lt;br /&gt;
              a meal specified by &amp;lt;MEAL&amp;gt; for the given daytime &amp;lt;TIME&amp;gt;, where &amp;lt;TIME&amp;gt;&lt;br /&gt;
              is in the form of mm/dd/yyyy-hh:mm. If &amp;lt;MEAL&amp;gt; and &amp;lt;TIME&amp;gt; isn't&lt;br /&gt;
              specified it means that the Geek/Hacker will grab the next phone,&lt;br /&gt;
              call the local Pizza or Doener delivery service and order a Pizza or&lt;br /&gt;
              Doener there, that he will consume as soon as it arrives.&lt;br /&gt;
&lt;br /&gt;
       --weekend, -we&lt;br /&gt;
              moves the Geek or Hacker into a two day lasting weekend where he is&lt;br /&gt;
              normaly not available on the PC, but it might happen that he has a&lt;br /&gt;
              connection to the internet from his cell-phone, so better take it&lt;br /&gt;
              away.&lt;br /&gt;
&lt;br /&gt;
       --suspend, --sleep, -s &amp;lt;TIME&amp;gt;&lt;br /&gt;
              moves the Geek or Hacker for &amp;lt;TIME&amp;gt; in seconds to sleep, if &amp;lt;TIME&amp;gt;&lt;br /&gt;
              isn't specified it defaults here to 10800 seconds what would be 3hrs.&lt;br /&gt;
&lt;br /&gt;
       --drink, -d &amp;lt;DRINK&amp;gt; &amp;lt;AMOUNT&amp;gt; &amp;lt;TIME&amp;gt;&lt;br /&gt;
              so that the Geek or Hacker doesn't die, he also sometimes need to drink.&lt;br /&gt;
              this moves him to get &amp;lt;AMOUNT&amp;gt; of &amp;lt;DRINK&amp;gt; at &amp;lt;TIME&amp;gt;. If you specified&lt;br /&gt;
              &amp;lt;DRINK&amp;gt; it is necessary that you also specify the &amp;lt;AMOUNT&amp;gt; else the&lt;br /&gt;
              command is abborted. When the drinking should happen at a special time&lt;br /&gt;
              add &amp;lt;TIME&amp;gt; in format mm/dd/yyyy-hh:mm to the command. If you just use&lt;br /&gt;
              the drink-option it will default to &amp;lt;DRINK&amp;gt;=coffee or Jolt-coke&lt;br /&gt;
              depending on what the Geek or Hacker sees first and &amp;lt;AMOUNT&amp;gt;=2-3 cups&lt;br /&gt;
              or cans and &amp;lt;TIME&amp;gt;=now.&lt;br /&gt;
&lt;br /&gt;
       --holiday, -away, -a &amp;lt;TIME&amp;gt;&lt;br /&gt;
              will move the Geek or Hacker away from the net for &amp;lt;TIME&amp;gt; and give him&lt;br /&gt;
              a recreational pause. He will come back after &amp;lt;TIME&amp;gt; to work with more&lt;br /&gt;
              power and even better ideas. &amp;lt;TIME&amp;gt; here is explicit needed and has to&lt;br /&gt;
              be given in format of days or weeks, so 14d will be equal to 2w.&lt;br /&gt;
&lt;br /&gt;
       --social_contact, -sc &amp;lt;PERSON&amp;gt; or &amp;lt;GROUP&amp;gt;&lt;br /&gt;
              that moves the Geek or Hacker away from the PC for a short period where&lt;br /&gt;
              a &amp;lt;PERSON&amp;gt; or &amp;lt;GROUP&amp;gt; comes over to visit him or he needs to move to&lt;br /&gt;
              them. The period of time he is away can vary from several hours to some&lt;br /&gt;
              days, so be patient if this option is set.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|lang_skills=I speak German as my native lang and learned English for 8 and French for 5 years at School. ATM I'm not really used to talk French any more as I hadn't had a opportunity to do so for the last years... So will give my best to also help our french users, feel free to ask. For places to meet me see at Biography...&lt;br /&gt;
|working_on= * working on [[flora]], the Funtoo Linux Overlay for User Contribution&lt;br /&gt;
* writing howto for [[nginx]]&lt;br /&gt;
* writing howto for [[wpa_supplicant]] &lt;br /&gt;
* writing an ebuild for ConTeXt-minimals source based, atm a low priority project...&lt;br /&gt;
|worked_on=* updated ebuild for dhcpcd-5.2.11&lt;br /&gt;
* tested sandbox 2.5 with metro&lt;br /&gt;
* starting to rewrite the quick install howto from Guy Fontaine to [[Funtoo_Quick_Install]]&lt;br /&gt;
* update Funtoo install guide with quick install guide&lt;br /&gt;
* writing guide for [[flora]], the Funtoo Linux Overlay for User Contribution&lt;br /&gt;
}}&lt;br /&gt;
== Boxes ==&lt;br /&gt;
* mordor -- Homeserver (x86_64 architecture) ~funtoo&lt;br /&gt;
* hobbigen -- Main PC (x86_64 architecture) ~funtoo will be there for a gentoo bug resolver&lt;br /&gt;
* lorien -- Laptop (x86_64 architecture) ~funtoo HP Compaq 6820s&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Linux</id>
		<title>Funtoo Linux</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Linux"/>
				<updated>2013-01-12T00:36:35Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: /* Differences between Funtoo Linux and Gentoo Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started =&lt;br /&gt;
Start by [[Funtoo Linux Installation|installing Funtoo]]. If you have questions, someone has probably asked them already in our [[Funtoo Linux FAQ]]. Otherwise, there are other [[Funtoo Wiki:Community portal|community resources]] available. For more information on the vision of Funtoo, see: [[vision]]&lt;br /&gt;
&lt;br /&gt;
= Differences between Funtoo Linux and Gentoo Linux =&lt;br /&gt;
&lt;br /&gt;
From an installation perspective, the main difference between Funtoo Linux and Gentoo Linux is that Funtoo Linux has a different Portage tree. We store our Portage tree in a git repository. Our Portage tree does track the Gentoo repository (we import Gentoo changes almost every day,) but our tree does contain some significant changes from Gentoo's tree.&lt;br /&gt;
&lt;br /&gt;
For the purpose of users Funtoo Linux decided to run a three modeled tree, the stable, the current and the experimental tree. Experimental tree is designed for Core Team in general to work on new features and is a seperated tree not available by keywords, for stable Funtoo uses the &amp;quot;*&amp;quot; arch-keyword and for current the &amp;quot;~*&amp;quot; arch-keyword. Most of the time current and experimental do not differ, but in cases of new features or toolchain updates both differ as some testings might break your system, so we like to keep this away from users while we test. Read more about it under [[Funtoo Linux#What are the differences between 'stable', 'current' and 'experimental' ?|What are the differences between 'stable', 'current' and 'experimental' ?]]&lt;br /&gt;
&lt;br /&gt;
Here is a basic overview of how Funtoo Linux differ from Gentoo Linux:&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
!||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;|stable||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f78888;&amp;quot;|current||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f70088;&amp;quot;|experimental&lt;br /&gt;
|-&lt;br /&gt;
!Category&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!portage&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.1.11.31&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; | 2.1.11.40&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!portage tree&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |rsync-based&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |rsync-based&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!glibc&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.16.0&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!gcc&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!udev&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |171-r9&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |197-r1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!init scripts&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!perl&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |5.12.4-r1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.12.4-r1&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!ruby&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |1.8.7_p370&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p370&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!core openresolv&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |no&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |no&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!custom pkgs&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!merged overlays&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!upstream tree&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo stable&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo unstable&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo unstable&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;|stable||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f78888;&amp;quot;|current||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f70088;&amp;quot;|experimental&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= What are the differences between 'stable', 'current' and 'experimental' ? =&lt;br /&gt;
&lt;br /&gt;
Funtoo Linux follows a continuous development cycle. This means that new packages are continuously added to the [[Portage Tree]] and others are periodically improved with patches and bug fixes. &lt;br /&gt;
&lt;br /&gt;
When a package is considered to be stable, it is tagged as such, and means that you are very unlikely to have trouble with it during installation and in daily usage. All other packages are typically tagged as 'current' meaning they have undergone less widespread testing and you are more likely to experience issues with the software itself, or a package build failure. However, in day-to-day experience:&lt;br /&gt;
&lt;br /&gt;
* Funtoo 'experimental' is the the development tree for CoreTeam members, it generally is the Funtoo 'current' tree to which tools are added that are right now at a testing, if one of these testing circles is done and finished the 'experimental' tree is merged into the 'current' tree and will so long not difer from it, until new packages with heavy impact are there for being tested. This tree is just designed for CoreTeam members as troubles might be more common here than in 'current'.&lt;br /&gt;
&lt;br /&gt;
* '''Funtoo 'current' is almost as stable as Funtoo 'stable'''', although some troubles may appear from time to time. Some distributions name their 'current' branch 'unstable' but we do not because it implies that &amp;quot;unstable == unusable&amp;quot; (Funtoo current '''IS''' usable for a daily usage in production environments, depending on your requirements). &lt;br /&gt;
&lt;br /&gt;
* Funtoo 'stable' can, per definition, lag '''a long ways behind''' 'current'. This branch is recommended for setting up servers which have standard and very well supported hardware for a long time. If you have a desktop machine which requires the most recent drivers / kernel available using 'stable' may not be a solution for you. Efforts are also made to ensure compatibility with stable Red Hat Enterprise Linux 5 kernels for use in environments where stability is of the utmost importance.&lt;br /&gt;
&lt;br /&gt;
= What's Been Done So Far =&lt;br /&gt;
&lt;br /&gt;
My technical goals for Funtoo Linux are to focus on improving the core Gentoo system, ie. what you'd find inside a stage3. I also have been working to improve general Gentoo technologies, such as migrating Portage to git, and ensuring that Funtoo is easily buildable in an automated way, by creating Metro. These changes are intended to empower me to improve Funtoo more easily, and are shared with you so that you can benefit from them as well.&lt;br /&gt;
&lt;br /&gt;
These improvements are detailed below:&lt;br /&gt;
&lt;br /&gt;
== Git-based Portage Tree ==&lt;br /&gt;
&lt;br /&gt;
One of the first things I did was migrate Gentoo's development Portage tree from cvs to git, and migrate Gentoo's user Portage tree from rsync to git. This was done to help me work more effectively, since git is simply a much more powerful and efficient tool than cvs.&lt;br /&gt;
&lt;br /&gt;
Zack Medico, Portage/emerge maintainer, has enhanced the 2.2 version of Portage so that it is compatible with git. This allows ''users'' to pull a Portage tree from a git repository. This can often be more efficient than rsync, although the git repository does take up more space on disk. But I did not switch away from rsync because it wasn't fast enough.&lt;br /&gt;
&lt;br /&gt;
More important for me is the fact that users can pull from the same repositories that I use for Funtoo development. This simplifies Funtoo infrastructure considerably, keeping things more fun for me :)&lt;br /&gt;
&lt;br /&gt;
Git also provides integrity-checking functionality that is superior to that which currently exists in Portage, which will allow improved data integrity checks in future versions of Portage. This work is not yet finished, or even really started, but by using git we are starting to move in this direction. This work will continue as I have time.&lt;br /&gt;
&lt;br /&gt;
== Forked Tree ==&lt;br /&gt;
&lt;br /&gt;
Funtoo has its own Portage tree that is 99% identical to Gentoo's Portage tree. I merge changes from Gentoo into our tree every 12 hours, using an automated process. Our tree has a few significant differences from the Gentoo Portage tree, which are covered in more detail in our [http://www.funtoo.org/en/articles/funtoo/quick-install-howto/ Quick Install Guide]&lt;br /&gt;
&lt;br /&gt;
I created my own Portage tree for a multitude of reasons. The main reason for creating the tree was so I could get improvements into my Portage tree immediately, changes which Gentoo developers may or may not be interested in adding to the official Gentoo tree. I don't want to wait around or try to convince someone to add a fix I need.&lt;br /&gt;
&lt;br /&gt;
== Metro and Daily Builds ==&lt;br /&gt;
&lt;br /&gt;
[[Metro]] is a tool I created to build Gentoo and Funtoo releases in an automated way. For around a year, I have been using Gentoo's catalyst, and now [[Metro]] to build daily releases of Gentoo and Funtoo. These stages are available on the [[Download|Download page]].&lt;br /&gt;
&lt;br /&gt;
Metro is a big improvement over Gentoo's automated build tool, catalyst, which I originally wrote but has not aged well over the years. Metro is still missing some functionality that exists in catalyst, most notably LiveCD support (I haven't created a Funtoo LiveCD yet, which is why :) but in nearly all other respects is much more capable than catalyst. I will continue to maintain and improve Metro as I have time. The daily builds serve as a good ongoing test for Metro as well as the integrity of the Funtoo Portage tree.&lt;br /&gt;
&lt;br /&gt;
== Forkable - Empowering Developers ==&lt;br /&gt;
&lt;br /&gt;
Combine the transition to git with Metro, and Funtoo is now actually quite easy to fork, unlike Gentoo. If you wanted to create your own derivative of Funtoo or Gentoo, you could simply clone my git repository and then set up Metro to build releases of this variant. With some basic familiarity with git, this can all be accomplished by an single individual in a single day.&lt;br /&gt;
&lt;br /&gt;
Why is this important? If you love Gentoo like I do, but want to work on Gentoo independently, so that you have your own personal &amp;amp;quot;fun, too&amp;amp;quot; project where ''you'' are Chief Architect, you have all the tools you need to make this happen. There is no longer a need to become an official Gentoo developer in order to grow in your Gentoo knowledge.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Core System Changes ==&lt;br /&gt;
Funtoo has several core system changes, and I plan to continue to focus on improving the core system quite a bit. Funtoo has its own &amp;lt;tt&amp;gt;sys-fs/udev&amp;lt;/tt&amp;gt; package, its own &amp;lt;tt&amp;gt;sys-apps/baselayout&amp;lt;/tt&amp;gt;, its own &amp;lt;tt&amp;gt;sys-apps/openrc&amp;lt;/tt&amp;gt; (which is used by default), along with various other packages and improvements. Work is currently under way on a [[Unified Configuration]] structure as well as new, improved profile method which allows specifying multiple profiles (See [[Multiple Profiles]]).&lt;br /&gt;
&lt;br /&gt;
== Articles ==&lt;br /&gt;
On the [[:Category:Articles|Articles]] page, you'll notice a number of technical articles and HOWTOs. My original IBM developerWorks Linux articles are gradually being added to the site and updated as time permits.&lt;br /&gt;
&lt;br /&gt;
Every now and then, I will be adding interesting new content, such as the intriguing [http://www.funtoo.org/en/security/slowloris/ Slowloris DOS Mitigation Guide], which details various mitigations for the Slowloris DOS that affects the Apache Web server. This article was co-authored with Ryan Vick, a security researcher who is a friend of mine.&lt;br /&gt;
&lt;br /&gt;
= What's in the Works =&lt;br /&gt;
In addition to various ongoing [[:Category:Projects|Funtoo Linux Projects]], there are other efforts.&lt;br /&gt;
&lt;br /&gt;
== Funtoo Filesystem Hierarchy ==&lt;br /&gt;
&lt;br /&gt;
The [[Funtoo Filesystem Hierarchy]] seeks to document the specific nuances of the Funtoo fileystem hierarchy beyond what is in the [http://pathname.com/fhs/ Filesystem Hierarchy Standard] already.&lt;br /&gt;
&lt;br /&gt;
[[Category:Funtoo]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Funtoo_Linux</id>
		<title>Funtoo Linux</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Funtoo_Linux"/>
				<updated>2013-01-12T00:30:41Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: /* Differences between Funtoo Linux and Gentoo Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Getting Started =&lt;br /&gt;
Start by [[Funtoo Linux Installation|installing Funtoo]]. If you have questions, someone has probably asked them already in our [[Funtoo Linux FAQ]]. Otherwise, there are other [[Funtoo Wiki:Community portal|community resources]] available. For more information on the vision of Funtoo, see: [[vision]]&lt;br /&gt;
&lt;br /&gt;
= Differences between Funtoo Linux and Gentoo Linux =&lt;br /&gt;
&lt;br /&gt;
From an installation perspective, the main difference between Funtoo Linux and Gentoo Linux is that Funtoo Linux has a different Portage tree. We store our Portage tree in a git repository. Our Portage tree does track the Gentoo repository (we import Gentoo changes almost every day,) but our tree does contain some significant changes from Gentoo's tree.&lt;br /&gt;
&lt;br /&gt;
For the purpose of users Funtoo Linux decided to run a three modeled tree, the stable, the current and the experimental tree. Experimental tree is designed for Core Team in general to work on new features and is a seperated tree not available by keywords, for stable Funtoo uses the &amp;quot;*&amp;quot; arch-keyword and for current the &amp;quot;~*&amp;quot; arch-keyword. Most of the time current and experimental do not differ, but in cases of new features or toolchain updates both differ as some testings might break your system, so we like to keep this away from users while we test.&lt;br /&gt;
&lt;br /&gt;
Here is a basic overview of how Funtoo Linux differ from Gentoo Linux:&lt;br /&gt;
&lt;br /&gt;
{| {{Table}}&lt;br /&gt;
!||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;|stable||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f78888;&amp;quot;|current||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f70088;&amp;quot;|experimental&lt;br /&gt;
|-&lt;br /&gt;
!Category&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |Gentoo Linux&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |Funtoo Linux&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!portage&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.1.11.31&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; | 2.1.11.40&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.3.5-r5 (funtoo)&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!portage tree&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |rsync-based&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |rsync-based&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |git-based&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!glibc&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |2.16.0&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |2.15-r3&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!gcc&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |4.6.3&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!udev&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |171-r9&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |197-r1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |171-r8&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!init scripts&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |openrc&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!perl&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |5.12.4-r1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.12.4-r1&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |5.16.1&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!ruby&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |1.8.7_p370&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p370&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |1.8.7_p371&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!core openresolv&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |no&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |no&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |yes&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!custom pkgs&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[[Portage (Funtoo)|portage]], udev, grub, coreboot, openrc, and [http://github.com/funtoo/funtoo-overlay more]&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!merged overlays&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |[https://github.com/slashbeast/foo-overlay slashbeast], [https://github.com/adessemond/bar-overlay A. Dessemond], [https://github.com/funtoo/flora flora]&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!upstream tree&lt;br /&gt;
|colspan=&amp;quot;1&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo stable&lt;br /&gt;
|style=&amp;quot;background-color: #ddf;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |None&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo unstable&lt;br /&gt;
|style=&amp;quot;background-color: #f78888;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|style=&amp;quot;background-color:#87CEEB;&amp;quot; |N/A&lt;br /&gt;
|style=&amp;quot;background-color:#A0E75A;&amp;quot; |gentoo unstable&lt;br /&gt;
|style=&amp;quot;background-color: #f70088;&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
!||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #ddf;&amp;quot;|stable||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f78888;&amp;quot;|current||colspan=&amp;quot;4&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;background-color: #f70088;&amp;quot;|experimental&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= What are the differences between 'stable', 'current' and 'experimental' ? =&lt;br /&gt;
&lt;br /&gt;
Funtoo Linux follows a continuous development cycle. This means that new packages are continuously added to the [[Portage Tree]] and others are periodically improved with patches and bug fixes. &lt;br /&gt;
&lt;br /&gt;
When a package is considered to be stable, it is tagged as such, and means that you are very unlikely to have trouble with it during installation and in daily usage. All other packages are typically tagged as 'current' meaning they have undergone less widespread testing and you are more likely to experience issues with the software itself, or a package build failure. However, in day-to-day experience:&lt;br /&gt;
&lt;br /&gt;
* Funtoo 'experimental' is the the development tree for CoreTeam members, it generally is the Funtoo 'current' tree to which tools are added that are right now at a testing, if one of these testing circles is done and finished the 'experimental' tree is merged into the 'current' tree and will so long not difer from it, until new packages with heavy impact are there for being tested. This tree is just designed for CoreTeam members as troubles might be more common here than in 'current'.&lt;br /&gt;
&lt;br /&gt;
* '''Funtoo 'current' is almost as stable as Funtoo 'stable'''', although some troubles may appear from time to time. Some distributions name their 'current' branch 'unstable' but we do not because it implies that &amp;quot;unstable == unusable&amp;quot; (Funtoo current '''IS''' usable for a daily usage in production environments, depending on your requirements). &lt;br /&gt;
&lt;br /&gt;
* Funtoo 'stable' can, per definition, lag '''a long ways behind''' 'current'. This branch is recommended for setting up servers which have standard and very well supported hardware for a long time. If you have a desktop machine which requires the most recent drivers / kernel available using 'stable' may not be a solution for you. Efforts are also made to ensure compatibility with stable Red Hat Enterprise Linux 5 kernels for use in environments where stability is of the utmost importance.&lt;br /&gt;
&lt;br /&gt;
= What's Been Done So Far =&lt;br /&gt;
&lt;br /&gt;
My technical goals for Funtoo Linux are to focus on improving the core Gentoo system, ie. what you'd find inside a stage3. I also have been working to improve general Gentoo technologies, such as migrating Portage to git, and ensuring that Funtoo is easily buildable in an automated way, by creating Metro. These changes are intended to empower me to improve Funtoo more easily, and are shared with you so that you can benefit from them as well.&lt;br /&gt;
&lt;br /&gt;
These improvements are detailed below:&lt;br /&gt;
&lt;br /&gt;
== Git-based Portage Tree ==&lt;br /&gt;
&lt;br /&gt;
One of the first things I did was migrate Gentoo's development Portage tree from cvs to git, and migrate Gentoo's user Portage tree from rsync to git. This was done to help me work more effectively, since git is simply a much more powerful and efficient tool than cvs.&lt;br /&gt;
&lt;br /&gt;
Zack Medico, Portage/emerge maintainer, has enhanced the 2.2 version of Portage so that it is compatible with git. This allows ''users'' to pull a Portage tree from a git repository. This can often be more efficient than rsync, although the git repository does take up more space on disk. But I did not switch away from rsync because it wasn't fast enough.&lt;br /&gt;
&lt;br /&gt;
More important for me is the fact that users can pull from the same repositories that I use for Funtoo development. This simplifies Funtoo infrastructure considerably, keeping things more fun for me :)&lt;br /&gt;
&lt;br /&gt;
Git also provides integrity-checking functionality that is superior to that which currently exists in Portage, which will allow improved data integrity checks in future versions of Portage. This work is not yet finished, or even really started, but by using git we are starting to move in this direction. This work will continue as I have time.&lt;br /&gt;
&lt;br /&gt;
== Forked Tree ==&lt;br /&gt;
&lt;br /&gt;
Funtoo has its own Portage tree that is 99% identical to Gentoo's Portage tree. I merge changes from Gentoo into our tree every 12 hours, using an automated process. Our tree has a few significant differences from the Gentoo Portage tree, which are covered in more detail in our [http://www.funtoo.org/en/articles/funtoo/quick-install-howto/ Quick Install Guide]&lt;br /&gt;
&lt;br /&gt;
I created my own Portage tree for a multitude of reasons. The main reason for creating the tree was so I could get improvements into my Portage tree immediately, changes which Gentoo developers may or may not be interested in adding to the official Gentoo tree. I don't want to wait around or try to convince someone to add a fix I need.&lt;br /&gt;
&lt;br /&gt;
== Metro and Daily Builds ==&lt;br /&gt;
&lt;br /&gt;
[[Metro]] is a tool I created to build Gentoo and Funtoo releases in an automated way. For around a year, I have been using Gentoo's catalyst, and now [[Metro]] to build daily releases of Gentoo and Funtoo. These stages are available on the [[Download|Download page]].&lt;br /&gt;
&lt;br /&gt;
Metro is a big improvement over Gentoo's automated build tool, catalyst, which I originally wrote but has not aged well over the years. Metro is still missing some functionality that exists in catalyst, most notably LiveCD support (I haven't created a Funtoo LiveCD yet, which is why :) but in nearly all other respects is much more capable than catalyst. I will continue to maintain and improve Metro as I have time. The daily builds serve as a good ongoing test for Metro as well as the integrity of the Funtoo Portage tree.&lt;br /&gt;
&lt;br /&gt;
== Forkable - Empowering Developers ==&lt;br /&gt;
&lt;br /&gt;
Combine the transition to git with Metro, and Funtoo is now actually quite easy to fork, unlike Gentoo. If you wanted to create your own derivative of Funtoo or Gentoo, you could simply clone my git repository and then set up Metro to build releases of this variant. With some basic familiarity with git, this can all be accomplished by an single individual in a single day.&lt;br /&gt;
&lt;br /&gt;
Why is this important? If you love Gentoo like I do, but want to work on Gentoo independently, so that you have your own personal &amp;amp;quot;fun, too&amp;amp;quot; project where ''you'' are Chief Architect, you have all the tools you need to make this happen. There is no longer a need to become an official Gentoo developer in order to grow in your Gentoo knowledge.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Core System Changes ==&lt;br /&gt;
Funtoo has several core system changes, and I plan to continue to focus on improving the core system quite a bit. Funtoo has its own &amp;lt;tt&amp;gt;sys-fs/udev&amp;lt;/tt&amp;gt; package, its own &amp;lt;tt&amp;gt;sys-apps/baselayout&amp;lt;/tt&amp;gt;, its own &amp;lt;tt&amp;gt;sys-apps/openrc&amp;lt;/tt&amp;gt; (which is used by default), along with various other packages and improvements. Work is currently under way on a [[Unified Configuration]] structure as well as new, improved profile method which allows specifying multiple profiles (See [[Multiple Profiles]]).&lt;br /&gt;
&lt;br /&gt;
== Articles ==&lt;br /&gt;
On the [[:Category:Articles|Articles]] page, you'll notice a number of technical articles and HOWTOs. My original IBM developerWorks Linux articles are gradually being added to the site and updated as time permits.&lt;br /&gt;
&lt;br /&gt;
Every now and then, I will be adding interesting new content, such as the intriguing [http://www.funtoo.org/en/security/slowloris/ Slowloris DOS Mitigation Guide], which details various mitigations for the Slowloris DOS that affects the Apache Web server. This article was co-authored with Ryan Vick, a security researcher who is a friend of mine.&lt;br /&gt;
&lt;br /&gt;
= What's in the Works =&lt;br /&gt;
In addition to various ongoing [[:Category:Projects|Funtoo Linux Projects]], there are other efforts.&lt;br /&gt;
&lt;br /&gt;
== Funtoo Filesystem Hierarchy ==&lt;br /&gt;
&lt;br /&gt;
The [[Funtoo Filesystem Hierarchy]] seeks to document the specific nuances of the Funtoo fileystem hierarchy beyond what is in the [http://pathname.com/fhs/ Filesystem Hierarchy Standard] already.&lt;br /&gt;
&lt;br /&gt;
[[Category:Funtoo]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/ZFS_rootfs_over_encrypted_container</id>
		<title>ZFS rootfs over encrypted container</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/ZFS_rootfs_over_encrypted_container"/>
				<updated>2013-01-11T23:54:58Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial will show you how to install Funtoo on ZFS (rootfs) over an encrypted container.&lt;br /&gt;
&lt;br /&gt;
This tutorial is meant to be an &amp;quot;overlay&amp;quot; over the [[Funtoo_Linux_Installation|Regular Funtoo Installation]]. Follow the normal installation and only use this guide for steps 2, 3, and 8.&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|'''Since ZFS was really designed for 64 bit systems, we are only recommending and supporting 64 bit platforms and installations. We will not be supporting 32 bit platforms'''!}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting up your environment ==&lt;br /&gt;
In order for us to install Funtoo on ZFS, you will need an environment that provides the ZFS userspace tools. We will be downloading two things, System Rescue CD 3.1.2, and the ZFS SRM (System Rescue Module). This is just a file that when combined with System Rescue CD, gives you ZFS functionality.&lt;br /&gt;
&lt;br /&gt;
[https://sourceforge.net/projects/systemrescuecd/files/sysresccd-x86/3.1.2/systemrescuecd-x86-3.1.2.iso/download Download System Rescue CD 3.1.2]&lt;br /&gt;
&lt;br /&gt;
[http://jonathanvasquez.com/files/sysresccd/ Download the ZFS System Rescue Module]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name: SystemRescueCd-x86-3.1.2 (350 MiB)&lt;br /&gt;
Release Date: 2012-12-05&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
md5sum 3c1ddfe5f26bb2f979a2ed9dfb504ee3&lt;br /&gt;
sha1sum 217cf7a81380d894b2433c59451787c16bc0af2f&lt;br /&gt;
sha256sum ec0a995875e64ff9816a043737e5cbbb689b7f596b48679116f0a779f3dce673&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once you place the ISO on your USB flash drive, extract the modules from the tarball, and place the .srm and .md5 at the root of your USB filesystem. Further instructions can be found [[Creating_System_Rescue_CD_Modules#Using_the_prebuilt_srm|here]]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will now start to partition the system. Open up a terminal, and type in the following (We will assume it's a fresh drive for simplicity).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating partitions ==&lt;br /&gt;
We will be creating two partitions, /boot, and the remaining disk space will be for ZFS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(All commands will be ran as root).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== fdisk (MBR Style) ===&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (ZFS over encrypted container):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
Command: ##i##t ↵&lt;br /&gt;
Partition number: ##i##2 ↵&lt;br /&gt;
Hex code (type L to list codes): ##i##bf ↵&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes&lt;br /&gt;
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors&lt;br /&gt;
Units = sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disk identifier: 0x3e954df7&lt;br /&gt;
   Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;
/dev/sda1            2048      514047      256000   83  Linux&lt;br /&gt;
/dev/sda2          514048  1953525167   976505560   bf  Solaris&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== gdisk (GPT Style) ===&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
Hex Code: ##i##↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (BIOS Boot Partition):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+32M ↵&lt;br /&gt;
Hex Code: ##i##EF02 ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|Only make the above BIOS Boot Partition if you are using GRUB 2 on GPT. If you are using the extlinux bootloader, this partition is not necessary. The below instructions continue as if you did not create this partition and assumes you are using extlinux as the bootloader.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2(/3)''' (ZFS over encrypted container):&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
Hex Code: ##i##bf01 ↵&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
Disk /dev/sda: 1953525168 sectors, 931.5 GiB&lt;br /&gt;
Logical sector size: 512 bytes&lt;br /&gt;
Disk identifier (GUID): C0C1E56A-B24F-492F-95DB-2E227676F228&lt;br /&gt;
Partition table holds up to 128 entries&lt;br /&gt;
First usable sector is 34, last usable sector is 1953525134&lt;br /&gt;
Partitions will be aligned on 2048-sector boundaries&lt;br /&gt;
Total free space is 2014 sectors (1007.0 KiB)&lt;br /&gt;
Number  Start (sector)    End (sector)  Size       Code  Name&lt;br /&gt;
   1            2048          514047   250.0 MiB   8300  Linux filesystem&lt;br /&gt;
   2          514048      1953525134   931.3 GiB   BF01  Solaris /usr &amp;amp; Mac ZFS&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Format your boot volume ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkfs.ext4 /dev/sda1&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the crypto container ===&lt;br /&gt;
Be aware that this step will take a lot of time, 1-2 days might be possible depending on your disksize. The bs part in the next commands is important, so that you don't know about the actual disksize and the disk get's filled up to the end with data for the cryptocontainer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##dd if=/dev/zero of=/dev/sda2 bs=100M&lt;br /&gt;
# ##i##dd if=/dev/urandom of=/dev/sda2 bs=100M&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next we will create the cryptocontainer in the before prepared partition and mount the container after that:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cryptsetup -c aes-xts-plain64 luksFormat /dev/sda2&lt;br /&gt;
# ##i##cryptsetup luksOpen /dev/sda2 enc-root&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This opens the cryptocontainer in '''/dev/mapper/enc-root''', what will from now on the device for our ZFS pool.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the zpool ===&lt;br /&gt;
We will first create the pool. The pool will be named `rpool` and the disk will be aligned to 4096 (using ashift=12)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool create -f -o ashift=12 -o cachefile= -O compression=on -m none -R /mnt/funtoo rpool /dev/mapper/enc-root&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create the zfs datasets ===&lt;br /&gt;
We will now create some datasets. For this installation, we will create a small but future proof amount of datasets. We will have a dataset for the OS (/), and your swap. We will also show you how to create some optional datasets: /home, /var, /usr/src, and /usr/portage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Create some empty containers for organization purposes, and make the dataset that will hold /&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/ROOT&lt;br /&gt;
# ##i##zfs create -o mountpoint=/ rpool/ROOT/funtoo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Optional, but recommended datasets: /home, /root &lt;br /&gt;
# ##i##zfs create -o mountpoint=/home rpool/HOME&lt;br /&gt;
# ##i##zfs create -o mountpoint=/root rpool/HOME/root&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Optional datasets: /usr/src, /var&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/FUNTOO&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/src rpool/FUNTOO/src&lt;br /&gt;
# ##i##zfs create -o mountpoint=/var rpool/FUNTOO/var&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Creating a separate portage dataset (optional) ====&lt;br /&gt;
Creating a separate portage dataset could be useful if you would like to keep your portage tree, distfiles (source code files), and packages (your compiled binaries if you have FEATURES=&amp;quot;buildpkg&amp;quot; enabled) in a safe place (or if you want to back up this directory up easily).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This requires a few extra steps because we can't just do a regular emerge --sync when we initially chroot. We will need to download a portage snapshot tarball and extract it into the directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The required steps for getting and extracting the snapshot will be shown later on in the guide once you chroot into the environment. For now just create the datasets:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage -o compression=off rpool/FUNTOO/portage&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage/distfiles -o compression=off rpool/FUNTOO/distfiles&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Create your swap dataset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Make your swap +1G greater than your RAM. An 8G machine would have 9G of RAM (This is kinda big though).'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 9G rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Format your swap dataset ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkswap -f /dev/zvol/rpool/swap&lt;br /&gt;
# ##i##swapon /dev/zvol/rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alright that finishes the creation of the zpool and zfs datasets. Check to make sure everything appears fine:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Copy the zpool.cache file to your new environment.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkdir -p /mnt/funtoo/etc/zfs&lt;br /&gt;
# ##i##cp /etc/zfs/zpool.cache /mnt/funtoo/etc/zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Make an empty mtab file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##touch /mnt/funtoo/etc/mtab&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now we will continue to install funtoo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing Funtoo ==&lt;br /&gt;
[[Funtoo_Linux_Installation|Download and install the Funtoo stage3 and continue installation as normal.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then chroot into your new funtoo environment:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mount your boot drive&lt;br /&gt;
# ##i##mount /dev/sda1 /mnt/funtoo/boot&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bind the kernel related directories&lt;br /&gt;
# ##i##for i in proc dev sys; do mount --bind /$i ./$i; done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Copy network settings&lt;br /&gt;
# ##i##cp /etc/resolv.conf etc/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
chroot into your new funtoo environment&lt;br /&gt;
# ##i##env -i HOME=/root TERM=$TERM chroot . bash -l&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Syncing your portage tree ===&lt;br /&gt;
==== If you didn't create a separate portage dataset, then just sync your portage tree as normal. ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== If you did create a separate portage dataset, let's now get the portage snapshot set up. ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Change into your /usr directory&lt;br /&gt;
# ##i##cd /usr&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Download and extract the portage snapshot&lt;br /&gt;
# ##i##wget http://ftp.osuosl.org/pub/funtoo/funtoo-current/snapshots/portage-latest.tar.xz&lt;br /&gt;
# ##i##tar xf portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Change into your portage directory and checkout the funtoo branch&lt;br /&gt;
# ##i##cd portage&lt;br /&gt;
# ##i##git checkout funtoo.org&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now sync your portage tree&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Kernel Configuration ==&lt;br /&gt;
Tested with kernel 2.6.32, 3.2.34, 3.6.9, 3.7.1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you get up to the kernel, make sure that you disable the CFQ scheduler, and turnon No-op (It's the default one once you disable all schedulers). The reason for this is because ZFS has itsown scheduler and the CFQ one conflicts with it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Go to your kernel config, and make sure you have the following: (there should be a /usr/src/linux symlink as well)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ZLIB_INFLATE/DEFLATE must be compiled into the kernel (not as a module).&lt;br /&gt;
&amp;gt; ZLIB_INFLATE [=y], ZLIB_DEFLATE [=y]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
General setup ---&amp;gt;&lt;br /&gt;
&amp;gt; [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support&lt;br /&gt;
&amp;gt; () Initramfs source file(s)&lt;br /&gt;
[*] Enable loadable module support ---&amp;gt;&lt;br /&gt;
[*] Module unloadingEnable the block layer ---&amp;gt;&lt;br /&gt;
IO Schedulers ---&amp;gt;&lt;br /&gt;
&amp;lt; &amp;gt; Deadline I/O scheduler&lt;br /&gt;
&amp;lt; &amp;gt; CFQ I/O schedulerDefault I/O scheduler (No-op)&lt;br /&gt;
Device Drivers ---&amp;gt;&lt;br /&gt;
&amp;gt; Generic Driver Options ---&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; [*] Maintain a devtmpfs filesystem to mount at /dev&lt;br /&gt;
&amp;gt;&amp;gt; [*] Automount devtmpfs at /dev, after the kernel mounted the rootfs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cryptographic API ---&amp;gt;&lt;br /&gt;
&amp;gt; &amp;lt;*&amp;gt; XTS support&lt;br /&gt;
&amp;gt; -*- AES cipher algorithms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* All other drivers required to see your PATA/SATA drives must be compiled in.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue and compile/install your kernel:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##make bzImage&lt;br /&gt;
# ##i##make modules_install&lt;br /&gt;
# ##i##cp arch/x86_64/boot/bzImage /boot/bzImage-&amp;lt;Kernel-version&amp;gt;&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing the ZFS userspace tools ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -av zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check to make sure that the zfs tools are working, the zpool.cache file that you copied before should be displayed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If everything worked, continue.&lt;br /&gt;
&lt;br /&gt;
== Bliss Initramfs Creator ==&lt;br /&gt;
Make sure you compile sys-apps/busybox and sys-fs/cryptsetup with the static flag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##echo &amp;quot;sys-apps/busybox static&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/busybox&lt;br /&gt;
# ##i##echo &amp;quot;sys-fs/cryptsetup static&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/cryptsetup&lt;br /&gt;
# ##i##echo &amp;quot;sys-libs/e2fsprogs-libs static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/e2fsprogs-libs&lt;br /&gt;
# ##i##echo &amp;quot;dev-libs/popt static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/popt&lt;br /&gt;
# ##i##echo &amp;quot;sys-apps/util-linux static-libs&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use/util-linux&lt;br /&gt;
# ##i##emerge -avt sys-apps/busybox sys-fs/cryptsetup&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone my creator which is located at: git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##git clone git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
# ##i##cd Bliss-Initramfs-Creator&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then run the script as root, and place the initrd into /boot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##./createInit&lt;br /&gt;
Choose Option 2 ZFS+LUKS&lt;br /&gt;
# ##i##mv initrd-&amp;lt;kernel_name&amp;gt;.img /boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;kernel_name&amp;gt;''' is the name of what you selected in the initramfs creator, and the name of the outputted file.&lt;br /&gt;
&lt;br /&gt;
Once you do this just go to your bootloader config, and add it in there.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 kernel name is: bzImage-3.7.1-ALL&lt;br /&gt;
 initramfs name is: initrd-3.7.1-ALL.img&lt;br /&gt;
 pool root is: rpool/ROOT/funtoo&lt;br /&gt;
 encrypted root is: /dev/sda2&lt;br /&gt;
&lt;br /&gt;
== Installing Extlinux ==&lt;br /&gt;
To install extlinux first merge syslinux&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -avt syslinux&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
next prepare your /boot folder&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##install -d /boot/extlinux&lt;br /&gt;
# ##i##extlinux --install /boot/extlinux&lt;br /&gt;
# ##i##cd /boot&lt;br /&gt;
# ##i##ln -s . boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally install Extlinux for your Boot Record&lt;br /&gt;
&lt;br /&gt;
=== MBR ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/mbr.bin of=/dev/sda&lt;br /&gt;
# ##i##cp /usr/share/syslinux/menu.c32 /boot/extlinux/&lt;br /&gt;
# ##i##touch /boot/extlinux/extlinux.conf&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GPT ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##sgdisk /dev/sda --attributes=1:set:2&lt;br /&gt;
# ##i##sgdisk /dev/sda --attributes=1:show&lt;br /&gt;
1:2:1 (legacy BIOS bootable)&lt;br /&gt;
# ##i##dd bs=440 conv=notrunc count=1 if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&lt;br /&gt;
# ##i##cp /usr/share/syslinux/menu.c32 /boot/extlinux/&lt;br /&gt;
# ##i##touch /boot/extlinux/extlinux.conf&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Config Extlinux ===&lt;br /&gt;
Open '''/boot/extlinux/extlinux.conf''' with your favorite editor and add the following to it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
TIMEOUT 30&lt;br /&gt;
UI menu.c32&lt;br /&gt;
&lt;br /&gt;
MENU TITLE Funtoo Boot Menu&lt;br /&gt;
MENU COLOR title        1;37;40&lt;br /&gt;
MENU COLOR border       30;40&lt;br /&gt;
MENU COLOR unsel        37;40&lt;br /&gt;
&lt;br /&gt;
LABEL funtoo bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  MENU LABEL Funtoo Linux bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  KERNEL /bzImage-&amp;lt;Kernel-Version&amp;gt;&lt;br /&gt;
  INITRD /initrd-&amp;lt;Kernel-Version&amp;gt;.img&lt;br /&gt;
  APPEND enc_root=/dev/sda2 pool_root=rpool/ROOT/funtoo&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Final configuration ==&lt;br /&gt;
=== Add the zfs tools to openrc ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##rc-update add zfs boot&lt;br /&gt;
# ##i##rc-update add zfs-shutdown shutdown&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add filesystems to /etc/fstab ===&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##nano /etc/fstab&lt;br /&gt;
# &amp;lt;fs&amp;gt;                  &amp;lt;mountpoint&amp;gt;    &amp;lt;type&amp;gt;          &amp;lt;opts&amp;gt;          &amp;lt;dump/pass&amp;gt;&lt;br /&gt;
/dev/sda1               /boot           ext4            defaults        1 2&lt;br /&gt;
/dev/zvol/rpool/swap    none            swap            sw              0 0&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Clean up and reboot ===&lt;br /&gt;
We are almost done, we are just going to clean up and unmount whatever we mounted and get out.&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Delete the stage3/portage tarballs you downloaded earlier so they don't take up space.&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##rm stage3-latest.tar.xz&lt;br /&gt;
# ##i##rm /usr/portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
Set your root password&lt;br /&gt;
# ##i##passwd&lt;br /&gt;
&amp;gt;&amp;gt; Enter your password, you won't see what you are writing (for security reasons), but it is there!&lt;br /&gt;
&lt;br /&gt;
Get out of the chroot environment&lt;br /&gt;
# ##i##exit&lt;br /&gt;
&lt;br /&gt;
Unmount all the kernel filesystem stuff and boot&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
# ##i##umount proc dev sys boot&lt;br /&gt;
&lt;br /&gt;
Turn off the swap&lt;br /&gt;
# ##i##swapoff /dev/zvol/rpool/swap&lt;br /&gt;
&lt;br /&gt;
Export the zpool&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##zpool export -f rpool&lt;br /&gt;
&lt;br /&gt;
Reboot&lt;br /&gt;
# ##i##reboot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and that should be enough to get your system to boot on ZFS.&lt;br /&gt;
&lt;br /&gt;
== Extra: After reboot ==&lt;br /&gt;
After you restart your machine and your inside your desktop, continue to set up anything you need in terms of /etc configurations. Once you have everything the way you like it, take a snapshot of your system. You will be using this snapshot to revert back to this state if anything ever happens to your system down the road. The snapshots are cheap, and almost instant. To take the snapshot of your rootfs, type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs snapshot rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To see if your snapshot was taken, type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs list -t snapshot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your machine ever fails and you need to get back to this state, just type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs rollback rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enjoy your new install on ZFS :)&lt;br /&gt;
&lt;br /&gt;
== Getting back into your ZFS pool in case of emergency ==&lt;br /&gt;
If you ever need to get back into your ZFS pool in case of an emergency (missing rebuild of modules, unable to boot, etc) reboot your box with the System Rescue USB you created earlier, then issue the following commands:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##depmod&lt;br /&gt;
# ##i##cryptsetup luksOpen /dev/sda2 enc-root&lt;br /&gt;
# ##i##zpool import -f -o cachefile= -R /mnt/funtoo rpool&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you should be able to mount the system like we did earlier in this Guide [[ZFS_rootfs_over_encrypted_container#Installing_Funtoo|(chroot instructions)]], fix your problem and enjoy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Filesystems]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/ZFS_Install_Guide</id>
		<title>ZFS Install Guide</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/ZFS_Install_Guide"/>
				<updated>2013-01-11T23:54:29Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial will show you how to install Funtoo on ZFS (rootfs).&lt;br /&gt;
&lt;br /&gt;
This tutorial is meant to be an &amp;quot;overlay&amp;quot; over the [[Funtoo_Linux_Installation|Regular Funtoo Installation]]. Follow the normal installation and only use this guide for steps 2, 3, and 8.&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|'''Since ZFS was really designed for 64 bit systems, we are only recommending and supporting 64 bit platforms and installations. We will not be supporting 32 bit platforms'''!}}&lt;br /&gt;
&lt;br /&gt;
== Setting up your environment ==&lt;br /&gt;
In order for us to install Funtoo on ZFS, you will need an environment that provides the ZFS tools. We will be downloading two things: System Rescue CD, &amp;lt;br /&amp;gt;&lt;br /&gt;
and the ZFS System Rescue Module (SRM). This is just a file that when combined with System Rescue CD, gives you those tools.&lt;br /&gt;
&lt;br /&gt;
[https://sourceforge.net/projects/systemrescuecd/files/sysresccd-x86/3.2.0/systemrescuecd-x86-3.2.0.iso/download Download System Rescue CD 3.2.0]&lt;br /&gt;
&lt;br /&gt;
[http://jonathanvasquez.com/files/sysresccd/ Download the ZFS System Rescue Module]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Name: SystemRescueCd-x86-3.2.0 (353 MiB)&lt;br /&gt;
Release Date: 2013-01-07&lt;br /&gt;
&lt;br /&gt;
md5sum 90528f0c4b861363992fd9cbcc52d00a&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Creating_System_Rescue_CD_Modules|Follow the instructions here to download and place the srm into your flash drive]]. &lt;br /&gt;
&lt;br /&gt;
We will now start to partition the system. Open up a terminal, and type in the following (We will assume it's a fresh drive for simplicity).&lt;br /&gt;
&lt;br /&gt;
== Creating partitions ==&lt;br /&gt;
&lt;br /&gt;
We will be creating two partitions, /boot, and the remaining disk space will be for ZFS.&lt;br /&gt;
&lt;br /&gt;
(All commands will be ran as root).&lt;br /&gt;
&lt;br /&gt;
=== fdisk (MBR Style) ===&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (ZFS):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition type: ##i##↵&lt;br /&gt;
Partition number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
&lt;br /&gt;
Command: ##i##t ↵&lt;br /&gt;
Partition number: ##i##2 ↵&lt;br /&gt;
Hex code (type L to list codes): ##i##bf ↵&lt;br /&gt;
&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
&lt;br /&gt;
Disk /dev/sda: 1000.2 GB, 1000204886016 bytes&lt;br /&gt;
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors&lt;br /&gt;
Units = sectors of 1 * 512 = 512 bytes&lt;br /&gt;
Sector size (logical/physical): 512 bytes / 512 bytes&lt;br /&gt;
I/O size (minimum/optimal): 512 bytes / 512 bytes&lt;br /&gt;
Disk identifier: 0x3e954df7&lt;br /&gt;
&lt;br /&gt;
   Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;
/dev/sda1            2048      514047      256000   83  Linux&lt;br /&gt;
/dev/sda2          514048  1953525167   976505560   bf  Solaris&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== gdisk (GPT Style) ===&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 1''' (boot):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+250M ↵&lt;br /&gt;
Hex Code: ##i##↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (BIOS Boot Partition):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##+32M ↵&lt;br /&gt;
Hex Code: ##i##EF02 ↵&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|Only make the above BIOS Boot Partition if you are using GRUB 2 on GPT. If you are using the extlinux bootloader, this partition is not necessary. The below instructions continue as if you did not create this partition and assumes you are using extlinux as the bootloader.}}&lt;br /&gt;
&lt;br /&gt;
'''Create Partition 2''' (ZFS):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Command: ##i##n ↵&lt;br /&gt;
Partition Number: ##i##↵&lt;br /&gt;
First sector: ##i##↵&lt;br /&gt;
Last sector: ##i##↵&lt;br /&gt;
Hex Code: ##i##bf01 ↵&lt;br /&gt;
&lt;br /&gt;
Command: ##i##p ↵&lt;br /&gt;
Disk /dev/sda: 1953525168 sectors, 931.5 GiB&lt;br /&gt;
Logical sector size: 512 bytes&lt;br /&gt;
Disk identifier (GUID): C0C1E56A-B24F-492F-95DB-2E227676F228&lt;br /&gt;
Partition table holds up to 128 entries&lt;br /&gt;
First usable sector is 34, last usable sector is 1953525134&lt;br /&gt;
Partitions will be aligned on 2048-sector boundaries&lt;br /&gt;
Total free space is 2014 sectors (1007.0 KiB)&lt;br /&gt;
&lt;br /&gt;
Number  Start (sector)    End (sector)  Size       Code  Name&lt;br /&gt;
   1            2048          514047   250.0 MiB   8300  Linux filesystem&lt;br /&gt;
   2          514048      1953525134   931.3 GiB   BF01  Solaris /usr &amp;amp; Mac ZFS&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Format your boot volume ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkfs.ext4 /dev/sda1&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create the zpool ===&lt;br /&gt;
We will first create the pool. The pool will be named `rpool` and the disk will be aligned to 4096 (using ashift=12)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool create -f -o ashift=12 -o cachefile= -O compression=on -m none -R /mnt/funtoo rpool /dev/sda2&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|If you followed the GPT partitioning instructions, you should change /dev/sda2 to /dev/sda3.}}&lt;br /&gt;
&lt;br /&gt;
{{fancynote|If you have a previous pool that you would like to import, you can do a: '''zpool import -R /mnt/funtoo &amp;lt;pool_name&amp;gt;'''}}&lt;br /&gt;
&lt;br /&gt;
=== Create the zfs datasets ===&lt;br /&gt;
We will now create some datasets. For this installation, we will create a small but future proof amount of datasets. We will have a dataset for the OS (/), and your swap. We will also show you how to create some optional datasets: /home, /var, /usr/src, and /usr/portage.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Create some empty containers for organization purposes, and make the dataset that will hold /&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/ROOT&lt;br /&gt;
# ##i##zfs create -o mountpoint=/ rpool/ROOT/funtoo&lt;br /&gt;
&lt;br /&gt;
Optional, but recommended datasets: /home, /root &lt;br /&gt;
# ##i##zfs create -o mountpoint=/home rpool/HOME&lt;br /&gt;
# ##i##zfs create -o mountpoint=/root rpool/HOME/root&lt;br /&gt;
&lt;br /&gt;
Optional datasets: /usr/src, /var&lt;br /&gt;
# ##i##zfs create -o mountpoint=none rpool/FUNTOO&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/src rpool/FUNTOO/src&lt;br /&gt;
# ##i##zfs create -o mountpoint=/var rpool/FUNTOO/var&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating a separate portage dataset (optional) ====&lt;br /&gt;
&lt;br /&gt;
Creating a separate portage dataset could be useful if you would like to keep your portage tree, distfiles (source code files), and packages (your compiled binaries if you have FEATURES=&amp;quot;buildpkg&amp;quot; enabled) in a safe place (or if you want to back up this directory up easily).&lt;br /&gt;
&lt;br /&gt;
This requires a few extra steps because we can't just do a regular emerge --sync when we initially chroot. We will need to download a portage snapshot tarball and extract it into the directory.&lt;br /&gt;
&lt;br /&gt;
The required steps for getting and extracting the snapshot will be shown later on in the guide once you chroot into the environment. For now just create the datasets:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage -o compression=off rpool/FUNTOO/portage&lt;br /&gt;
# ##i##zfs create -o mountpoint=/usr/portage/distfiles -o compression=off rpool/FUNTOO/distfiles&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create your swap zvol ===&lt;br /&gt;
&lt;br /&gt;
'''Make your swap +1G greater than your RAM. An 8G machine would have 9G of RAM (This is kinda big though).'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -V 9G rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Format your swap zvol ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkswap -f /dev/zvol/rpool/swap&lt;br /&gt;
# ##i##swapon /dev/zvol/rpool/swap&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alright that finishes the creation of the zpool and zfs datasets. &lt;br /&gt;
&lt;br /&gt;
Check to make sure everything appears fine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Copy the zpool.cache file to your new environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##mkdir -p /mnt/funtoo/etc/zfs&lt;br /&gt;
# ##i##cp /etc/zfs/zpool.cache /mnt/funtoo/etc/zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make an empty mtab file&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##touch /mnt/funtoo/etc/mtab&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we will continue to install funtoo.&lt;br /&gt;
&lt;br /&gt;
== Installing Funtoo ==&lt;br /&gt;
&lt;br /&gt;
[[Funtoo_Linux_Installation|Download and install the Funtoo stage3 and continue installation as normal.]]&lt;br /&gt;
&lt;br /&gt;
Then chroot into your new funtoo environment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
&lt;br /&gt;
Mount your boot drive&lt;br /&gt;
# ##i##mount /dev/sda1 /mnt/funtoo/boot&lt;br /&gt;
&lt;br /&gt;
Bind the kernel related directories&lt;br /&gt;
# ##i##mount --bind /proc ./proc&lt;br /&gt;
# ##i##mount --bind /dev ./dev&lt;br /&gt;
# ##i##mount --bind /sys ./sys&lt;br /&gt;
&lt;br /&gt;
Copy network settings&lt;br /&gt;
# ##i##cp /etc/resolv.conf etc/&lt;br /&gt;
&lt;br /&gt;
chroot into your new funtoo environment&lt;br /&gt;
# ##i##env -i HOME=/root TERM=$TERM chroot . bash -l&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Syncing your portage tree ===&lt;br /&gt;
&lt;br /&gt;
==== If you didn't create a separate portage dataset, then just sync your portage tree as normal. ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== If you did create a separate portage dataset, let's now get the portage snapshot set up. ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Change into your /usr directory&lt;br /&gt;
# ##i##cd /usr&lt;br /&gt;
&lt;br /&gt;
Download and extract the portage snapshot&lt;br /&gt;
# ##i##wget http://ftp.osuosl.org/pub/funtoo/funtoo-current/snapshots/portage-latest.tar.xz&lt;br /&gt;
# ##i##tar xf portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
Change into your portage directory and checkout the funtoo branch&lt;br /&gt;
# ##i##cd portage&lt;br /&gt;
# ##i##git checkout funtoo.org&lt;br /&gt;
&lt;br /&gt;
Now sync your portage tree&lt;br /&gt;
# ##i##emerge --sync&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kernel Configuration ==&lt;br /&gt;
&lt;br /&gt;
Tested with kernel 2.6.32, 3.2.34, 3.6.9, 3.7.1.&lt;br /&gt;
&lt;br /&gt;
When you get up to the kernel, make sure that you disable the CFQ scheduler, and turn&lt;br /&gt;
on No-op (It's the default one once you disable all schedulers). The reason for this is because ZFS has its&lt;br /&gt;
own scheduler and the CFQ one conflicts with it.&lt;br /&gt;
&lt;br /&gt;
Go to your kernel config, and make sure you have the following: (there should be a /usr/src/linux symlink as well)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;ZLIB_INFLATE/DEFLATE must be compiled into the kernel (not as a module).&lt;br /&gt;
&amp;gt; ZLIB_INFLATE [=y], ZLIB_DEFLATE [=y]&lt;br /&gt;
&lt;br /&gt;
General setup ---&amp;gt;&lt;br /&gt;
&amp;gt; [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support&lt;br /&gt;
&amp;gt; () Initramfs source file(s)&lt;br /&gt;
&lt;br /&gt;
[*] Enable loadable module support ---&amp;gt;&lt;br /&gt;
[*] Module unloading&lt;br /&gt;
&lt;br /&gt;
Enable the block layer ---&amp;gt;&lt;br /&gt;
IO Schedulers ---&amp;gt;&lt;br /&gt;
&amp;lt; &amp;gt; Deadline I/O scheduler&lt;br /&gt;
&amp;lt; &amp;gt; CFQ I/O scheduler&lt;br /&gt;
Default I/O scheduler (No-op)&lt;br /&gt;
&lt;br /&gt;
Device Drivers ---&amp;gt;&lt;br /&gt;
&amp;gt; Generic Driver Options ---&amp;gt;&lt;br /&gt;
&amp;gt;&amp;gt; [*] Maintain a devtmpfs filesystem to mount at /dev&lt;br /&gt;
&amp;gt;&amp;gt; [*] Automount devtmpfs at /dev, after the kernel mounted the rootfs&lt;br /&gt;
&lt;br /&gt;
* All other drivers required to see your PATA/SATA drives must be compiled in.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Continue and compile/install your kernel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##make bzImage modules&lt;br /&gt;
# ##i##make install&lt;br /&gt;
# ##i##make modules_install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing the ZFS userspace tools ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -av zfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check to make sure that the zfs tools are working, the zpool.cache file that you copied before should be displayed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zpool status&lt;br /&gt;
# ##i##zfs list&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If everything worked, continue.&lt;br /&gt;
&lt;br /&gt;
== Create the initramfs ==&lt;br /&gt;
&lt;br /&gt;
There are two ways to do this, you can use genkernel, or you can use my bliss initramfs creator. I will&lt;br /&gt;
show you both.&lt;br /&gt;
&lt;br /&gt;
=== Bliss Initramfs Creator ===&lt;br /&gt;
&lt;br /&gt;
Make sure you compile sys-apps/busybox with the static flag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##echo &amp;quot;sys-apps/busybox static&amp;quot; &amp;gt;&amp;gt; /etc/portage/package.use&lt;br /&gt;
# ##i##emerge -av sys-apps/busybox&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clone my creator which is located at: git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##git clone git://github.com/fearedbliss/Bliss-Initramfs-Creator.git&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then go into this new directory, run the script as root, and place it into /boot&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##cd Bliss-Initramfs-Creator&lt;br /&gt;
# ##i##./createInit&lt;br /&gt;
# ##i##mv initrd-&amp;lt;kernel_name&amp;gt;.img /boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;kernel_name&amp;gt;''' is the name of what you selected in the initramfs creator, and the name of the outputted file.&lt;br /&gt;
&lt;br /&gt;
Once you do this just go to your bootloader config, and add it in there.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
Kernel name is: vmlinuz-3.7.1-ALL&lt;br /&gt;
initramfs name is: initrd-3.7.1-ALL.img&lt;br /&gt;
Pool root is: rpool/ROOT/funtoo&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
extlinux.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
LABEL funtoo&lt;br /&gt;
  MENU LABEL Funtoo 3.7.1-ALL&lt;br /&gt;
  KERNEL /boot/vmlinuz-3.7.1-ALL&lt;br /&gt;
  INITRD /boot/initrd-3.7.1-ALL.img&lt;br /&gt;
  APPEND pool_root=rpool/ROOT/funtoo&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== genkernel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##emerge -av sys-kernel/genkernel&lt;br /&gt;
# ##i##genkernel --zfs initramfs&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
kernel name is: vmlinuz-3.7.1-ALL&lt;br /&gt;
initramfs name is: initramfs-genkernel-x86_64-3.7.1-ALL&lt;br /&gt;
pool name is: rpool&lt;br /&gt;
&lt;br /&gt;
extlinux.conf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
LABEL funtoo&lt;br /&gt;
  MENU LABEL Funtoo 3.7.1-ALL&lt;br /&gt;
  KERNEL /boot/vmlinuz-3.7.1-ALL&lt;br /&gt;
  INITRD /boot/initramfs-genkernel-x86_64-3.7.1-ALL&lt;br /&gt;
  APPEND real_root=ZFS=rpool/ROOT/funtoo dozfs=force&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Final configuration ==&lt;br /&gt;
&lt;br /&gt;
=== Add the zfs tools to openrc ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##rc-update add zfs boot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add filesystems to /etc/fstab ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##nano /etc/fstab&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;fs&amp;gt;                  &amp;lt;mountpoint&amp;gt;    &amp;lt;type&amp;gt;          &amp;lt;opts&amp;gt;          &amp;lt;dump/pass&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/dev/sda1               /boot           ext4            defaults        1 2&lt;br /&gt;
/dev/zvol/rpool/swap    none            swap            sw              0 0&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Clean up and reboot ===&lt;br /&gt;
We are almost done, we are just going to clean up, '''set our root password''', and unmount whatever we mounted and get out.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Delete the stage3/portage tarballs you downloaded earlier so they don't take up space.&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##rm stage3-latest.tar.xz&lt;br /&gt;
# ##i##rm /usr/portage-latest.tar.xz&lt;br /&gt;
&lt;br /&gt;
Set your root password&lt;br /&gt;
# ##i##passwd&lt;br /&gt;
&amp;gt;&amp;gt; Enter your password, you won't see what you are writing (for security reasons), but it is there!&lt;br /&gt;
&lt;br /&gt;
Get out of the chroot environment&lt;br /&gt;
# ##i##exit&lt;br /&gt;
&lt;br /&gt;
Unmount all the kernel filesystem stuff and boot&lt;br /&gt;
# ##i##cd /mnt/funtoo&lt;br /&gt;
# ##i##umount proc dev sys boot&lt;br /&gt;
&lt;br /&gt;
Turn off the swap&lt;br /&gt;
# ##i##swapoff /dev/zvol/rpool/swap&lt;br /&gt;
&lt;br /&gt;
Export the zpool&lt;br /&gt;
# ##i##cd /&lt;br /&gt;
# ##i##zpool export -f rpool&lt;br /&gt;
&lt;br /&gt;
Reboot&lt;br /&gt;
# ##i##reboot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{fancyimportant|'''Don't forget to set your root password as stated above before exiting chroot and rebooting. If you don't set the root password, you won't be able to log into your new system.'''}}&lt;br /&gt;
and that should be enough to get your system to boot on ZFS.&lt;br /&gt;
&lt;br /&gt;
== Extra: After reboot ==&lt;br /&gt;
&lt;br /&gt;
After you restart your machine and your inside your desktop, continue to set up anything you need in terms of /etc configurations. Once you have everything the way you like it, take a snapshot of your system. You will be using this snapshot to revert back to this state if anything ever happens to your system down the road. The snapshots are cheap, and almost instant. To take the snapshot of your rootfs, type the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs snapshot rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To see if your snapshot was taken, type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs list -t snapshot&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your machine ever fails and you need to get back to this state, just type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs rollback rpool/ROOT/funtoo@install&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Recovery Environment ===&lt;br /&gt;
On ZFS it is extremely easy to create a recovery environment using an already working snapshot. So that's what we will be doing. &lt;br /&gt;
&lt;br /&gt;
Create a clone of the @install snapshot which you will use for recovery purposes. If something happens to your main install, you can boot into this clone and fix the main one. One of the differences (maybe the only difference) between a clone and a snapshot is that a clone is rewritable while a snapshot is only read-only.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
# ##i##zfs clone rpool/ROOT/funtoo@install rpool/ROOT/recovery&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Add the clone to your extlinux.conf ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
LABEL funtoo-recovery&lt;br /&gt;
    MENU LABEL Funtoo Recovery&lt;br /&gt;
    KERNEL /boot/vmlinuz-3.7.1-ALL&lt;br /&gt;
    INITRD /boot/initrd-3.7.1-ALL.img&lt;br /&gt;
    APPEND pool_root=rpool/ROOT/recovery&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Things to watch out for ====&lt;br /&gt;
&lt;br /&gt;
Since your recovery clone will tend to get old as you use your main system, and since &lt;br /&gt;
your recovery and other stuff are on the same pool, we don't want the new pool stuff&lt;br /&gt;
to be mounted when we launch recovery. We also don't want video drivers to be&lt;br /&gt;
conflicting.&lt;br /&gt;
&lt;br /&gt;
1. Make sure that nvidia/nouveau stuff are blacklisted.&lt;br /&gt;
2. Make sure that your /boot and /lib/modules for the kernel in your 'recovery' are&lt;br /&gt;
matching.&lt;br /&gt;
3. Disable the zfs openrc script so that nothing else gets automatically mounted.&lt;br /&gt;
Only your rootfs.&lt;br /&gt;
&lt;br /&gt;
You can do the above stuff by mounting your copy and chrooting into it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;console&amp;gt;&lt;br /&gt;
Mount the recovery clone&lt;br /&gt;
# ##i##mkdir /mnt/recovery&lt;br /&gt;
# ##i##mount -t zfs -o zfsutil rpool/ROOT/recovery /mnt/recovery&lt;br /&gt;
# ##i##cd /mnt/recovery&lt;br /&gt;
&lt;br /&gt;
Mount the kernel devices&lt;br /&gt;
# ##i##mount --bind /proc ./proc&lt;br /&gt;
# ##i##mount --bind /dev ./dev&lt;br /&gt;
# ##i##mount --bind /sys ./sys&lt;br /&gt;
&lt;br /&gt;
Copy zpool.cache&lt;br /&gt;
# ##i##cp /etc/zfs/zpool.cache etc/zfs&lt;br /&gt;
&lt;br /&gt;
Chroot into the new environment&lt;br /&gt;
# ##i##env -i HOME=/root TERM=$TERM chroot . bash --login&lt;br /&gt;
&lt;br /&gt;
Disable zfs/zfs-shutdown openrc scripts&lt;br /&gt;
# ##i##rc-config delete zfs boot&lt;br /&gt;
&lt;br /&gt;
Blacklist nouveau/nvidia drivers&lt;br /&gt;
# ##i##echo &amp;quot;blacklist nouveau&amp;quot; &amp;gt;&amp;gt; /etc/modprobe.d/blacklist.conf&lt;br /&gt;
# ##i##echo &amp;quot;blacklist nvidia&amp;quot; &amp;gt;&amp;gt; /etc/modprobe.d/blacklist.conf&lt;br /&gt;
&amp;lt;/console&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Getting into the recovery ====&lt;br /&gt;
Just start your machine and pick the '''Funtoo Recovery''' option from the Boot Menu.&lt;br /&gt;
&lt;br /&gt;
Enjoy your new install on ZFS :)&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Filesystems]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Emacs</id>
		<title>Emacs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Emacs"/>
				<updated>2013-01-11T23:48:58Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Undo revision 8585 by Golodhrim (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:emacs-logo.png]]&lt;br /&gt;
&lt;br /&gt;
Emacs is a famous text editor, famous by its flexibility and extensibility.  One manual describes it as &amp;quot;the extensible, customizable, self-documenting, real-time display editor&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This page is designed to give users a good place to share their config and settings for a nice emacs setup.&lt;br /&gt;
&lt;br /&gt;
== installing emacs ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
emerge -avt emacs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for the standard gnu emacs and&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
emerge -avt xemacs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
for the 1980 created fork of emacs, both should handle the same, while emacs on its own stands here for both. If you install additional extensions for both you might need to add &amp;lt;tt&amp;gt;app-emacs&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;app-xemacs&amp;lt;/tt&amp;gt; to the package as there are two different versions for both.&lt;br /&gt;
&lt;br /&gt;
== What emacs is and what it is not ==&lt;br /&gt;
&lt;br /&gt;
(X)Emacs is primarily a text editor and not a word processor, it concentrates on manipulating any kind of text, rather than manipulating the font and look. It is client and GUI based, so can be used on local box in graphical environments with a GUI and remote on a server in a client mode. (X)Emacs provides commands for manipulate every kind of text and syntax highlighting.&lt;br /&gt;
&lt;br /&gt;
=== Customizability ===&lt;br /&gt;
&lt;br /&gt;
(X)Emacs is highly customizable in many ways through:&lt;br /&gt;
&lt;br /&gt;
* the &amp;lt;tt&amp;gt;customize&amp;lt;/tt&amp;gt; extension, which allows settings of customized variables, such as color themes, graphical interface, etc. This part is intended for emacs beginners, who do not want to work with Emacs lisp code.&lt;br /&gt;
* combine keystrokes to execute complex makros.&lt;br /&gt;
* using Emacs Lisp. Designed for the emacs professional.&lt;br /&gt;
&lt;br /&gt;
=== Extensibility ===&lt;br /&gt;
&lt;br /&gt;
As a result of the above points, (X)Emacs behaviour can be easily definied to all text behavings without limit. Like some of the examples below show you:&lt;br /&gt;
&lt;br /&gt;
* AUCTeX, A suite for LaTeX and other TeX versions,&lt;br /&gt;
* ERC, A Emacs IRC client,&lt;br /&gt;
* ORG-mode, A Emacs PIM and Orga tool&lt;br /&gt;
* Wanderlust, A highly flexible Mail tool for Emacs&lt;br /&gt;
&lt;br /&gt;
== User Configs ==&lt;br /&gt;
=== golodhrim's config ===&lt;br /&gt;
==== .emacs ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; General Settings ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
&lt;br /&gt;
(setq emacs-root-dir (concat (getenv &amp;quot;HOME&amp;quot;) &amp;quot;/em/&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
(setq inhibit-startup-message t)    ;; Suppress the startup message&lt;br /&gt;
(setq standard-indent 4)            ;; Default indent level is 3 chars&lt;br /&gt;
(setq-default indent-tabs-mode nil) ;; Indent with spaces, not tabs&lt;br /&gt;
&lt;br /&gt;
(setq make-backup-files nil)          ;; Enable backup files.&lt;br /&gt;
(setq version-control nil)            ;; Enable versioning with default values&lt;br /&gt;
(setq backup-directory-alist (quote ((&amp;quot;.*&amp;quot; . &amp;quot;~/.emacs_backups/&amp;quot;))))  ;; Save all backup file in this directory.&lt;br /&gt;
&lt;br /&gt;
(line-number-mode 1)                ;; Show line-number in the mode line&lt;br /&gt;
(column-number-mode 1)              ;; Show column-number in the mode line&lt;br /&gt;
&lt;br /&gt;
(setq auto-fill-mode 1)             ;; Line wrap&lt;br /&gt;
&lt;br /&gt;
(set-default-font &amp;quot;Inconsolata-12&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
(setq browse-url-browser-function 'browse-url-generic&lt;br /&gt;
      browse-url-generic-program &amp;quot;google-chrome&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
(global-set-key (kbd &amp;quot;C-&amp;lt;prior&amp;gt;&amp;quot;) 'previous-buffer)&lt;br /&gt;
(global-set-key (kbd &amp;quot;C-&amp;lt;next&amp;gt;&amp;quot; ) 'next-buffer    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(setq load-path (cons &amp;quot;~/.emacs.d/plugins&amp;quot; load-path))&lt;br /&gt;
&lt;br /&gt;
(setq global-font-lock-mode 1)&lt;br /&gt;
&lt;br /&gt;
(show-paren-mode 1)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; el-get setup ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;&lt;br /&gt;
(add-to-list 'load-path &amp;quot;~/.emacs.d/el-get/el-get&amp;quot;) &lt;br /&gt;
(unless (require 'el-get nil t) &lt;br /&gt;
  (with-current-buffer &lt;br /&gt;
    (url-retrieve-synchronously &amp;quot;https://raw.github.com/golodhrim/el-get/master/el-get-install.el&amp;quot;) &lt;br /&gt;
  (end-of-buffer) &lt;br /&gt;
  (eval-print-last-sexp)))&lt;br /&gt;
&lt;br /&gt;
(el-get 'sync)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;&lt;br /&gt;
;; mediawiki ;;&lt;br /&gt;
;;;;;;;;;;;;;;;&lt;br /&gt;
(require 'mediawiki)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Org-mode stuff ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
&lt;br /&gt;
;; Tell emacs where org-mode is&lt;br /&gt;
;;(setq load-path (cons &amp;quot;/usr/share/emacs/site-lisp/org-mode/&amp;quot; load-path))&lt;br /&gt;
;;(setq load-path (cons &amp;quot;/usr/share/emacs/site-lisp/org-mode/contrib/&amp;quot; load-path))&lt;br /&gt;
(require 'org-install) ;; Tell emacs to use org-mode&lt;br /&gt;
(add-to-list 'auto-mode-alist '(&amp;quot;\\.org$&amp;quot; . org-mode)) ;; Turn on org-mode for all *.org files&lt;br /&gt;
&lt;br /&gt;
;; Some key sequences&lt;br /&gt;
(define-key global-map &amp;quot;\C-cl&amp;quot; 'org-store-link) &lt;br /&gt;
(define-key global-map &amp;quot;\C-ca&amp;quot; 'org-agenda)&lt;br /&gt;
(global-set-key [f9]    'org-archive-subtree-default)&lt;br /&gt;
&lt;br /&gt;
(setq org-log-done t) ;; I have no idea what this does, it was in the manual -- think it controls whether or not to log time completed for tasks&lt;br /&gt;
&lt;br /&gt;
(setq org-directory &amp;quot;~/notes&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
;; Files that should be included in agenda views:&lt;br /&gt;
(setq org-agenda-files (list &amp;quot;~/notes/business.org&amp;quot;&lt;br /&gt;
                             &amp;quot;~/notes/personal.org&amp;quot; &lt;br /&gt;
                             &amp;quot;~/notes/projects/&amp;quot;&lt;br /&gt;
			     &amp;quot;~/notes/projects/writing/&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
(setq org-todo-keywords '((type &amp;quot;TODO&amp;quot; &amp;quot;Postponed&amp;quot; &amp;quot;Upcoming&amp;quot; &amp;quot;Doing&amp;quot; &amp;quot;|&amp;quot; &amp;quot;DONE(#)&amp;quot;))) ;; TODO workflows&lt;br /&gt;
&lt;br /&gt;
(setq org-tag-alist '((&amp;quot;work&amp;quot; . ?k) (&amp;quot;personal&amp;quot; . ?p) (&amp;quot;organization&amp;quot; . ?o) (&amp;quot;writing&amp;quot; . ?w) (&amp;quot;code&amp;quot; . ?c) (&amp;quot;blog&amp;quot; . ?b) (&amp;quot;funtoo&amp;quot; . ?f) (&amp;quot;social&amp;quot; . ?s))) ;; Most-used tags, with shortcuts&lt;br /&gt;
&lt;br /&gt;
;; Capture stuff&lt;br /&gt;
(setq org-default-notes-file &amp;quot;~/.org/capture.org&amp;quot;)&lt;br /&gt;
(define-key global-map &amp;quot;\C-cc&amp;quot; 'org-capture)&lt;br /&gt;
(setq org-refile-targets '((org-agenda-files :level . 1)(org-agenda-files :level . 2)))&lt;br /&gt;
(setq org-refile-use-outline-path 'file)&lt;br /&gt;
&lt;br /&gt;
(setq org-capture-templates&lt;br /&gt;
      '((&amp;quot;t&amp;quot; &amp;quot;Todo&amp;quot; entry (file+headline &amp;quot;~/.org/capture.org&amp;quot; &amp;quot;Tasks&amp;quot;)&lt;br /&gt;
             &amp;quot;- TODO %?\n  %i\n  %a&amp;quot;)&lt;br /&gt;
        (&amp;quot;j&amp;quot; &amp;quot;Journal&amp;quot; entry (file+datetree &amp;quot;~/.org/journal.org&amp;quot;)&lt;br /&gt;
             &amp;quot;- %?\nEntered on %U\n  %i\n  %a&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
(setq org-mobile-directory &amp;quot;~/Dropbox/MobileOrg&amp;quot;)&lt;br /&gt;
(setq org-mobile-use-encryption)&lt;br /&gt;
(setq org-mobile-use-encryption-password &amp;quot;PASSWORD&amp;quot;)&lt;br /&gt;
(setq org-mobile-inbox-for-pull &amp;quot;~/notes/mobileorg/inbox.org&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Markdown Mode ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
&lt;br /&gt;
(require 'markdown-mode)&lt;br /&gt;
(add-to-list 'auto-mode-alist '(&amp;quot;\\.markdown$&amp;quot; . markdown-mode))&lt;br /&gt;
(add-to-list 'auto-mode-alist '(&amp;quot;\\.md$&amp;quot; . markdown-mode))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Python IDE ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;&lt;br /&gt;
(c-add-style&lt;br /&gt;
   &amp;quot;python-new&amp;quot;&lt;br /&gt;
   '((indent-tabs-mode . nil)&lt;br /&gt;
     (fill-column      . 78)&lt;br /&gt;
     (c-basic-offset   . 4)&lt;br /&gt;
     (c-offsets-alist  . ((substatement-open . 0)&lt;br /&gt;
                          (inextern-lang     . 0)&lt;br /&gt;
                          (arglist-intro     . +)&lt;br /&gt;
                          (knr-argdecl-intro . +)))&lt;br /&gt;
     (c-hanging-braces-alist . ((brace-list-open)&lt;br /&gt;
                                (brace-list-intro)&lt;br /&gt;
                                (brace-list-close)&lt;br /&gt;
                                (brace-entry-open)&lt;br /&gt;
                                (substatement-open after)&lt;br /&gt;
                                (block-close . c-snug-do-while)))&lt;br /&gt;
     (c-block-comment-prefix . &amp;quot;* &amp;quot;))&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
;; This is a very crude hook that auto-selects the C style depending on&lt;br /&gt;
;; whether it finds a line starting with tab in the first 3000 characters&lt;br /&gt;
;; in the file&lt;br /&gt;
(defun c-select-style ()&lt;br /&gt;
   (save-excursion&lt;br /&gt;
     (if (re-search-forward &amp;quot;^\t&amp;quot; 3000 t)&lt;br /&gt;
         (c-set-style &amp;quot;python&amp;quot;)&lt;br /&gt;
       (c-set-style &amp;quot;python-new&amp;quot;))))&lt;br /&gt;
(add-hook 'c-mode-hook 'c-select-style)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;&lt;br /&gt;
;; Django ;;&lt;br /&gt;
;;;;;;;;;;;;&lt;br /&gt;
(yas/initialize)&lt;br /&gt;
(add-to-list 'load-path &amp;quot;~/.emacs.d/el-get/django-mode/&amp;quot;)&lt;br /&gt;
(require 'django-html-mode)&lt;br /&gt;
(require 'django-mode)&lt;br /&gt;
(yas/load-directory &amp;quot;~/.emacs.d/el-get/django-mode/snippets&amp;quot;)&lt;br /&gt;
(add-to-list 'auto-mode-alist '(&amp;quot;\\.djhtml$&amp;quot; . django-html-mode))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Document Engineering (AUCTeX + ConTeXt) ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
(load &amp;quot;auctex.el&amp;quot; nil t t)&lt;br /&gt;
(load &amp;quot;preview-latex.el&amp;quot; nil t t)&lt;br /&gt;
&lt;br /&gt;
(setq TeX-auto-save 1)&lt;br /&gt;
(setq TeX-parse-self 1)&lt;br /&gt;
(setq TeX-auto-untabify 1)&lt;br /&gt;
(setq TeX-display-help 1)&lt;br /&gt;
(setq TeX-save-query nil)&lt;br /&gt;
(setq TeX-clean-confirm nil)&lt;br /&gt;
(setq-default TeX-master nil)&lt;br /&gt;
&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (TeX-fold-mode 1)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (TeX-source-specials-mode 1)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (TeX-toggle-debug-bad-boxes)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (TeX-toggle-debug-warnings)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (outline-minor-mode)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (abbrev-mode t)))&lt;br /&gt;
(add-hook 'TeX-mode-hook (lambda () (auto-fill-mode 1)))&lt;br /&gt;
&lt;br /&gt;
(add-hook 'TeX-mode-hook 'LaTeX-math-mode)&lt;br /&gt;
&lt;br /&gt;
(autoload 'etexshow &amp;quot;etexshow&amp;quot; &amp;quot;Browser for ConTeXt commands.&amp;quot; t)&lt;br /&gt;
&lt;br /&gt;
(setq etexshow-xml-files-alist&lt;br /&gt;
   `((,(concat emacs-root-dir &amp;quot;libs/etexshow/cont-en.xml&amp;quot;) .&lt;br /&gt;
      ,(concat &amp;quot;/tmp/cont-en.cache&amp;quot;))))&lt;br /&gt;
&lt;br /&gt;
(setq etexshow-comment-file&lt;br /&gt;
   (concat emacs-root-dir &amp;quot;libs/etexshow/cont-en-comments.xml&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
(setq TeX-PDF-mode 1)&lt;br /&gt;
(setq revert-without-query '(&amp;quot;.+pdf$&amp;quot;))&lt;br /&gt;
(add-hook 'doc-view-mode-hook 'auto-revert-mode)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;&lt;br /&gt;
;; bbdb ;;&lt;br /&gt;
;;;;;;;;;;&lt;br /&gt;
(setq bbdb-file &amp;quot;~/.emacs.d/.bbdb&amp;quot;)&lt;br /&gt;
(require 'bbdb)&lt;br /&gt;
(bbdb-initialize)&lt;br /&gt;
(setq&lt;br /&gt;
 bbdb-offer-save 1                         ;; 1 means save-without-asking&lt;br /&gt;
 bbdb-use-pop-up t                         ;; allow popups for addresses&lt;br /&gt;
 bbdb-electric-p t                         ;; be disposable with SPC&lt;br /&gt;
 bbdb-popup-target-lines 1                 ;; very small&lt;br /&gt;
 bbdb-dwim-net-address-allow-redundancy t  ;; always use full name&lt;br /&gt;
 bbdb-quiet-about-name-mismatches 2        ;; show name-mismatches 2 secs&lt;br /&gt;
 bbdb-always-add-address t                 ;; add new addresses to existing...&lt;br /&gt;
                                           ;; ...contacts automatically&lt;br /&gt;
 bbdb-canonicalize-redundant-nets-p t      ;; x@foo.bar.cx =&amp;gt; x@bar.cx&lt;br /&gt;
 bbdb-completion-type nil                  ;; complete on anything&lt;br /&gt;
 bbdb-complete-name-allow-cycling t        ;; cycle through matches&lt;br /&gt;
                                           ;; this only works partially&lt;br /&gt;
 bbdb-message-caching-enabled t            ;; be fast&lt;br /&gt;
 bbdb-use-alternate-names t                ;; use AKA&lt;br /&gt;
 bbdb-elided-display t                     ;; single-line addresses&lt;br /&gt;
 ;; auto-create addresses from mail&lt;br /&gt;
 bbdb/mail-auto-create-p 'bbdb-ignore-some-messages-hook&lt;br /&gt;
 bbdb-ignore-some-messages-alist           ;; don't ask about fake addresses&lt;br /&gt;
 ;; NOTE: there can be only one entry per header (such as To, From)&lt;br /&gt;
 ;; http://flex.ee.uec.ac.jp/texi/bbdb/bbdb_11.html&lt;br /&gt;
 '(( &amp;quot;From&amp;quot; . &amp;quot;no.?reply\\|DAEMON\\|daemon\\|facebookmail\\|twitter&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Jabber Mode ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;&lt;br /&gt;
&lt;br /&gt;
(require 'jabber-autoloads)&lt;br /&gt;
(setq jabber-account-list '(&lt;br /&gt;
                            (&amp;quot;USER@jabber-server.tld&amp;quot;&lt;br /&gt;
                            (:password . &amp;quot;PASSWORD&amp;quot;)&lt;br /&gt;
                            )&lt;br /&gt;
                           )&lt;br /&gt;
)&lt;br /&gt;
(setq&lt;br /&gt;
    jabber-history-enabled t&lt;br /&gt;
    jabber-use-global-history nil&lt;br /&gt;
    jabber-backlog-number 40&lt;br /&gt;
    jabber-backlog-days 30&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(add-hook 'jabber-chat-mode-hook 'goto-address)&lt;br /&gt;
&lt;br /&gt;
(load &amp;quot;~/.emacs.d/plugins/autosmiley.el&amp;quot;)&lt;br /&gt;
(require 'autosmiley)&lt;br /&gt;
(add-hook 'jabber-chat-mode-hook 'autosmiley-mode)&lt;br /&gt;
&lt;br /&gt;
(defvar libnotify-program &amp;quot;/usr/bin/notify-send&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
(defun notify-send (title message)&lt;br /&gt;
  (start-process &amp;quot;notify&amp;quot; &amp;quot; notify&amp;quot;&lt;br /&gt;
                 libnotify-program &amp;quot;--expire-time=4000&amp;quot; title message))&lt;br /&gt;
&lt;br /&gt;
(defun libnotify-jabber-notify (from buf text proposed-alert)&lt;br /&gt;
  &amp;quot;(jabber.el hook) Notify of new Jabber chat messages via libnotify&amp;quot;&lt;br /&gt;
  (when (or jabber-message-alert-same-buffer&lt;br /&gt;
                        (not (memq (selected-window) (get-buffer-window-list buf))))&lt;br /&gt;
    (if (jabber-muc-sender-p from)&lt;br /&gt;
        (notify-send (format &amp;quot;(PM) %s&amp;quot;&lt;br /&gt;
                             (jabber-jid-displayname (jabber-jid-user from)))&lt;br /&gt;
                     (format &amp;quot;%s: %s&amp;quot; (jabber-jid-resource from) text)))&lt;br /&gt;
    (notify-send (format &amp;quot;%s&amp;quot; (jabber-jid-displayname from))&lt;br /&gt;
                 text)))&lt;br /&gt;
&lt;br /&gt;
(add-hook 'jabber-alert-message-hooks 'libnotify-jabber-notify)&lt;br /&gt;
&lt;br /&gt;
(defun jabber-visit-history (jid)&lt;br /&gt;
  &amp;quot;Visit jabber history with JID in a new buffer.&lt;br /&gt;
&lt;br /&gt;
Performs well only for small files. Expect to wait a few seconds&lt;br /&gt;
for large histories. Adapted from `jabber-chat-create-buffer'.&amp;quot;&lt;br /&gt;
  (interactive (list (jabber-read-jid-completing &amp;quot;JID: &amp;quot;)))&lt;br /&gt;
  (let ((buffer (generate-new-buffer (format &amp;quot;*-jabber-history-%s-*&amp;quot;&lt;br /&gt;
                                             (jabber-jid-displayname jid)))))&lt;br /&gt;
    (switch-to-buffer buffer)&lt;br /&gt;
    (make-local-variable 'jabber-chat-ewoc)&lt;br /&gt;
    (setq jabber-chat-ewoc (ewoc-create #'jabber-chat-pp))&lt;br /&gt;
    (mapc 'jabber-chat-insert-backlog-entry&lt;br /&gt;
          (nreverse (jabber-history-query nil nil t t &amp;quot;.&amp;quot;&lt;br /&gt;
                                          (jabber-history-filename jid))))&lt;br /&gt;
    (view-mode)))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;&lt;br /&gt;
;; EMMS ;;&lt;br /&gt;
;;;;;;;;;;&lt;br /&gt;
(require 'emms-setup)&lt;br /&gt;
(emms-devel)&lt;br /&gt;
(emms-default-players)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;&lt;br /&gt;
;; ERC ;;&lt;br /&gt;
;;;;;;;;;&lt;br /&gt;
(require 'erc)&lt;br /&gt;
(require 'erc-extension)&lt;br /&gt;
(require 'erc-services)&lt;br /&gt;
(require 'erc-tex)&lt;br /&gt;
(require 'tls)&lt;br /&gt;
(require 'erc-nicklist)&lt;br /&gt;
&lt;br /&gt;
(and&lt;br /&gt;
 (require 'erc-highlight-nicknames)&lt;br /&gt;
 (add-to-list 'erc-modules 'highlight-nicknames)&lt;br /&gt;
 (erc-update-modules))&lt;br /&gt;
&lt;br /&gt;
(erc-services-mode 1)&lt;br /&gt;
&lt;br /&gt;
(setq tls-program '(&amp;quot;openssl s_client -connect %h:%p -no_ssl2 -ign_eof&lt;br /&gt;
                            -CAfile /home/USER/.ssl/USER.pem &lt;br /&gt;
                            -cert /home/USER/.ssl/USER.pem&amp;quot;&lt;br /&gt;
                    &amp;quot;gnutls-cli --priority secure256&lt;br /&gt;
                                --x509cafile /home/USER/.ssl/USER.pem &lt;br /&gt;
                                --x509certfile /home/USER/.ssl/USER.pem -p %p %h&amp;quot;&lt;br /&gt;
                    &amp;quot;gnutls-cli --priority secure256 -p %p %h&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
(autoload 'erc-nick-notify-mode &amp;quot;erc-nick-notify&amp;quot; &amp;quot;Minor mode that calls `erc-nick-notify-cmd' when his nick gets mentioned in an erc channel&amp;quot; t)&lt;br /&gt;
(eval-after-load 'erc '(erc-nick-notify-mode t))&lt;br /&gt;
(defun irc-erc ()&lt;br /&gt;
  &amp;quot;Fire up IRC.&amp;quot;&lt;br /&gt;
  (interactive)&lt;br /&gt;
  (erc-tls :server &amp;quot;chat.freenode.net&amp;quot; :port 7000 :nick &amp;quot;USER&amp;quot; :full-name &amp;quot;FULL NAME&amp;quot; :password &amp;quot;PASSWORD&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
(setq erc-autojoin-channels-alist '((&amp;quot;freenode.net&amp;quot; &amp;quot;#frogandowl&amp;quot; &amp;quot;#funtoo&amp;quot; &amp;quot;#funtoo-quebec&amp;quot; &amp;quot;#syntazia&amp;quot; &amp;quot;#context&amp;quot; &amp;quot;#nginx&amp;quot; &amp;quot;#emacs&amp;quot; &amp;quot;#openvswitch&amp;quot;)))&lt;br /&gt;
(setq erc-log-channels-directory &amp;quot;~/.erc/logs/&amp;quot;)&lt;br /&gt;
(setq erc-log-insert-log-on-open nil)&lt;br /&gt;
(setq erc-save-buffer-on-part nil&lt;br /&gt;
      erc-save-buffer-queries-on-quit nil&lt;br /&gt;
      erc-log-write-after-send t&lt;br /&gt;
      erc-log-write-after-insert t)&lt;br /&gt;
&lt;br /&gt;
(require 'smiley)&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\(:-?]\\)\\W&amp;quot; 1 &amp;quot;forced&amp;quot;))&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\s-\\(:-?/\\)\\W&amp;quot; 1 &amp;quot;wry&amp;quot;))&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\(:-?(\\)\\W&amp;quot; 1 &amp;quot;sad&amp;quot;))&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\((-?:\\)\\W&amp;quot; 1 &amp;quot;reverse-smile&amp;quot;))&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\(:-?D\\)\\W&amp;quot; 1 &amp;quot;grin&amp;quot;))&lt;br /&gt;
    (add-to-list 'smiley-regexp-alist '(&amp;quot;\\(:-?P\\)\\W&amp;quot; 1 &amp;quot;poke&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
;; (setq smiley-cached-regexp-alist nil)&lt;br /&gt;
;; (smiley-update-cache)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Wanderlust ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;&lt;br /&gt;
(autoload 'wl &amp;quot;wl&amp;quot; &amp;quot;Wanderlust&amp;quot; t)&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;&lt;br /&gt;
;; mailcrypt ;;&lt;br /&gt;
;;;;;;;;;;;;;;;&lt;br /&gt;
(require 'mailcrypt)&lt;br /&gt;
(add-hook 'wl-summary-mode-hook 'mc-install-read-mode)&lt;br /&gt;
(add-hook 'wl-mail-setup-hook 'mc-install-write-mode)&lt;br /&gt;
&lt;br /&gt;
(defun mc-wl-verify-signature ()&lt;br /&gt;
  (interactive)&lt;br /&gt;
  (save-window-excursion&lt;br /&gt;
    (wl-summary-jump-to-current-message)&lt;br /&gt;
    (mc-verify)))&lt;br /&gt;
&lt;br /&gt;
(defun mc-wl-decrypt-message ()&lt;br /&gt;
  (interactive)&lt;br /&gt;
  (save-window-excursion&lt;br /&gt;
    (wl-summary-jump-to-current-message)&lt;br /&gt;
    (let ((inhibit-read-only t))&lt;br /&gt;
      (mc-decrypt))))&lt;br /&gt;
&lt;br /&gt;
(eval-after-load &amp;quot;mailcrypt&amp;quot;&lt;br /&gt;
  '(setq mc-modes-alist&lt;br /&gt;
         (append&lt;br /&gt;
          (quote&lt;br /&gt;
           ((wl-draft-mode (encrypt . mc-encrypt-message)&lt;br /&gt;
                           (sign . mc-sign-message))&lt;br /&gt;
            (wl-summary-mode (decrypt . mc-wl-decrypt-message)&lt;br /&gt;
                             (verify . mc-wl-verify-signature))))&lt;br /&gt;
          mc-modes-alist)))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; notify function ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
(defun djcb-popup (title msg &amp;amp;optional icon sound)&lt;br /&gt;
  &amp;quot;Show a popup if we're on X, or echo it otherwise; TITLE is the title of the message, MSG is the context. Optionally, you can provide an ICON and a sound to be played&amp;quot;&lt;br /&gt;
  (interactive)&lt;br /&gt;
  (when sound (shell-command&lt;br /&gt;
               (concat &amp;quot;mplayer2 -really-quiet &amp;quot; sound &amp;quot; 2&amp;gt; /dev/null&amp;quot;)))&lt;br /&gt;
  (if (eq window-system 'x)&lt;br /&gt;
      (shell-command (concat &amp;quot;notify-send &amp;quot;&lt;br /&gt;
                             &lt;br /&gt;
                             (if icon (concat &amp;quot;-i &amp;quot; icon) &amp;quot;&amp;quot;)&lt;br /&gt;
                             &amp;quot; '&amp;quot; title &amp;quot;' '&amp;quot; msg &amp;quot;'&amp;quot;))&lt;br /&gt;
    ;; text only version&lt;br /&gt;
    (message (concat title &amp;quot;: &amp;quot; msg))))&lt;br /&gt;
&lt;br /&gt;
;; the appointment notification facility&lt;br /&gt;
(setq&lt;br /&gt;
 appt-message-warning-time 15 ;; warn 15 min in advance&lt;br /&gt;
 appt-display-mode-line t     ;; show in the modeline&lt;br /&gt;
 appt-display-format 'window) ;; usr our func&lt;br /&gt;
(appt-activate t)             ;; active appt (appointment notification)&lt;br /&gt;
(display-time)&lt;br /&gt;
&lt;br /&gt;
;; update appt each time agenda opened&lt;br /&gt;
(add-hook 'org-finalize-agenda-hook 'org-agenda-to-appt)&lt;br /&gt;
&lt;br /&gt;
;; our little facade-function for djcb-popup&lt;br /&gt;
(defun djcb-appt-display (min-to-app new-time msg)&lt;br /&gt;
  (djcb-popup (format &amp;quot;Appointment in %s minute(s)&amp;quot; min-to-app) msg&lt;br /&gt;
              &amp;quot;/usr/share/icons/gnome/32x32/status/appointment-soon.png&amp;quot;&lt;br /&gt;
              &amp;quot;/usr/share/sounds/purple/alert.wav&amp;quot;))&lt;br /&gt;
(setq appt-disp-window-function (function djcb-appt-display))&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Custom Variable sets ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
(custom-set-variables&lt;br /&gt;
  ;; custom-set-variables was added by Custom.&lt;br /&gt;
  ;; If you edit it by hand, you could mess it up, so be careful.&lt;br /&gt;
  ;; Your init file should contain only one such instance.&lt;br /&gt;
  ;; If there is more than one, they won't work right.&lt;br /&gt;
 '(TeX-command-list (quote ((&amp;quot;TeX&amp;quot; &amp;quot;%(PDF)%(tex) %`%S%(PDFout)%(mode)%' %t&amp;quot; TeX-run-TeX nil (plain-tex-mode texinfo-mode ams-tex-mode) :help &amp;quot;Run plain TeX&amp;quot;) (&amp;quot;LaTeX&amp;quot; &amp;quot;%`%l%(mode)%' %t&amp;quot; TeX-run-TeX nil (latex-mode doctex-mode) :help &amp;quot;Run LaTeX&amp;quot;) (&amp;quot;Makeinfo&amp;quot; &amp;quot;makeinfo %t&amp;quot; TeX-run-compile nil (texinfo-mode) :help &amp;quot;Run Makeinfo with Info output&amp;quot;) (&amp;quot;Makeinfo HTML&amp;quot; &amp;quot;makeinfo --html %t&amp;quot; TeX-run-compile nil (texinfo-mode) :help &amp;quot;Run Makeinfo with HTML output&amp;quot;) (&amp;quot;AmSTeX&amp;quot; &amp;quot;%(PDF)amstex %`%S%(PDFout)%(mode)%' %t&amp;quot; TeX-run-TeX nil (ams-tex-mode) :help &amp;quot;Run AMSTeX&amp;quot;) (&amp;quot;ConTeXt MKIV&amp;quot; &amp;quot;context %t&amp;quot; TeX-run-TeX nil (context-mode) :help &amp;quot;Run ConTeXt MKIV&amp;quot;) (&amp;quot;ConTeXt&amp;quot; &amp;quot;texexec --once --texutil %(execopts)%t&amp;quot; TeX-run-TeX nil (context-mode) :help &amp;quot;Run ConTeXt once&amp;quot;) (&amp;quot;ConTeXt Full&amp;quot; &amp;quot;texexec %(execopts)%t&amp;quot; TeX-run-TeX nil (context-mode) :help &amp;quot;Run ConTeXt until completion&amp;quot;) (&amp;quot;BibTeX&amp;quot; &amp;quot;bibtex %s&amp;quot; TeX-run-BibTeX nil t :help &amp;quot;Run BibTeX&amp;quot;) (&amp;quot;View&amp;quot; &amp;quot;%V&amp;quot; TeX-run-discard-or-function t t :help &amp;quot;Run Viewer&amp;quot;) (&amp;quot;Print&amp;quot; &amp;quot;%p&amp;quot; TeX-run-command t t :help &amp;quot;Print the file&amp;quot;) (&amp;quot;Queue&amp;quot; &amp;quot;%q&amp;quot; TeX-run-background nil t :help &amp;quot;View the printer queue&amp;quot; :visible TeX-queue-command) (&amp;quot;File&amp;quot; &amp;quot;%(o?)dvips %d -o %f &amp;quot; TeX-run-command t t :help &amp;quot;Generate PostScript file&amp;quot;) (&amp;quot;Index&amp;quot; &amp;quot;makeindex %s&amp;quot; TeX-run-command nil t :help &amp;quot;Create index file&amp;quot;) (&amp;quot;Check&amp;quot; &amp;quot;lacheck %s&amp;quot; TeX-run-compile nil (latex-mode) :help &amp;quot;Check LaTeX file for correctness&amp;quot;) (&amp;quot;Spell&amp;quot; &amp;quot;(TeX-ispell-document \&amp;quot;\&amp;quot;)&amp;quot; TeX-run-function nil t :help &amp;quot;Spell-check the document&amp;quot;) (&amp;quot;Clean&amp;quot; &amp;quot;TeX-clean&amp;quot; TeX-run-function nil t :help &amp;quot;Delete generated intermediate files&amp;quot;) (&amp;quot;Clean All&amp;quot; &amp;quot;(TeX-clean t)&amp;quot; TeX-run-function nil t :help &amp;quot;Delete generated intermediate and output files&amp;quot;) (&amp;quot;Other&amp;quot; &amp;quot;&amp;quot; TeX-run-command t t :help &amp;quot;Run an arbitrary command&amp;quot;))))&lt;br /&gt;
 '(column-number-mode t)&lt;br /&gt;
 '(erc-modules (quote (autojoin bbdb button completion fill irccontrols list log match menu move-to-prompt netsplit networks noncommands readonly ring services smiley stamp spelling track)))&lt;br /&gt;
 '(mediawiki-site-alist (quote ((&amp;quot;Funtoo&amp;quot; &amp;quot;http://www.funtoo.org/&amp;quot; &amp;quot;USER&amp;quot; &amp;quot;PASSWORD&amp;quot; &amp;quot;&amp;quot;)))))&lt;br /&gt;
(custom-set-faces&lt;br /&gt;
  ;; custom-set-faces was added by Custom.&lt;br /&gt;
  ;; If you edit it by hand, you could mess it up, so be careful.&lt;br /&gt;
  ;; Your init file should contain only one such instance.&lt;br /&gt;
  ;; If there is more than one, they won't work right.&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;; Color-Themes ;;&lt;br /&gt;
;;;;;;;;;;;;;;;;;;&lt;br /&gt;
;;(add-to-list 'load-path &amp;quot;/usr/share/emacs/site-lisp/color-theme/color-theme.el&amp;quot;)&lt;br /&gt;
;;(add-to-list 'load-path &amp;quot;~/.emacs.d/themes/&amp;quot;)&lt;br /&gt;
(require 'color-theme)&lt;br /&gt;
(color-theme-initialize)&lt;br /&gt;
;;(color-theme-subtle-hacker)&lt;br /&gt;
(color-theme-twilight)&lt;br /&gt;
;;(eval-after-load &amp;quot;color-theme&amp;quot;&lt;br /&gt;
;;  '(progn&lt;br /&gt;
;;     (color-theme-initialize)&lt;br /&gt;
;;     (require 'color-theme-citrus)&lt;br /&gt;
;;     (require 'color-theme-candy)&lt;br /&gt;
;;     (require 'color-theme-autumn-leaves)&lt;br /&gt;
;;     (require 'color-theme-inthedark)&lt;br /&gt;
;;     (require 'color-theme-marine)&lt;br /&gt;
;;     (require 'color-theme-october)&lt;br /&gt;
;;     (require 'color-theme-eatyourgreens)&lt;br /&gt;
;;     (require 'color-theme-august)&lt;br /&gt;
;;     (require 'color-theme-saddle-2)&lt;br /&gt;
;;     (color-theme-saddle-2)))&lt;br /&gt;
;;     (color-theme-subtle-hacker)))&lt;br /&gt;
&lt;br /&gt;
(setq css-indent-offset 2)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== .wl ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; load bbdb support&lt;br /&gt;
(require 'bbdb-wl)&lt;br /&gt;
(bbdb-wl-setup)&lt;br /&gt;
&lt;br /&gt;
;; setup from where to get addresses&lt;br /&gt;
(setq bbdb-wl-folder-regexp &amp;quot;^\.INBOX|^\.inbox|^\.Sent|^\.sent|^\.\[IMAPS\]\\Sent&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
;; define keybinding&lt;br /&gt;
(define-key wl-draft-mode-map (kbd &amp;quot;&amp;lt;C-tab&amp;gt;&amp;quot;) 'bbdb-complete-name)&lt;br /&gt;
&lt;br /&gt;
;; set multiple e-mail addresses&lt;br /&gt;
(setq wl-user-mail-address-list (quote (&amp;quot;User@googlemail.com&amp;quot; &amp;quot;USER@own-server.tld&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
;; handle (&amp;quot;d&amp;quot;) mark&lt;br /&gt;
;; remove = instant removal (same as &amp;quot;D&amp;quot;), thrash = move to wl-trash-folder&lt;br /&gt;
;; string = move to string&lt;br /&gt;
(setq wl-dispose-folder-alist&lt;br /&gt;
      '(&lt;br /&gt;
        (&amp;quot;\.\*googlemail\\.com&amp;quot; &amp;quot;%[Imap]/Trash:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!&amp;quot;)&lt;br /&gt;
        (&amp;quot;\.\*@own\-\server\\.tld&amp;quot; &amp;quot;%INBOX.Trash:&amp;quot;USER&amp;quot;/clear@imap.own-server.tld&amp;quot;)&lt;br /&gt;
))&lt;br /&gt;
&lt;br /&gt;
;; notify hook&lt;br /&gt;
(add-hook 'wl-biff-notify-hook&lt;br /&gt;
          (lambda()&lt;br /&gt;
            (djcb-popup &amp;quot;Wanderlust&amp;quot; &amp;quot;You have new mail!&amp;quot;&lt;br /&gt;
                        &amp;quot;/usr/share/icons/gnome/32x32/status/mail-unread.png&amp;quot;&lt;br /&gt;
                        &amp;quot;/usr/share/sounds/purple/alert.wav&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
;; timer settings&lt;br /&gt;
(setq&lt;br /&gt;
 wl-biff-check-interval 30 ;; check every 30 seconds&lt;br /&gt;
 wl-biff-use-idle-timer t) ;; in the background&lt;br /&gt;
&lt;br /&gt;
;; Name of top-folder, default &amp;quot;Desktop&amp;quot;&lt;br /&gt;
(setq wl-folder-desktop-name &amp;quot;e-Mail&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
;; select correct email address when we _start_ writing a draft.&lt;br /&gt;
(add-hook 'wl-mail-setup-hook 'wl-draft-config-exec)&lt;br /&gt;
&lt;br /&gt;
(setq wl-draft-config-alist&lt;br /&gt;
      '(&lt;br /&gt;
        ((string-match &amp;quot;googlemail.com&amp;quot; wl-draft-parent-folder)&lt;br /&gt;
         (template . &amp;quot;User&amp;quot;))&lt;br /&gt;
        ((string-match &amp;quot;own-server.tld&amp;quot; wl-draft-parent-folder)&lt;br /&gt;
         (template . &amp;quot;USER&amp;quot;))&lt;br /&gt;
))&lt;br /&gt;
&lt;br /&gt;
;; choose template with C-c C-j&lt;br /&gt;
(setq wl-template-alist&lt;br /&gt;
      '((&amp;quot;User&amp;quot;&lt;br /&gt;
         (wl-from . &amp;quot;Full Name &amp;lt;User@googlemail.com&amp;gt;&amp;quot;)&lt;br /&gt;
         (&amp;quot;From&amp;quot; . wl-from)&lt;br /&gt;
         (wl-smtp-posting-user . &amp;quot;User&amp;quot;)&lt;br /&gt;
         (wl-smtp-posting-server . &amp;quot;smtp.gmail.com&amp;quot;)&lt;br /&gt;
         (wl-smtp-authenticate-type . &amp;quot;plain&amp;quot;)&lt;br /&gt;
         (wl-smtp-connection-type . 'starttls)&lt;br /&gt;
         (wl-smtp-posting-port . 587)&lt;br /&gt;
         (wl-local-domain . &amp;quot;googlemail.com&amp;quot;)&lt;br /&gt;
         (wl-message-id-domain . &amp;quot;smtp.gmail.com&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         (wl-fcc .  &amp;quot;%[IMAPS]/Sent:\&amp;quot;User@googlemail.com\&amp;quot;/clear@imap.gmail.com:993!&amp;quot;)&lt;br /&gt;
         (wl-draft-folder .  &amp;quot;%[IMAPS]/Draft:\&amp;quot;User@googlemail.com\&amp;quot;/clear@imap.gmail.com:993!&amp;quot;)&lt;br /&gt;
        )&lt;br /&gt;
        (&amp;quot;USER&amp;quot;&lt;br /&gt;
         (wl-from  . &amp;quot;Full Name &amp;lt;USER@own-server.tld&amp;gt;&amp;quot;)&lt;br /&gt;
         (&amp;quot;From&amp;quot;  . wl-from)&lt;br /&gt;
         (wl-smtp-posting-user  . &amp;quot;USER&amp;quot;)&lt;br /&gt;
         (wl-smtp-posting-server  . &amp;quot;smtp.own-server.tld&amp;quot;)&lt;br /&gt;
         (wl-local-domain . &amp;quot;own-server.tld&amp;quot;)&lt;br /&gt;
         &lt;br /&gt;
         (wl-fcc  &amp;quot;%INBOX.Sent:USER/digest-md5@imap.own-server.tld:143&amp;quot;)&lt;br /&gt;
         (wl-draft-folder  &amp;quot;%INBOX.Drafts:USER/digest-md5@imap.own-server.tld:143&amp;quot;)&lt;br /&gt;
        )&lt;br /&gt;
       )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
(define-key wl-template-mode-map (kbd &amp;quot;&amp;lt;right&amp;gt;&amp;quot;) 'wl-template-next)&lt;br /&gt;
(define-key wl-template-mode-map (kbd &amp;quot;&amp;lt;left&amp;gt;&amp;quot;) 'wl-template-prev)&lt;br /&gt;
&lt;br /&gt;
(setq wl-default-spec &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
(setq wl-fcc-force-as-read t)&lt;br /&gt;
(setq wl-auto-save-drafts-interval nil)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== .folders ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User@googlemail{&lt;br /&gt;
         %INBOX:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!    &amp;quot;Inbox&amp;quot;&lt;br /&gt;
        [IMAPS-gmail]{&lt;br /&gt;
                %[IMAPS]/Sent:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!      &amp;quot;Sent&amp;quot;&lt;br /&gt;
                %[IMAPS]/Draft:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!      &amp;quot;Draft&amp;quot;&lt;br /&gt;
                %[IMAPS]/Spam:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!      &amp;quot;Spam&amp;quot;&lt;br /&gt;
                %[IMAPS]/Trash:&amp;quot;User@googlemail.com&amp;quot;/clear@imap.gmail.com:993!      &amp;quot;Trash&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
USER@own-server.tld{&lt;br /&gt;
        %INBOX:USER/digest-md5@imap.own-server.tld   &amp;quot;Inbox&amp;quot;&lt;br /&gt;
        %INBOX.Sent:USER/digest-md5@imap.own-server.tld &amp;quot;Sent&amp;quot;&lt;br /&gt;
        %INBOX.Drafts:USER/digest-md5@imap.own-server.tld &amp;quot;Drafts&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:HOWTO]]&lt;br /&gt;
[[Category:Featured]]&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	<entry>
		<id>http://www.funtoo.org/wiki/Emacs</id>
		<title>Emacs</title>
		<link rel="alternate" type="text/html" href="http://www.funtoo.org/wiki/Emacs"/>
				<updated>2013-01-11T23:44:13Z</updated>
		
		<summary type="html">&lt;p&gt;Golodhrim: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Golodhrim</name></author>	</entry>

	</feed>