SealSkin

store

The object store that holds everything the nodes of a cluster share.

Users, groups, installed apps, app stores, templates, and the cluster's own records (cluster/) are objects under fixed keys. Every node reads and writes them through one ObjectStore, so the store is the authority and no node is:

  • FileStore keeps each object as the file SealSkin has always kept it in, so a single server stores what it stored before and an administrator can still edit it by hand.
  • S3Store keeps them in a bucket of any S3-compatible service.
  • PeerStore reads and writes the FileStore of another node, for a small cluster with no bucket.

A write may be conditional on the object's entity tag (if_match) or on its absence (if_absent), which is all the locking the administrative writes need. Calls block: reads are served from the caches the callers keep, and writes are administrative and rare. A service that takes the conditions and ignores them would leave the nodes overwriting each other unseen, so verify proves them with one throwaway object before the node serves anything.

A remote store is mirrored into the local files as it is read, and a node that cannot reach it serves that mirror until it can.

attributelogger
= logging.getLogger(__name__)
attributeMOUNTSdict[str, str]
= {'installed_apps.yml': 'installed_apps_path', 'app_stores.yml': 'app_stores_path', 'proot_catalogs.yml': 'proot_catalogs_path', 'vpn_profiles.yml': 'vpn_profiles_path', 'app_templates/': 'app_templates_path', 'keys/': 'keys_base_path', 'groups/': 'groups_base_path', 'branding/': 'branding_path', 'cluster/': 'cluster_path', 'files/': 'shared_files_path'}
attributeWATCHED
= tuple(prefix for prefix in MOUNTS if prefix != 'files/')
attributeUNWATCHED
= ('cluster/leases/', 'cluster/probe/')