How to only run kopia snapshots when zfs dataset is decrypted?

I am pretty new to kopia but very happy so far. I use it to snapshot and backup an encrypted ZFS dataset, but I just noticed that I had forgotten the fact that upon restart of this NAS where kopia runs I need to manually decrypt the ZFS dataset which holds the folder kopia should back up.

Furthermore, I know I can create a script which gets run by cron, and which first checks if the dataset is encrypted, but I thought I’d first ask if anyone has a better or similar solution/problem?

Kopia does not have the ability to decrypt the ZFS dataset for you.

BUT, what you can do is write your script that decrypts the ZFS dataset and then use Kopia’s Actions feature (see Actions | Kopia) so that Kopia runs your script automatically before the snapshot. You can even tell Kopia to run another script after the snapshot is complete (such as to re-encrypt the ZFS dataset).

1 Like

I wanted to continue tinkering with actions but am confused by the terminology I found on the actions docs page: Actions | Kopia

could somebody please explain in plain words what the difference is between --before-folder-action
and
--before-snapshot-root-action or simply point me to where I can find more info about the difference?

Lets take this scenario:

I have 3 cronjobs which run periodic snapshots of 3 folders. 2 of them are encrypted so on these snapshots I need some action to run a script and only continue if the decryption keys for these folders are available and the folders are mounted while the 3rd cron job should not do any actions as the folder it snapshots is unencrypted.

I already found a script which can exit with 0/1 depending on the encryption status of a specific folder, I’m simply struggling to understand the concept of these two --beforeXYZ options.

  • Before folder action runs before Kopia scans a folder when running a snapshot.

  • After folder action runs after Kopia scans a folder when running a snapshot

  • Before snapshot action runs before Kopia starts its snapshot

  • After snapshot action runs after Kopia finishes its snapshot

You can tackle your scenario in multiple different ways:

(1) Backup all three folders using one policy. Have a before snapshot action decrypt your two folders. Have an after snapshot action reencrypt your two folders. You can also use before/after folder actions.

(2) Create a separate policy for each folder. Again, you can use before/after snapshot actions or before/after folder actions.

Thanks, that is very useful advice. I didn’t even know I could add multiple [sources] to one snapshot action :frowning: after I read your reply I checked again: snapshot create | Kopia and it was mentioned at the very bottom:

image

so basically that would look like:
kopia snapshot create /some/Folder/One/ /some/Folder/Two/ /other/Folder/

I think I am good to go now but let me ask a last question:

What is the purpose of before/after FOLDER actions? I can’t come up with any usage scenarios while before/after SNAPSHOT actions are easy to find usage scenarios for.

I think I am close to figuring it out. After I read the below text, I think I get it. If you have to set these before/after folder actions directly for a specific folder, that makes much more sense. I couldn’t figure what action I’d want to run before backing up each and every sub-folder :slight_smile:

THANKS for your patience and the help!

I didnt mean this, and I am not sure this will work. (Feel free to try it and report back.) I meant that you can create separate policies for separate folders, all backed up to the same repository. So, for example, create one policy to backup /some/Folder/One/ and another policy to backup /some/Folder/Two/ and so on. If you choose to create these separate policies (as opposed to one policy for /some/Folder/, you can then have different actions for each of these policies.

thanks for all your help. Here is what I am trying to do:

2 cron jobs:

11 * * * * kopia snapshot create /sixer/Documents/ --log-level=warning --no-progress --force-enable-actions
41 * * * * kopia snapshot create /sixer/Pictures/ --log-level=warning --no-progress --force-enable-actions

I think next I need to enable the actions for each source:

kopia policy set /sixer/Documents/ --action-command-mode=essential --before-snapshot-root-action /root/scripts/check-encryption-status.sh --persist-action-script 
kopia policy set /sixer/Pictures/ --action-command-mode=essential --before-snapshot-root-action /root/scripts/check-encryption-status.sh --persist-action-script

/root/scripts/check-encryption-status.sh is a script which takes 1 argument and then checks whether the key for the encrypted dataset is available and the dataset is mounted. If both are true, it exits with “exit 0”

I’m now trying to figure out what and how I can pass through as argument for the dataset. The dataset value would be “/sixer/Documents” or “/sixer/Pictures”

I found these 2 options but am unsure which one to use and how exactly.
image

here is my script for now using an argument to check:

#!/bin/bash                                                                                                                                                                                                                                                                                                          
keystatus=$(zfs get -H -o value keystatus $1 )                                                                                                                                                                                                                                                                       
mountstatus=$(zfs get -H -o value mounted $1 )                                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                    
if [ "$keystatus" = "available" ] && [ "$mountstatus" = "yes" ]; then                                                                                                                                                                                                                                                
        exit 0                                                                                                                                                                                                                                                                                                       
else                                                                                                                                                                                                                                                                                                                 
        exit 1                                                                                                                                                                                                                                                                                                       
fi

would this work?

eystatus=$(zfs get -H -o value keystatus $KOPIA_SOURCE_PATH )                                                                                                                                                                                                                                                                       
mountstatus=$(zfs get -H -o value mounted $KOPIA_SOURCE_PATH )

KOPIA_SOURCE_PATH VS KOPIA_SNAPSHOT_PATH? Can’t figure out the difference. :frowning:

I don’t want to globally enable actions so I added --force-enable-actions to my cron job. Is this the right way? Is it not enough to set actions via policy?

To me, the help docs at Actions | Kopia are pretty clear with regards to the questions you have. I would recommend giving them another read.

In short, I believe KOPIA_SOURCE_PATH is the path of the source files and KOPIA_SNAPSHOT_PATH is the path that Kopia is snapshotting. When doing a before action, these two values are the same. When doing an after action, these two values can differ if you change KOPIA_SNAPSHOT_PATH such as in a script. Look at the examples on the actions help docs page.

Setting actions via a policy does nothing if you do not have actions enabled. You enter either enable them globally for the repo or using --force-enable-actions.

Thanks for your patience. I seem to have it all figured out now. I have read that man page about actions countless times, hence all my questions. I must either be in way above my head or maybe it’s a matter of English being my second language but without your help, I wouldn’t have figured it out relying solely on the man page.

If you are open to it, feel free to share what worked for you (including the script), so that people may be able to use it if they have similar issues.

I set a policy for a source like this:
kopia policy set /sixer/Documents/ --action-command-mode=essential --before-snapshot-root-action /root/scripts/check-encryption-status.sh --persist-action-script

then I set up a cronjob:
11 * * * * kopia snapshot create /sixer/Documents/ --log-level=warning --no-progress --force-enable-actions

The script I ended up using as --before-snapshot-root-action is this

#!/bin/bash                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
keystatus=$(/usr/sbin/zfs get -H -o value keystatus $KOPIA_SOURCE_PATH )                                                                                                                                                                                                                                             
mountstatus=$(/usr/sbin/zfs get -H -o value mounted $KOPIA_SOURCE_PATH )                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                     
if [ "$keystatus" = "available" ] && [ "$mountstatus" = "yes" ]; then             
        exit 0                                                                                                                                                                                                                                                                                                       
else                                                                                                                                                                                                                                                                                                                 
        exit 1                                                                                                                                                                                                                                                                                                       
fi

This way, before each snapshot the action script checks whether my encrypted zfs dataset has a key available and if it is mounted. Both clauses need to be true for a snapshot to happen.

2 Likes