예제 #1
0
    def get_target_info(self, run_state, path, dep_paths, args, reply_fn):
        """
        Return target_info of path in bundle as a message on the reply_fn
        """
        bundle_uuid = run_state.bundle['uuid']
        target_info = None

        # if path is a dependency raise an error
        if path and os.path.normpath(path) in dep_paths:
            err = (http.client.NOT_FOUND,
                   '{} not found in bundle {}'.format(path, bundle_uuid))
            reply_fn(err, None, None)
            return
        else:
            try:
                target_info = download_util.get_target_info(
                    run_state.bundle_path, bundle_uuid, path, args['depth'])
            except PathException as e:
                err = (http.client.NOT_FOUND, str(e))
                reply_fn(err, None, None)
                return

        if not path and args['depth'] > 0:
            target_info['contents'] = [
                child for child in target_info['contents']
                if child['name'] not in dep_paths
            ]

        reply_fn(None, {'target_info': target_info}, None)
예제 #2
0
    def get_target_info(self, run_state, path, args, reply_fn):
        """
        Return target_info of path in bundle as a message on the reply_fn
        """
        target_info = None
        dep_paths = set([dep.child_path for dep in run_state.bundle.dependencies])

        # if path is a dependency raise an error
        if path and os.path.normpath(path) in dep_paths:
            err = (
                http.client.NOT_FOUND,
                '{} not found in bundle {}'.format(path, run_state.bundle.uuid),
            )
            reply_fn(err, None, None)
            return
        else:
            try:
                target_info = download_util.get_target_info(
                    run_state.bundle_path, BundleTarget(run_state.bundle.uuid, path), args['depth']
                )
            except PathException as e:
                err = (http.client.NOT_FOUND, str(e))
                reply_fn(err, None, None)
                return

        if not path and args['depth'] > 0:
            target_info['contents'] = [
                child for child in target_info['contents'] if child['name'] not in dep_paths
            ]
        # Object is not JSON serializable so submit its dict in API response
        # The client is responsible for deserializing it
        target_info['resolved_target'] = target_info['resolved_target'].__dict__
        reply_fn(None, {'target_info': target_info}, None)
예제 #3
0
 def test_single_file(self):
     """Test getting target info of a single file (compressed as .gz) on Azure Blob Storage."""
     bundle_uuid, bundle_path = self.create_file(b"a")
     target_info = get_target_info(bundle_path, BundleTarget(bundle_uuid, None), 0)
     target_info.pop("resolved_target")
     self.assertEqual(
         target_info, {'name': bundle_uuid, 'type': 'file', 'size': 1, 'perm': 0o755}
     )
 def _get_target_info_within_bundle(self, target, depth):
     """
     Helper for get_target_info that only checks for the target info within that bundle
     without considering the path might be pointing to one of the dependencies.
     Raises NotFoundError if the path is not found.
     """
     bundle_state = self._bundle_model.get_bundle_state(target.bundle_uuid)
     bundle_link_url = self._bundle_model.get_bundle_metadata(
         [target.bundle_uuid], "link_url").get(target.bundle_uuid)
     if bundle_link_url:
         bundle_link_url = self._transform_link_path(bundle_link_url)
     # Raises NotFoundException if uuid is invalid
     if bundle_state == State.PREPARING:
         raise NotFoundError(
             "Bundle {} hasn't started running yet, files not available".
             format(target.bundle_uuid))
     elif bundle_state != State.RUNNING:
         bundle_path = bundle_link_url or self._bundle_store.get_bundle_location(
             target.bundle_uuid)
         try:
             return download_util.get_target_info(bundle_path, target,
                                                  depth)
         except download_util.PathException as err:
             raise NotFoundError(str(err))
     else:
         # get_target_info calls are sent to the worker even on a shared file
         # system since 1) due to NFS caching the worker has more up to date
         # information on directory contents, and 2) the logic of hiding
         # the dependency paths doesn't need to be re-implemented here.
         worker = self._bundle_model.get_bundle_worker(target.bundle_uuid)
         response_socket_id = self._worker_model.allocate_socket(
             worker['user_id'], worker['worker_id'])
         try:
             read_args = {'type': 'get_target_info', 'depth': depth}
             self._send_read_message(worker, response_socket_id, target,
                                     read_args)
             with closing(
                     self._worker_model.start_listening(
                         response_socket_id)) as sock:
                 result = self._worker_model.get_json_message(sock, 60)
             if result is None:  # dead workers are a fact of life now
                 logging.info(
                     'Unable to reach worker, bundle state {}'.format(
                         bundle_state))
                 raise NotFoundError(
                     'Unable to reach worker of running bundle with bundle state {}'
                     .format(bundle_state))
             elif 'error_code' in result:
                 raise http_error_to_exception(result['error_code'],
                                               result['error_message'])
             target_info = result['target_info']
             # Deserialize dict response sent over JSON
             target_info[
                 'resolved_target'] = download_util.BundleTarget.from_dict(
                     target_info['resolved_target'])
             return target_info
         finally:
             self._worker_model.deallocate_socket(response_socket_id)
