コード例 #1
0
  def _FillInExecutableFromApp(self, wrapper, app):
    """Fill in the fields of a SandboxSpec.Executable object from |app|.

    Args:
      wrapper: instance of SandboxSpecWrapper.
      app: dictionary of information taken from the appc pod manifest.
    """
    sub_app = json_lib.GetValueOfType(
        app, KEY_APP_SUB_APP, dict, 'per app app dict')
    user = json_lib.GetValueOfType(
        sub_app, KEY_SUB_APP_USER, unicode, 'app dict user')
    group = json_lib.GetValueOfType(
        sub_app, KEY_SUB_APP_GROUP, unicode, 'app dict group')

    if not self._user_db.UserExists(user):
      raise ValueError('Found invalid username "%s"' % user)
    if not self._user_db.GroupExists(group):
      raise ValueError('Found invalid groupname "%s"' % group)

    cmd = json_lib.GetValueOfType(
        sub_app, KEY_SUB_APP_EXEC, list, 'app command line')
    if not cmd:
      raise ValueError('App command line must give the executable to run.')
    self._CheckAbsPathToExecutable(cmd[0])
    for cmd_piece in cmd:
      json_lib.AssertIsInstance(cmd_piece, unicode, 'app.exec fragment')

    port_list = sub_app.get(KEY_SUB_APP_PORTS, None)
    wrapper.AddExecutable(self._user_db.ResolveUsername(user),
                          self._user_db.ResolveGroupname(group),
                          cmd,
                          _GetPortList(PROTOCOL_TCP, port_list),
                          _GetPortList(PROTOCOL_UDP, port_list),
                          _ExtractLinuxCapNames(sub_app))
コード例 #2
0
  def _FillInEndpointNamesFromAnnotations(self, wrapper, annotations):
    """Fill in the SandboxSpec endpoint_names field from |annotations|.

    An appc pod specification can contain a list of (mostly) arbitrary
    annotations that projects can use to add their own metadata fields.
    |annotations| is a list of dicts that each contain a name and value field,
    and this method looks for 'name' fields that are prefixed with
    ENDPOINT_NAME_ANNOTATION_PREFIX and treats the associated 'value' as the
    name of an endpoint that psyched will expect to be registered from within
    this sandbox.

    Args:
      wrapper: instance of SandboxSpecWrapper.
      annotations: list of dicts, each with a name and value field.
    """
    for annotation in annotations:
      json_lib.AssertIsInstance(annotation, dict, 'a single annotation')
      name = json_lib.GetValueOfType(
          annotation, KEY_ANNOTATION_NAME, unicode, 'annotation name')
      if not IsValidAcName(name):
        raise ValueError('Annotation name "%s" contains illegal characters.' %
                         name)
      if name.startswith(ENDPOINT_NAME_ANNOTATION_PREFIX):
        endpoint_name = json_lib.GetValueOfType(
            annotation, KEY_ANNOTATION_VALUE, unicode, 'endpoint name value')
        if not IsValidAcName(name):
          raise ValueError('Endpoint name "%s" contains illegal characters.' %
                           endpoint_name)
        wrapper.AddEndpointName(endpoint_name)
