
# Compound actions

## Introduction

The main idea behind the compound actions is to group the huge amount of 
actions, resulting from an actiongraph, in different sets of actions related 
somehow. For example, when a partition is created and then formatted and mounted,
we can consider all these actions sufficiently related as to group them in only 
one high order action.

Let consider the following commit actions:

*  Create primary partition /dev/sda1 (20.00 GiB)
*  Create ext4 on /dev/sda1 (20.00 GiB)
*  Mount /dev/sda1 at /
*  Add mount point / of /dev/sda1 to /etc/fstab

Instead of these four commit actions, we can summarize them in an unique compact 
action easier to read for the end-user:

* Create primary partition /dev/sda1 (20.00 GiB) for / with ext4

### Highlights

* Compound actions are implemented by class `CompoundAction`.
* A compound action represents a set of commit actions (actions of an 
  **actiongraph**).
* Each commit action has an associated device, and they perform an specific 
  action over that device.
* All commit actions belonging to a compound action share the same 
  *target device*.
* The target device is obtained from the device of a commit action (see next 
  section **Obtaining target device**).

The class `CompoundAction` is accessible via SWIG bindings. This allows the 
client (ruby or python) to obtain a list of compound actions objects from an 
actiongraph instead of a list of strings, as it is actually done with the commit 
actions.

Working directly with a list of objects has many advantages. For example, all 
the logic to represent the actions is delegated to the client: actions order, 
how to group them, representation style, filters, etc.


## Obtaining target device

The compound actions are generated by the class `CompoundAction::Generator`. To 
generate them, a target device is defined for each commit action. The target 
device is the final device related to a specific commit action. It depends on 
the device type of a commit action:

|Device type     | Possible targets
|----------------|----------------------
|Md              | Md
|Disk            | Disk
|PartitionTable  | Disk, Md, Dasd
|Partition       | Partition
|Encryption      | Disk, Md, Dasd, Partition, LvmLv 
|LvmPv           | Encryption, Disk, Md, Dasd, Partition
|LvmVg           | LvmVg
|LvmLv           | LvmLv
|Nfs             | Nfs 
|BtrfsSubvolume  | BtrfSubvolume
|BlkFilesystem   | Disk, Md, Dasd, Partition, LvmLv
|MountPoint      | Disk, Md, Dasd, Partition, LvmLv, BtrfsSubvolume

A compound action is generated with all commit actions that share the same 
target device.


## Generating the compact sentence

The class `CompoundAction::Formatter` generates the sentence (string 
representation) of a compound action. That sentence depends on the set of commit 
actions. There is a specific formatter depending on the type of the target 
device.

### `CompoundAction::Formatter::Partition`

Example of commit actions:

* Create primary partition /dev/sda1 (40.00 GiB)
* Create btrfs on /dev/sda1 (40.00 GiB)
* Mount /dev/sda1 at /
* Add mount point / of /dev/sda1 to /etc/fstab

Resulting sentence:

* Create partition /dev/sda1 (40.00 GiB) for / with btrfs

### `CompoundAction::Formatter::Partition`

Example of commit actions:

* Create primary partition /dev/sda1 (47.00 GiB)
* Set id of partition /dev/sda1 to Linux LVM (0x8E)
* Create physical volume on /dev/sda1

Resulting sentence:

* Create partition /dev/sda1 (47.00 GiB) as LVM physical volume

### `CompoundAction::Formatter::LvmLv`

Example of commit actions:

* Create logical volume root (20.00 GiB) on volume group system
* Create ext4 on /dev/system/root (20.00 GiB)
* Mount /dev/system/root at /
* Add mount point / of /dev/system/root to /etc/fstab

Resulting sentence:

* Create LVM logical volume /dev/system/root (20.00 GiB) for / with ext4

### `CompoundAction::Formatter::BtrfsSubvolume`

Example of commit actions:

* Create subvolume @/var/lib/pgsql on /dev/sda1
* Set option 'no copy on write' for subvolume @/var/lib/pgsql on /dev/sda1
* Mount subvolume @/var/lib/pgsql on /dev/sda1 at /var/lib/pgsql
* Add mount point /var/lib/pgsql of subvolume @/var/lib/pgsql on 
  /dev/sda1 to /etc/fstab

Resulting sentence:

* Create subvolume @/var/lib/mysql on /dev/sda1 with option 'no copy on write'


## Collapsing/expanding btrfs subvolume actions

The list of btrfs subvolume actions in the proposal summary exceeded the 
threshold of being useful. To avoid a large list of subvolume actions, a 
collapsible list is added after the general actions in the proposal summary. 
This list of subvolume actions is collapsed by default with a link to expand it. 
Once the list is expanded, all subvolume actions are showed, presenting delete 
ones at the beginning.

Collapsed list

* 20 subvolume actions (see details)

Expanded list

* 20 subvolume actions (hide details)
* Delete subvolume @/var/lib/machines on /dev/sda2
* Delete subvolume @/var/lib/libvirt/images on /dev/sda2
* Delete subvolume @/var/crash on /dev/sda2
* Delete subvolume @/var/cache on /dev/sda2
* Delete subvolume @/usr/local on /dev/sda2
* Delete subvolume @/tmp on /dev/sda2
* Delete subvolume @/srv on /dev/sda2
* Create subvolume @ on /dev/system/root
* Create subvolume @/boot/grub2/i386-pc on /dev/system/root
* Create subvolume @/boot/grub2/x86_64-efi on /dev/system/root
* Create subvolume @/opt on /dev/system/root
* Create subvolume @/srv on /dev/system/root
* Create subvolume @/tmp on /dev/system/root
* Create subvolume @/usr/local on /dev/system/root
* Create subvolume @/var/cache on /dev/system/root
...