예제 #5
0
    def get_target_info(self, uuid, path, depth):
        """
        Returns information about an individual target inside the bundle,
        Raises NotFoundError if the bundle or the path within the bundle is not found

        For information about the format of the return value, see
        worker.download_util.get_target_info.
        """
        bundle_state = self._bundle_model.get_bundle_state(uuid)
        # Raises NotFoundException if uuid is invalid

        if bundle_state == State.PREPARING:
            raise NotFoundError(
                "Bundle {} hasn't started running yet, files not available".
                format(uuid))
        elif bundle_state != State.RUNNING:
            bundle_path = self._bundle_store.get_bundle_location(uuid)
            try:
                return download_util.get_target_info(bundle_path, uuid, path,
                                                     depth)
            except download_util.PathException as e:
                raise NotFoundError(str(e))
        else:
            # get_target_info calls are sent to the worker even on a shared file
            # system since 1) due to NFS caching the worker has more up to date
            # information on directory contents, and 2) the logic of hiding
            # the dependency paths doesn't need to be re-implemented here.
            worker = self._worker_model.get_bundle_worker(uuid)
            response_socket_id = self._worker_model.allocate_socket(
                worker['user_id'], worker['worker_id'])
            try:
                read_args = {'type': 'get_target_info', 'depth': depth}
                self._send_read_message(worker, response_socket_id, uuid, path,
                                        read_args)
                with closing(
                        self._worker_model.start_listening(
                            response_socket_id)) as sock:
                    result = self._worker_model.get_json_message(sock, 60)
                if result is None:  # dead workers are a fact of life now
                    logging.info(
                        'Unable to reach worker, bundle state {}'.format(
                            bundle_state))
                    raise NotFoundError(
                        'Unable to reach worker of running bundle with bundle state {}'
                        .format(bundle_state))
                elif 'error_code' in result:
                    raise http_error_to_exception(result['error_code'],
                                                  result['error_message'])
                return result['target_info']
            finally:
                self._worker_model.deallocate_socket(response_socket_id)
예제 #6
0
    def test_nested_directories(self):
        """Test getting target info of different files within a bundle that consists of nested directories, on Azure Blob Storage."""
        bundle_uuid, bundle_path = self.create_directory()

        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, None), 0)
        target_info.pop("resolved_target")
        self.assertEqual(target_info, {
            'name': bundle_uuid,
            'type': 'directory',
            'size': 249,
            'perm': 0o755
        })

        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, None), 1)
        target_info.pop("resolved_target")
        self.assertEqual(
            target_info,
            {
                'name':
                bundle_uuid,
                'type':
                'directory',
                'size':
                249,
                'perm':
                0o755,
                'contents': [
                    {
                        'name': 'README.md',
                        'type': 'file',
                        'size': 11,
                        'perm': 0o644
                    },
                    {
                        'name': 'dist',
                        'type': 'directory',
                        'size': 0,
                        'perm': 0o644
                    },
                    {
                        'name': 'src',
                        'type': 'directory',
                        'size': 0,
                        'perm': 0o644
                    },
                ],
            },
        )

        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, "README.md"),
                                      1)
        target_info.pop("resolved_target")
        self.assertEqual(target_info, {
            'name': 'README.md',
            'type': 'file',
            'size': 11,
            'perm': 0o644
        })

        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, "src/test.sh"),
                                      1)
        target_info.pop("resolved_target")
        self.assertEqual(target_info, {
            'name': 'test.sh',
            'type': 'file',
            'size': 7,
            'perm': 0o644
        })

        target_info = get_target_info(
            bundle_path, BundleTarget(bundle_uuid, "dist/a/b/test2.sh"), 1)
        target_info.pop("resolved_target")
        self.assertEqual(target_info, {
            'name': 'test2.sh',
            'type': 'file',
            'size': 8,
            'perm': 0o644
        })

        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, "src"), 1)
        target_info.pop("resolved_target")
        self.assertEqual(
            target_info,
            {
                'name':
                'src',
                'type':
                'directory',
                'size':
                0,
                'perm':
                0o644,
                'contents': [{
                    'name': 'test.sh',
                    'type': 'file',
                    'size': 7,
                    'perm': 0o644
                }],
            },
        )

        # Return all depths
        target_info = get_target_info(bundle_path,
                                      BundleTarget(bundle_uuid, "dist/a"), 999)
        target_info.pop("resolved_target")

        self.assertEqual(
            target_info,
            {
                'name':
                'a',
                'size':
                0,
                'perm':
                0o644,
                'type':
                'directory',
                'contents': [{
                    'name':
                    'b',
                    'size':
                    0,
                    'perm':
                    0o644,
                    'type':
                    'directory',
                    'contents': [{
                        'name': 'test2.sh',
                        'size': 8,
                        'perm': 0o644,
                        'type': 'file'
                    }],
                }],
            },
        )
예제 #7
0
 def test_single_txt_file(self):
     """Test getting target info of a single txt file on Azure Blob Storage. As this isn't supported
     (paths should be specified within existing .gz / .tar.gz files), this should throw an exception."""
     bundle_uuid, bundle_path = self.create_txt_file(b"a")
     with self.assertRaises(PathException):
         get_target_info(bundle_path, BundleTarget(bundle_uuid, None), 0)