If you’re getting into SyncEvolution (hereafter SE), there are a few concepts that are crucial to understand. As SE is at heart a SyncML synchronization engine, the simplest case describes everything in terms of SE as a SyncML client, talking to a remote SyncML server.
So if I want to set up a file-based datastore called ‘local-contacts’, and a file-based datastore called ‘local-calendar, which I want to sync with a remote Horde SyncML server at https://horde.example.com/rpc.php, I would do the following
syncevolution –configure –template none backend=file database=”file:///tmp/my-contacts-store” databaseformat=text/vcard @Local local-contacts
This means: in context ‘@Local’ (contexts are created whenever they’re referenced), create (or update) a datastore ‘local-contacts’ (SE knows that we’re configuring a data store because we are passing it properties that are relevant to data stores), and on that datastore set the following properties: backend, database and databaseFormat.
Likewise, I set up my calendar data store:
syncevolution –configure –template none backend=file database=”file:///tmp/my-calendar-store” databaseformat=text/calendar @Local local-calendar
Next, I need to set up my client endpoint so I can specify the server to sync with:
syncevolution –configure –template none syncURL=https://horde.example.com/rpc.php username=<your Horde username> password= <your Horde password> Horde@Local local-calendar local-contacts
Which tells SE that I want to set up a client endpoint (implied by the syncURL property being set) named ‘Horde’ (if you’re setting a client endpoint property, the first name on the command line is the client endpoint) in context @Local, and that you want to sync the two data stores ‘local-calendar’ and ‘local-contacts’ using that endpoint (also in context @Local).
Then we still need to tell SE which direction we want to sync these, so we set up synced stores for these:
syncevolution –configure sync=two-way Horde@Local local-calendar
syncevolution –configure sync=two-way Horde@Local local-contacts
Which means ‘if I sync client endpoint Horde from context @Local, offer data store local-calendar/local-contacts to the remote server for two-way sync’. Now we should be all set to sync. The first time, it is required to do a slow sync:
syncevolution –sync slow Horde@Local
Which will sync all synced stores for this endpoint. After this first time, you can do an incremental (much faster) sync with
syncevolution Horde@Local
But synchronizing between a remote SyncML server and a local file-based store (or a local evolution data store – hence the name) is not all that SE can do. It can also synchronize with ‘server-based’ data stores, such as Exchange (through activesync, aka EAS) or WebDAV-based servers that implement the CalDAV and/or CardDAV protocols.
EAS and WebDAV are not considered sync engine technologies within the scope of SE, but data storage engines. While it would be in principle possible to set up a pair of server-based backends, for simplicity and debuggability, we set up a hub-and-spoke system with the hub a simple backend such as the ‘file’ or ‘eds’ backends. The hub will be SE as a syncml client, as described above. We shall leave the setup from the first section in place, but add an Exchange server (which understands both contacts and calendars) to sync our data stores with.
Since SE really only speaks SyncML for synchronization, we need a SyncML ‘server front’ for EAS and WebDAV servers to talk to. Fortunately, SE itself implements such a faux SyncML server.
SE implements this faux server in what it calls a ‘target config’, and which I’ll call a ‘Faux Server Endpoint’ (FSE) here. The FSE must always be named ‘target-config’, so ‘target-config’ might seem the best way to go for naming, but I want to distinguish between the concept of the FSE, and any particular FSE, which must have the name ‘target-config’.
The FSE (conceptually) awaits an incoming connection from the SE client endpoint set up above. This incoming server must know what data stores it has available, so we set it up with some synced stores – in this case, EAS-based stores.
EAS based stores take a little more tending to than file-based stores, but nothing beyond some mild head-against-concrete bashing. For EAS, you will need to have activesyncd installed in addition to syncevolution, and you’ll need to store some configuration data outside SE where activesyncd can find it: your username/password on the server, and the activesync URL. These can be set up as follows:
gconftool-2 –set –type=string “/apps/activesyncd/accounts/<your exchange email address>/username” <your username, including domain>
gconftool-2 –set –type=string “/apps/activesyncd/accounts/<your exchange email address>/password” <your password>
gconftool-2 –set –type=string “/apps/activesyncd/accounts/<your exchange email address>/serverUri” <your exchange activesync URL>
The EAS URL will usually look something like ‘https://owa.example.com/Microsoft-Server-ActiveSync’; if you don’t know it, head over to https://testconnectivity.microsoft.com/, select tab ‘Exchange Server’, option ‘Automatic detection of Exchange ActiveSync’ and let it discover the settings; in the resulting page, expand everything, and search for <Name>; in it will be the full EAS url.
After we’ve set up the credentials, we can go back to SE. First the contacts data store:
syncevolution –configure –template none backend=eas-contacts database=<contacts folder name> @Exchange exchange-contacts
This means: in context ‘@Exchange’, create a datastore ‘exchange-contacts’ (SE again knows that we’re configuring a data store because we are passing it properties that are relevant to data stores), and on that datastore set the following properties: backend, database. In this case, we do not need to set up databaseFormat, since the backend ‘eas-contacts’ can only store contacts. The database in this case is a little different than the file stores we set up above, since it is not a full specification of where to find your EAS contacts; it is instead resolved from at the moment SE logs on, and the information is specified later. We will get back to this in a bit. The name of your contacts folder can be seen in Outlook, or you can list the available folders using SE:
syncevolution –print-databases username=<your exchange email address> backend=eas-contacts
and likewise, for your calendars, which we’ll need in a bit:
syncevolution –print-databases username=<your exchange email address> backend=eas-events
In the same way, we set up our calendar store:
syncevolution –configure –template none backend=eas-events database=<calendar folder name> @Exchange exchange-calendar
At this point we have two data stores in the @Exchange context, named ‘exchange-contacts’ and ‘exchange-calendar’, but we still need to set up the corresponding synced stores:
So now we set up the actual FSE. Notice the name: it must be ‘target-config’
syncevolution –configure –template none username=<your exchange email address> password= printChanges=1 target-config@Exchange
We don’t need to set a password, since we’ve already handed that to activesyncd, but SE does need to know which activesyncd user to use, so <your exchange email address> is passed as a matching key; hence the <your exchange email address> in the gconftool-2 invocations. It is here where the ‘database’ property from the data store becomes fully meaningful in combination with the data we stuffed into activesyncd; there is no meaningful direct URL to any Exchange folder when it comes to activesync.
Now we still need to tell SE which data stores can be synced through the FSE. These are specified as synced stores much like we did before:
syncevolution –configure sync=none target-config@Exchange exchange-contacts
syncevolution –configure sync=none target-config@Exchange exchange-calendar
Which means ‘if I am contacted for sync in context @Exchange, I have data stores exchange-calendar/exchange-contacts in context @Exhange available for sync’. We’re setting sync=none here only to trigger the creating of a synced store. We could have used any value for ‘sync’, as its value is ignored; the ‘sync’ value of the client side will take precedence.
Next, we set up the available stores for the FSE:
syncevolution –configure sync=none target-config@Exchange exchange-contacts
syncevolution –configure sync=none target-config@Exchange exchange-calendar
Which means 'if I am contacted for sync in context @Exchange, I have data stores exchange-calendar/exchange-contacts in
context @Exhange available for sync'.
We're setting sync=none here only to trigger the creating of a synced store. We could have used any value for 'sync', as
its value is ignored; the 'sync' value of the client side will take precedence.
Now that we have our FSE(s) set up, it’s time to tie them together with our data stores that we set up in the @Local context. For this, we’ll need to create a new client endpoint, and with it, the required synced stores. First the client endpoint:
syncevolution –configure syncUrl=local://@Exchange peerIsClient=1 ExchangeEP@Local
which means: create client endpoint ‘ExchangeEP’ in context @Local, and give it syncURL ‘local://@Exchange’. I could have named my client endpoint ‘Exchange’ without any problem (and it would indeed be common practice to do it this way), but I want to distinguish between these two different things (context and client endpoint) explicitly for the moment. As for the peerIsClient – it is just required at this point. The URL is special, and we will get to that in a bit. Next, some synced stores:
syncevolution –configure sync=two-way uri=exchange-contacts ExchangeEP@Local local-contacts
syncevolution –configure sync=two-way uri=exchange-calendar ExchangeEP@Local local-calendar
Which means: When I sync ExchangeEP@Local, perform a two-way sync between local-contacts from context @Local with exchange-contacts from context @Exchange; we know this exchange-contacts lives in @Exchange because the syncURL from ExchangeEP (local://@Exchange) tells us that we’re syncing with an FSE in that context. Likewise perform a two-way sync between local-calendar from context @Local with exchange-calendar from context @Exchange.
And that was all she wrote. Just like the simple example, we must first perform a slow sync
syncevolution –sync slow ExchangeEP@Local
Which will sync all synced stores for this endpoint. After this first time, you can do an incremental (much faster) sync with
syncevolution ExchangeEP@Local
And that, was that.