By Jove, I do think I've got it. The full howto is below.
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.
Contexts. Contexts mainly group data stores, client endpoints and server
endpoints together; each of these always lives in exactly one
context.Data stores, or stores for short. In the existing SE parlance
these are called sources or data sources. You can think of a data store
as you would of an individual database, with a single table. The table
can store items of exactly one kind (in the case of SE: events, memos,
contacts or tasks), and the data store configuration holds all
information required to access that database. Specifically, you will at
least need to set up the first two properties for a data store, and
optionally more, depending on the backend selected: backend, which
specifies the storage ‘engine’database: a specification of where the
database can be found. It needs to be fully specified, but its format
depends on the backend. The ‘file’ backend will take full paths to a
directory, for example (in url format), the carddav backend requires the
carddav url for the carddav serverdataFormat, in case the storage engine
is capable of implementing more than one kind of ‘table’. The ‘file’
backend, for example, can be used to store either contacts or events.
The carddav backend can only store contacts, so for this engine the only
possible format is implieddatabaseUser, databasePassword: credentials to
access the database, if required. Obviously not necessary for the ‘file’
backend, but in some instances, the credentials can be provided by a
different path – more on that later.Client Endpoints, or sync configs in
the existing SE parlance. These describe an SyncML client, implemented
in SE. To set up a client endpoint, you provide the following
properties: username, password: credentials to access the remote SyncML
serversyncURL: URL of the remote SyncML serverSynced stores. Synced
stores specify which data stores within the same context a client
endpoint wants to sync with the SyncML server above. a client endpoint
on its own can’t do anything since it doesn’t know what needs to be
synced; you can tie these together by specifying the desired client
endpoint and data store, and then specifying how you want to sync that
data store with the remote server two-way: only send/receive changes
since last syncslow: two-way, exchange all itemsrefresh-from-remote:
discard all local items and replace with the items on the
peerrefresh-from-local: discard all items on the peer and replace with
the local itemsone-way-from-remote: transmit changes from
peerone-way-from-local: transmit local changesdisabled (or none):
synchronization disabled
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
Synchronization beyond SyncML
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.
Exchange activesync
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.
Giving the FSE something to do
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.
Connecting with the FSE
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 Syncing with the FSE
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.
_______________________________________________
SyncEvolution mailing list
[email protected]
https://lists.syncevolution.org/mailman/listinfo/syncevolution