Exemplo n.º 1
0
 async def create_container(self, data):
     status, contr, err = Container.parse(data)
     if status != 200:
         return status, None, err
     status, _, _ = await self.__contr_db.get_container(
         contr.appliance, contr.id)
     if status == 200:
         return 409, None, "Container '%s' already exists" % contr.id
     await self.save_container(contr, True)
     return 201, contr, None
Exemplo n.º 2
0
 async def get_containers(self, **filters):
     return [
         Container.parse(c, False)[1]
         async for c in self.__contr_col.find(filters)
     ]
Exemplo n.º 3
0
 async def _get_container(self, **filters):
     contr = await self.__contr_col.find_one(filters)
     if not contr:
         return 404, None, "Container matching '%s' is not found" % filters
     return Container.parse(contr, False)
Exemplo n.º 4
0
  def parse(cls, data, from_user=True):

    def validate_dependencies(contrs):
      contrs = {c.id: c for c in contrs}
      parents = {}
      for c in contrs.values():
        nonexist = list(filter(lambda c: c not in contrs, c.dependencies))
        if nonexist:
          return 422, None, "Dependencies '%s' do not exist in this appliance" % nonexist
      parents.setdefault(c.id, set()).update(c.dependencies)
      for c, p in parents.items():
        cycles = ['%s<->%s' % (c, pp)
                  for pp in filter(lambda x: c in parents.get(x, set()), p)]
        if cycles:
          return 422, None, "Cycle(s) found: %s" % cycles
      return 200, 'Dependencies are valid', None

    if not isinstance(data, dict):
      return 422, None, "Failed to parse appliance request format: %s"%type(data)
    missing = Appliance.REQUIRED - data.keys()
    if missing:
      return 400, None, "Missing required field(s) of appliance: %s"%missing
    fields = {}
    # instantiate container objects
    containers, contr_ids = [], set()
    for c in data.pop('containers', []):
      if c['id'] in contr_ids:
        return 400, None, "Duplicate container id: %s"%c['id']
      if from_user:
        for unwanted_f in ('appliance', ):
          c.pop(unwanted_f, None)
      status, contr, err = Container.parse(dict(**c, appliance=data['id']), from_user)
      if status != 200:
        return status, None, err
      containers.append(contr)
      contr_ids.add(contr.id)
    addresses = set()
    for c in containers:
      if c.cmd:
        addresses.update(get_short_ids(c.cmd))
      for arg in c.args:
        addresses.update(get_short_ids(arg))
      for v in c.env.values():
        addresses.update(get_short_ids(v))
    undefined = list(addresses - contr_ids)
    if undefined:
      return 400, None, "Undefined container(s): %s"%undefined
    status, msg, err = validate_dependencies(containers)
    if status != 200:
      return status, None, err
    fields.update(containers=containers)

    # instantiate data persistence object
    if 'data_persistence' in data:
      status, dp, err = DataPersistence.parse(dict(**data.pop('data_persistence', {}),
                                                   appliance=data['id']), from_user)
      if status != 200:
        return status, None, err
      fields.update(data_persistence=dp)

    # instantiate scheduler object
    if 'scheduler' in data:
      status, scheduler, err = Scheduler.parse(data.pop('scheduler', {}), from_user)
      if status != 200:
        return status, None, err
      fields.update(scheduler=scheduler)

    return 200, Appliance(**fields, **data), None