コード例 #3
0
  def GetSandboxSpec(self, appc_contents, sandbox_spec_name):
    """Create a SandboxSpec encoding the information in an appc pod manifest.

    Args:
      appc_contents: string contents of an appc pod manifest
      sandbox_spec_name: string unique name of this sandbox.

    Returns:
      an instance of SandboxSpec.
    """
    wrapper = SandboxSpecWrapper()
    overlay_name = None

    app_list = json_lib.GetValueOfType(
        appc_contents, KEY_APPS_LIST, list, 'app list')
    for app in app_list:
      json_lib.AssertIsInstance(app, dict, 'app')

      # Aid debugging of problems in specific apps.
      app_name = json_lib.GetValueOfType(
          app, KEY_APP_NAME, unicode, 'app name')
      if not IsValidAcName(app_name):
        raise ValueError('Application name "%s" contains illegal characters.' %
                         app_name)
      logging.debug('Processing application "%s".', app_name)

      # Get the name of the image, check that it's consistent other image names.
      image = json_lib.GetValueOfType(
          app, KEY_APP_IMAGE, dict, 'image specification for app')
      image_name = json_lib.GetValueOfType(
          image, KEY_APP_IMAGE_NAME, unicode, 'image name')
      if not IsValidAcName(image_name):
        raise ValueError('Image name "%s" contains illegal characters.' %
                         image_name)

      if overlay_name and overlay_name != image_name:
        raise ValueError(
            'All elements of "apps" must have the same image.name.')
      overlay_name = image_name

      # Add the executable corresponding to this app to our SandboxSpec.
      self._FillInExecutableFromApp(wrapper, app)

    if not overlay_name:
      raise ValueError('Overlays must declare at least one app')

    annotation_list = json_lib.GetValueOfType(
        appc_contents, KEY_ANNOTATIONS_LIST, list, 'list of all annotations')
    self._FillInEndpointNamesFromAnnotations(wrapper, annotation_list)

    wrapper.SetName(sandbox_spec_name)
    return wrapper.sandbox_spec
コード例 #4
0
def _ExtractLinuxCapNames(app_dict):
  """Parses the set of Linux capabilities for an executable.

  Args:
    app_dict: dictionary defining an executable.

  Returns:
    List of names of Linux capabilities (e.g. ['CAP_CHOWN']).
  """
  if KEY_APP_ISOLATORS not in app_dict:
    return []

  isolator_list = json_lib.GetValueOfType(
      app_dict, KEY_APP_ISOLATORS, list,
      'list of isolators for application')
  linux_cap_isolators = []

  # Look for any isolators related to capability sets.
  for isolator in isolator_list:
    json_lib.AssertIsInstance(isolator, dict, 'isolator instance')
    isolator_name = json_lib.GetValueOfType(
        isolator, ISOLATOR_KEY_NAME, unicode, 'isolator name')
    if not isolator_name.startswith(ISOLATOR_NAME_PREFIX):
      continue
    if isolator_name != ISOLATOR_NAME_RETAIN_SET:
      raise ValueError('Capabilities may only be specified as %s' %
                       ISOLATOR_NAME_RETAIN_SET)
    linux_cap_isolators.append(isolator)

  # We may have only a single isolator.
  if len(linux_cap_isolators) > 1:
    raise ValueError('Found two lists of Linux caps for an executable')
  if not linux_cap_isolators:
    return []

  value = json_lib.GetValueOfType(
      linux_cap_isolators[0], ISOLATOR_KEY_VALUE, dict,
      'Linux cap isolator value')
  caps = json_lib.GetValueOfType(
      value, ISOLATOR_KEY_VALUE_SET, list, 'Linux cap isolator set')
  for cap in caps:
    json_lib.AssertIsInstance(cap, unicode, 'Linux capability in set.')

  return caps
コード例 #5
0
 def testPopValueOfType(self):
   """Test that PopValueOfType is correct."""
   input_dict = {'key': 'value'}
   self.assertEqual(
       'value',
       json_lib.GetValueOfType(input_dict, 'key', str, 'value'))
   self.assertEqual(
       'value',
       json_lib.PopValueOfType(input_dict, 'key', str, 'value'))
   self.assertFalse(input_dict)
コード例 #6
0
 def testGetValueOfType(self):
   """Test that GetValueOfType is correct."""
   self.assertRaises(
       ValueError, json_lib.GetValueOfType,
       {}, 'missing key', str, 'missing value')
   self.assertRaises(
       ValueError, json_lib.GetValueOfType,
       {'key': 1}, 'key', bool, 'bad type')
   self.assertRaises(
       ValueError, json_lib.GetValueOfType,
       {'key': [1]}, 'key', int, 'bad type')
   self.assertEqual(
       json_lib.GetValueOfType({'key': 1}, 'key', int, 'good value'),
       1)