Skip to content

ModelingServices

Larry Peterson edited this page Feb 12, 2015 · 8 revisions

Modeling Services

Approach

Rather than model each service as a subclass of the XOS Service class, we associate a set of opaque tuples (attributes) with each service, and create a service-specific View that renders this service to the user. This view understands how to interpret the attributes.

More specifically, we build a view using xoslib, which means to extend the server side of xoslib to include this service. It is fact this server side that "interprets" the service attributes. This a trust issue that needs to be addressed, but at this moving this to xoslib (or some service-specific library) is easier than adding models to the DB.

In the case of native services (those that do not already have a service-specific controller), we also provide a generic Observer that pulls these tuples out of the DB and distributes them to the instances (slivers) that implement the service, perhaps using a building block mechanism like Syndicate.

So in the end, XOS maintains the persistent state, but all in service-specific interpretation of this state happens outside the DB (i.e., in a library built on top, or in a backend instance that parses the configuration attributes it is handed).

Data Model

Service

  • Name -- human readable name
  • Slices[ ] -- resource container(s) in which service instances run
  • View -- info needed to implement a view on the service
  • Controller -- info needed to implement an observer plug-in
  • Parameters -- set of Attributes that represent global configuration state
  • Tenants[ ] -- state representing an individual tenant of the service

View

  • Name -- human readable name
  • Type -- iframe, javascript,...
  • Render -- URL that renders view

Tenant

  • Name -- human readable name
  • Parameters -- set of Attributes that represent this tenant
  • ???

Controller

  • URL of external controller, if there is one
  • credentials needed to call external controller
  • other info needed to run the observer plug-in

Attributes

  • Set of name/value pairs

Policy

  • Whitelist -- predicate that determines whether or not a given tenant can create a new tenancy.

Observer Support

In the case of legacy services -- those that already have a service controller -- the observer plug-in associated with the service reads the global parameters and per-tenant parameters associated with the service from the DB, and makes the corresponding calls on the existing service controller.

In the case of native services -- those that do not have a legacy controller -- we expect to use Syndicate to distribute the global parameters and per-tenant parameters to all the instances running in OpenCloud. The corresponding tuples are likely translated into a config file that is meaningful to those instances, and then written to a well-known place in a shared volume.

Bootstrapping Services

In addition to distributing configuration state to instances implementing a native service, Syndicate also offers the means to securely bootstrap service instances. Syndicate would offer a way for users to ship program binaries to their slices, as well as a way for the observer to ship configuration state to the slice.

Each slice will receive a private Syndicate volume, and the Observer will be registered as a read/write user on it that creates read-only configuration files. The user can mount the same volume on their local workstation to access the service proper as well as put new service code and data into the VM (Figure 1).

Figure 1

Figure 1: the Syndicate shared volume is used both as a mechanism for delivering service configuration from the OpenCloud observer to VMs (red arrows), as well as a mechanism for users to upload new service code and download new service state (green arrows).

Composing Services

Service composition is a multi-dimensional problem.

###Tenancy

By establishing conventions about tenancy (leveraging the tenant object as necessary), XOS can also offer a means for one service to be a tenant of another service. Let service A be a “landlord” service that grants tenancies, and let service B be a “tenant” service. Using the generic tenant object and the per-service Syndicate volume, creating a tenancy in A for B is a matter of (1) having A’s developers allow B to request a tenancy, (2) OpenCloud approving the tenancy request on behalf of A, and (3) the XOS observer generating and propagating the tenancy state to B’s VMs simply by serializing and writing them out as read-only files in B’s shared volume (Figure 1).

Step (1) is solved by A’s developers providing other OpenCloud users a Tenant view, as well as the complementary RESTful API for accessing it programmatically (via xoslib). Step (3) is solved using Syndicate.

Step (2) could be addressed using a per-service whitelisting function that lets OpenCloud evaluate whether or not the landlord service (service A) will allow the requesting service (service B) to have a tenancy. To do so, a landlord service (service A) would maintain a set of ACLs that allow/deny groups of tenants, which are evaluated by the whitelisting function and are kept up-to-date by A’s developers via either the developer view or the xoslib RESTful API. Any service-specific policies such as tenant billing are negotiated off-site, out of band. This means that service A could run a separate billing service that processed B’s payments, and then called back to A’s xoslib RESTful API to alter the ACLs to allow B to create tenancies (Figure 2).

Figure 2

Figure 2: Once service A and B have negotiated out-of-band (step 0), service A or some agent of it alters the ACLs in OpenCloud to allow B to request a tenancy (step 1). B then requests the tenancy (2a), and upon verifying with A’s whitelist function, XOS generates a tenancy object representing B’s tenancy in A (2b). Subsequently, XOS serializes the tenancy object into a directory hierarchy which it writes to B’s Syndicate volume (3).

###Specification Language

We need a language for specifying how services compose, which in turn influences (1) how VNs interconnect and (2) the order in which observers run (i.e., create slivers before instantiating a service in that sliver). One option is to adopt a widely adopted data modeling language like yang.

Clone this wiki locally