Usage¶
This is an introduction to usage of pimsync. For reference documentation, see the manual page, pimsync.1.
As mentioned in the introduction, pimsync is configured via a
configuration file. The default path for the configuration file is
~/.config/pimsync/pimsync.conf
, and it can be overridden using the -c
flag or by setting $XDG_CONFIG_HOME
.
Basic setup¶
The most basic setup synchronises calendar events from a remote CalDAV server to a local directory. This requires a configuration file with three sections:
A
storage
section describing the details of the CalDAV server.A
storage
section describing the details of the local directory.A
pair
section describing how these two storages should be synchronise with each other.
Additionally, a status_path must be specified. This is the path to a
directory where pimsync
shall store a small database with the state of the
events on both calendar storages. This helps resolve conflicts later: when a
file changes on one storage, pimsync
consults this status database to
determine which side changed and which way data needs to flow to synchronise
changes.
The corresponding configuration file for this example would looks something like:
# use a standard location for the status database:
status_path "~/.local/share/pimsync/status/"
storage calendars_remote {
type caldav
url https://caldav.example.com/
username hugo@example.com
password 123
}
storage calendars_local {
type vdir/vcard
path ~/.local/share/contacts/cards/
fileext vcf
}
pair calendars {
storage_a contacts_local
storage_b contacts_fastmail
collections all
}
The collections all directive indicates that all collections (calendars) from both sides should be synchronised. See pimsync.conf.5 for full details on the configuration file syntax and available directives.
Storing passwords in configuration files like this is considered poor security practice; one can accidentally leak them when sharing or backing up a configuration, and it’s easy for other misbehaving software to accidentally leak it. Instead, we store credentials in a secret storage service, and use some helper to retrieve credentials.
Usage with a secret storage service¶
In this case, I’ll be using himitsu, a secret storage manager, which I already have set up and running locally.
First I’ll store my password into the store by running hiq -a
, and then
providing the details for the entry, followed by ^d
:
proto=caldavs username=hugo@example.com password!=123
Consult the documentation for your system’s secret storage service for specific instructions on how to persist credentials. Usually non-password fields are required in order to query the secret service and indicate which secret we want.
For the above created entry, I can use the following command to query for the password:
hiq -dFpassword proto=caldavs username=hugo@example.com
When the above command runs, the secret storage will prompt for my authorisation to disclose credentials, and then provide the password if I accept the prompt.
The storage
block for the above CalDAV server now changes to:
storage calendars_remote {
type caldav
url https://caldav.example.com/
username hugo@example.com
password {
cmd hiq -dFpassword proto=caldavs username=hugo@example.com
}
}
Running as a deamon¶
The pimsync daemon
command will make pimsync run continuously and keep
calendars and contacts in sync. This is most suitable as a daemon that runs in
the background for your user session.
It is recommended to put this daemon and other which require credentials under a non-default bundle/target/run-level, so that they don’t result in credential prompts as soon as one logs in. This target should be manually started instead.
An service script for OpenRC should look something like:
#!/sbin/openrc-run
description="Synchronise calendars and contacts"
command="/usr/bin/pimsync daemon -r 3"
ready=fd:3
supervisor=supervise-daemon
error_logger="logger -t '${RC_SVCNAME}' -p daemon.error"
An service unit for systemd should looks something like:
[Unit]
Description=Synchronise calendars and contacts
Documentation=man:pimsync
[Service]
# TODO: glue for readiness notification
ExecStart=/usr/bin/pimsync daemon
Restart=no
Slice=background.slice
[Install]
WantedBy=sync.target
Fetching a calendar via Webcal¶
Webcal refers to events published in a single iCalendar file via HTTP(s). Pimsync can fetch events (and other iCalendar components) and synchronise them to a CalDAV or vdir storage. Webcal storages are read-only, since they’re no more than a regular resource exposed via HTTP(s).
A typical configuration looks something like:
pair holidays {
storage_a calendars_local
storage_b holidays_remote
collection holidays
}
storage holidays_remote {
type webcal
collection_id holidays
url https://www.thunderbird.net/media/caldata/autogen/DutchHolidays.ics
}
# storage calendars_local omitted for brevity; same as above.
Normally, storages have multiple calendar collections. Webcal is exception is
that it only contains a single collection. The name given to this collection is
controlled via the collection_id
parameter, as shown above. In the above
example, the calendar exposed via Webcal shall be synchronised with a calendar
named holidays
in the calendars_local
storage.
Webcal with secret URLs¶
Some Webcal URLs contain secret tokens in the URL, or other sensitive material
which should not be stored in a configuration file. The url
directive’s
parameter can be stored in an external secret storage, and retried via the same
mechanism as used in the usage with a secret storage service section above:
storage calendars_italki {
type webcal
collection_id italki
url {
cmd hiq -dFurl proto=webcal alias=italki
}
}
Protections against deletion¶
Pimsync features two configurable mechanisms to protect from accidental deletion of data.
Emptied collection¶
The on_empty
configuration directive controls which action to take when one
collection has been completely emptied. The default value is skip
, which means
that an emptied collection is skipped instead of synchronised. The other
possible value is sync
.
Let’s assume a typical setup: a local vdir is being synchronised with a remote CalDAV server. If we delete all items inside a local collection, then…
on_empty skip
will prevent deletion of items in the remote collection. Instead, a pimsync shall display a warning message. This prevents accidentally deleting all remote data when deleting all local data.on_empty sync
will perform a “normal” synchronisation, which in this case would completely empty the remote collection.
Deleted collection¶
The on_delete
configuration directive controls what happens when a
collection itself is deleted. Only empty collections are deleted, so the value
of the on_empty
setting has an indirect impact on this scenario as well.
on_delete sync
will synchronise deletion of collections. Only empty collecitons are ever deleted, so this setting only deletes collections if they were manually emptied on both sides, or when usingon_empty sync
.on_delete skip
will skip deletion of collections.
Wiping and starting over¶
Because pimsync keeps an internal status database, simply deleting all data from one storage won’t restore all of it from the other one. Usually the deletion protection mentioned above would kick in.
In a scenario where you want to delete all local data and have it recreated from the remote server, the following steps should be taken:
Ensure that
pimsync daemon
is not running, and that no automated mechanism would trigger a synchronisation.Delete all data for the local storage.
Delete the status database for the corresponding pair.
Further topics¶
Contributions for guides for other usage scenarios are most welcome.