예제 #1
0
    def run_project(self):
        """Run a project and allocate the necessary resources."""
        def start_container():
            """Start CernVM fork with the proper context."""
            memory_option = "'lxc.cgroup.memory.limit_in_bytes = {0}K'"
            swap_option = "'lxc.cgroup.memory.memsw.limit_in_bytes = {0}K'"
            mount_entry_option = "'lxc.mount.entry = {0}'"
            metafile_option = "'DUMBQ_METAFILE = /{0}'"

            # Basic command configuration
            repos_with_commas = ",".join(project_repos)
            cernvm_fork_command = [
                self.cernvm_fork_bin, container_name,
                "-n", "-d", "-f",
                "--run={0}".format(container_run),
                "--cvmfs={0}".format(repos_with_commas),
                "-o " + memory_option.format(quota_mem),
                "-o " + swap_option.format(quota_swap)
            ]

            # Mount shared mountpoint
            if mount_options:
                cernvm_fork_command.append(
                    "-o " + mount_entry_option.format(mount_options))

            # Share metadata file if exists
            if self.shared_meta_file:
                cernvm_fork_command.append(
                    ("-E " + metafile_option.format(self.guest_meta_file)))

            # Pass configuration environment variables
            for envvar in self.envvars:
                cernvm_fork_command.append(
                    "-E " + "'DUMBQ_{0}'".format(envvar))

            cernvm_fork_command.extend([
                "-E " + "'DUMBQ_NAME={0}'".format(project_name),
                "-E " + "'DUMBQ_UUID={0}'".format(container_uuid),
                "-E " + "'DUMBQ_VMID={0}'".format(self.host_uuid)
            ])

            # Append bind shares
            for bind_share in bind_shares:
                cernvm_fork_command.append(
                    "-o " + mount_entry_option.format(bind_share))

            # Return if container started correctly
            start_message = (self.feedback["starting_project"]
                             .format(container_name))
            self.logger.info(start_message)
            return call(cernvm_fork_command, stdout=DEVNULL) == 0

        def post_start_project():
            """Copy metadata, create runfile, update index and open tty."""
            if self.shared_meta_file:
                path_to_copy = (self.config["guest_mountpoint"]
                                .format(container_name, self.guest_meta_file))
                parent_path = re.sub("[^/]+$", "", path_to_copy)
                os.makedirs(parent_path)
                shutil.copy(self.shared_meta_file, path_to_copy)

            project_info = jsonify(
                uuid=container_uuid,
                wwwroot="/inst-{0}".format(container_name),
                project=project_name,
                memory=quota_mem,
                swap=quota_swap,
                cpus=quota_cpu
            )

            flag_filepath = os.path.join(self.run_dir, container_name)
            safe_write_to_file(flag_filepath, project_info, self.logger.error)

            if self.www_dir:
                self.update_project_stats()

            # Only open tty if the option is enabled
            if self.base_tty > 0:
                self.open_tty(container_name)

            return True

        # Get project to run, quotas and container conf
        project = self.pick_project()
        project_name = project[0]
        project_repos = project[2].split(",")
        project_script = project[3]

        quota_cpu = self.hw_info.slot_cpu
        quota_mem = self.hw_info.slot_mem
        quota_swap = self.hw_info.slot_swap + self.hw_info.slot_mem

        container_uuid = str(uuid4())
        container_name = "{0}-{1}".format(project_name, container_uuid)

        # If testing flag on, use local script
        if self.testing:
            container_run = project_script
        else:
            container_run = "/cvmfs/{0}".format(project_script)

        # Mount WWW dir
        if self.www_dir:
            mountpoint = "{0}/inst-{1}".format(self.www_dir, container_name)
            create_dir_if_nonexistent(mountpoint, mode=0555)
            guest_shared_mount = self.config["guest_shared_mount"]
            mount_options = ("{0} {1} none defaults,bind,user 0 0"
                             .format(mountpoint, guest_shared_mount))

        # Aggregate bind shares with mount options
        bind_shares = []
        for bind_share in self.bind_mount:
            # Get `host, guest` or `host, host`
            hg = bind_share.split("=")
            dir_host = hg[0]
            hg.append(dir_host)
            dir_guest = hg[1]

            rel_path = re.sub("^/?", "", dir_guest)
            mount_options = ("{0} {1} none defaults,bind 0 0"
                             .format(mountpoint, rel_path))
            bind_shares.append(mount_options)

        # Start container, post_start and log any error
        if start_container():
            is_success = post_start_project()
        else:
            cernvm_error = self.feedback["cernvm_error"]
            self.logger.error(cernvm_error)
            is_success = False

        return container_name if is_success else ""
예제 #2
0
    def run_project(self):
        """Run a project and allocate the necessary resources."""
        def start_container():
            """Start CernVM fork with the proper context."""
            memory_option = "'lxc.cgroup.memory.limit_in_bytes = {0}K'"
            swap_option = "'lxc.cgroup.memory.memsw.limit_in_bytes = {0}K'"
            mount_entry_option = "'lxc.mount.entry = {0}'"
            metafile_option = "'DUMBQ_METAFILE = /{0}'"

            # Basic command configuration
            repos_with_commas = ",".join(project_repos)
            cernvm_fork_command = [
                self.cernvm_fork_bin, container_name, "-n", "-d", "-f",
                "--run={0}".format(container_run),
                "--cvmfs={0}".format(repos_with_commas),
                "-o " + memory_option.format(quota_mem),
                "-o " + swap_option.format(quota_swap)
            ]

            # Mount shared mountpoint
            if mount_options:
                cernvm_fork_command.append(
                    "-o " + mount_entry_option.format(mount_options))

            # Share metadata file if exists
            if self.shared_meta_file:
                cernvm_fork_command.append(
                    ("-E " + metafile_option.format(self.guest_meta_file)))

            # Pass configuration environment variables
            for envvar in self.envvars:
                cernvm_fork_command.append("-E " +
                                           "'DUMBQ_{0}'".format(envvar))

            cernvm_fork_command.extend([
                "-E " + "'DUMBQ_NAME={0}'".format(project_name),
                "-E " + "'DUMBQ_UUID={0}'".format(container_uuid),
                "-E " + "'DUMBQ_VMID={0}'".format(self.host_uuid)
            ])

            # Append bind shares
            for bind_share in bind_shares:
                cernvm_fork_command.append(
                    "-o " + mount_entry_option.format(bind_share))

            # Return if container started correctly
            start_message = (
                self.feedback["starting_project"].format(container_name))
            self.logger.info(start_message)
            return call(cernvm_fork_command, stdout=DEVNULL) == 0

        def post_start_project():
            """Copy metadata, create runfile, update index and open tty."""
            if self.shared_meta_file:
                path_to_copy = (self.config["guest_mountpoint"].format(
                    container_name, self.guest_meta_file))
                parent_path = re.sub("[^/]+$", "", path_to_copy)
                os.makedirs(parent_path)
                shutil.copy(self.shared_meta_file, path_to_copy)

            project_info = jsonify(uuid=container_uuid,
                                   wwwroot="/inst-{0}".format(container_name),
                                   project=project_name,
                                   memory=quota_mem,
                                   swap=quota_swap,
                                   cpus=quota_cpu)

            flag_filepath = os.path.join(self.run_dir, container_name)
            safe_write_to_file(flag_filepath, project_info, self.logger.error)

            if self.www_dir:
                self.update_project_stats()

            # Only open tty if the option is enabled
            if self.base_tty > 0:
                self.open_tty(container_name)

            return True

        # Get project to run, quotas and container conf
        project = self.pick_project()
        project_name = project[0]
        project_repos = project[2].split(",")
        project_script = project[3]

        quota_cpu = self.hw_info.slot_cpu
        quota_mem = self.hw_info.slot_mem
        quota_swap = self.hw_info.slot_swap + self.hw_info.slot_mem

        container_uuid = str(uuid4())
        container_name = "{0}-{1}".format(project_name, container_uuid)

        # If testing flag on, use local script
        if self.testing:
            container_run = project_script
        else:
            container_run = "/cvmfs/{0}".format(project_script)

        # Mount WWW dir
        if self.www_dir:
            mountpoint = "{0}/inst-{1}".format(self.www_dir, container_name)
            create_dir_if_nonexistent(mountpoint, mode=0555)
            guest_shared_mount = self.config["guest_shared_mount"]
            mount_options = ("{0} {1} none defaults,bind,user 0 0".format(
                mountpoint, guest_shared_mount))

        # Aggregate bind shares with mount options
        bind_shares = []
        for bind_share in self.bind_mount:
            # Get `host, guest` or `host, host`
            hg = bind_share.split("=")
            dir_host = hg[0]
            hg.append(dir_host)
            dir_guest = hg[1]

            rel_path = re.sub("^/?", "", dir_guest)
            mount_options = ("{0} {1} none defaults,bind 0 0".format(
                mountpoint, rel_path))
            bind_shares.append(mount_options)

        # Start container, post_start and log any error
        if start_container():
            is_success = post_start_project()
        else:
            cernvm_error = self.feedback["cernvm_error"]
            self.logger.error(cernvm_error)
            is_success = False

        return container_name if is_success else ""
예제 #3
0
 def setup_public_www(self):
     """Create public WWW folder and make it readable."""
     if self.config["www_dir"]:
         create_dir_if_nonexistent(self.www_dir, mode=0555)
예제 #4
0
 def setup_public_www(self):
     """Create public WWW folder and make it readable."""
     if self.config["www_dir"]:
         create_dir_if_nonexistent(self.www_dir, mode=0555)