def setUp_job_manager(self):
     self.job_manager = RemoteManualAgentJobManager(
         [{
             "host": "localhost",
             "port": self._get_port()
         }], {"default": "ingi/inginious-c-default"},
         os.path.join(os.path.dirname(__file__),
                      'tasks'), self.course_factory, self.task_factory,
         self.generate_hook_manager(), True)
     self.job_manager.start()
 def setUp_job_manager(self):
     self.job_manager = RemoteManualAgentJobManager([{"host": "localhost", "port": self._get_port()}],
                                                    {"default": "ingi/inginious-c-default"},
                                                    os.path.join(os.path.dirname(__file__), 'tasks'),
                                                    self.course_factory,
                                                    self.task_factory,
                                                    self.generate_hook_manager(),
                                                    True)
     self.job_manager.start()
class TestRemoteJobManager(TestJobManager):
    port = None

    def _get_port(self):
        if not self.port:
            self.port = get_test_port()
        return self.port

    def setUp_job_manager(self):
        self.job_manager = RemoteManualAgentJobManager([{"host": "localhost", "port": self._get_port()}],
                                                       {"default": "ingi/inginious-c-default"},
                                                       os.path.join(os.path.dirname(__file__), 'tasks'),
                                                       self.course_factory,
                                                       self.task_factory,
                                                       self.generate_hook_manager(),
                                                       True)
        self.job_manager.start()

    def generate_hook_manager(self):
        return None
class TestRemoteJobManager(TestJobManager):
    port = None

    def _get_port(self):
        if not self.port:
            self.port = get_test_port()
        return self.port

    def setUp_job_manager(self):
        self.job_manager = RemoteManualAgentJobManager(
            [{
                "host": "localhost",
                "port": self._get_port()
            }], {"default": "ingi/inginious-c-default"},
            os.path.join(os.path.dirname(__file__),
                         'tasks'), self.course_factory, self.task_factory,
            self.generate_hook_manager(), True)
        self.job_manager.start()

    def generate_hook_manager(self):
        return None
def create_job_manager(configuration,
                       plugin_manager,
                       task_directory,
                       course_factory,
                       task_factory,
                       is_testing=False):
    """ Creates a new inginious.backend job manager from the configuration """

    # Create the job manager
    backend_type = configuration.get("backend", "local")
    if backend_type == "local":
        return LocalJobManager(
            configuration.get(
                'containers', {
                    "default": "ingi/inginious-c-default",
                    "sekexe": "ingi/inginious-c-sekexe"
                }), task_directory, course_factory, task_factory,
            configuration.get('local_agent_tmp_dir', "/tmp/inginious_agent"),
            plugin_manager, is_testing)
    elif backend_type == "remote":
        return RemoteDockerJobManager(
            configuration.get("docker_daemons", []),
            configuration.get(
                'containers', {
                    "default": "ingi/inginious-c-default",
                    "sekexe": "ingi/inginious-c-sekexe"
                }), task_directory, course_factory, task_factory,
            plugin_manager, is_testing)
    elif backend_type == "remote_manual":
        return RemoteManualAgentJobManager(
            configuration.get("agents", [{
                "host": "localhost",
                "port": 5001
            }]),
            configuration.get(
                'containers', {
                    "default": "ingi/inginious-c-default",
                    "sekexe": "ingi/inginious-c-sekexe"
                }), task_directory, course_factory, task_factory,
            plugin_manager, is_testing)
    elif backend_type == "docker_machine":
        return DockerMachineJobManager(
            configuration.get("machines", []),
            configuration.get(
                'containers', {
                    "default": "ingi/inginious-c-default",
                    "sekexe": "ingi/inginious-c-sekexe"
                }), task_directory, course_factory, task_factory,
            plugin_manager, is_testing)
    else:
        raise Exception("Unknown inginious.backend {}".format(backend_type))
Beispiel #6
0
    def __init__(
        self,
        docker_daemons,
        image_aliases,
        task_directory,
        course_factory,
        task_factory,
        hook_manager=None,
        is_testing=False,
    ):
        """
            Starts the job manager.

            :param docker_daemons:
                a list of dict representing docker daemons.

                { "remote_host": "192.168.59.103" ## host of the docker daemon *from the webapp*
                  "remote_docker_port": 2375      ## port of the distant docker daemon *from the webapp*
                  "remote_agent_port": 63456      ## a mandatory port used by the inginious.backend and the agent that will be automatically started.
                                                  ## Needs to be available on the remote host, and to be open in the firewall.

                  ## Optionnal. Enable remote container debugging via SSH.
                  ## The port needs to be available on the remote host, and to be open in the firewall.
                  #"remote_agent_ssh_port": 63457,

                  ##does the docker daemon requires tls? Defaults to false
                  ##parameter can be set to true or path to the certificates
                  #use_tls: false

                  ##link to the docker daemon *from the host that runs the docker daemon*. Defaults to:
                  #"local_location": "unix:///var/run/docker.sock"

                  ##path to the cgroups "mount" *from the host that runs the docker daemon*. Defaults to:
                  #"cgroups_location": "/sys/fs/cgroup"

                  ##name that will be used to reference the agent
                  #"agent_name": "inginious-agent"
                }
            :param task_directory: the task directory
            :param course_factory: a CourseFactory object
            :param task_factory: a TaskFactory object, possibly with specific task files managers attached
            :param image_aliases: a dict of image aliases, like {"default": "ingi/inginious-c-default"}.
            :param hook_manager: An instance of HookManager. If no instance is given(None), a new one will be created.
        """
        agents = []

        for daemon in docker_daemons:
            if daemon.get("use_tls", False):
                if isinstance(daemon["use_tls"], basestring):
                    tls_config = docker.tls.TLSConfig(
                        client_cert=(daemon["use_tls"] + "/cert.pem", daemon["use_tls"] + "/key.pem"),
                        verify=daemon["use_tls"] + "/ca.pem",
                    )
                else:
                    tls_config = True
                docker_connection = docker.Client(
                    base_url="https://" + daemon["remote_host"] + ":" + str(int(daemon["remote_docker_port"])),
                    tls=tls_config,
                )
            else:
                docker_connection = docker.Client(
                    base_url="http://" + daemon["remote_host"] + ":" + str(int(daemon["remote_docker_port"])), tls=False
                )

            agent_name = daemon.get("agent_name", "inginious-agent")

            # Verify if the container is available and at the right version
            if not self.is_agent_valid_and_started(docker_connection, agent_name):

                # Verify that the image ingi/inginious-agent exists and is up-to-date
                if self.is_agent_image_update_needed(docker_connection):
                    print "Pulling the image ingi/inginious-agent. Please wait, this can take some time..."
                    for line in docker_connection.pull("ingi/inginious-agent", stream=True):
                        print line

                    # Verify again that the image is ok
                    if self.is_agent_image_update_needed(docker_connection):
                        raise Exception(
                            "The downloaded image ingi/inginious-agent is not at the same version as this instance of INGInious. "
                            "Please update  INGInious or pull manually a valid version of the container image ingi/inginious-agent."
                        )

                docker_local_location = daemon.get("local_location", "unix:///var/run/docker.sock")
                environment = {
                    "AGENT_CONTAINER_NAME": agent_name,
                    "AGENT_PORT": daemon.get("remote_agent_port", 63456),
                    "AGENT_SSH_PORT": daemon.get("remote_agent_ssh_port", ""),
                }
                volumes = {"/sys/fs/cgroup/": {}}
                binds = {daemon.get("cgroups_location", "/sys/fs/cgroup"): {"ro": False, "bind": "/sys/fs/cgroup"}}

                if docker_local_location.startswith("unix://"):
                    volumes["/var/run/docker.sock"] = {}
                    binds[docker_local_location[7:]] = {"ro": False, "bind": "/var/run/docker.sock"}
                    environment["DOCKER_HOST"] = "unix:///var/run/docker.sock"
                elif docker_local_location.startswith("tcp://"):
                    environment["DOCKER_HOST"] = docker_local_location
                    if daemon.get("use_tls", False):
                        environment["DOCKER_TLS_VERIFY"] = "on"
                else:
                    raise Exception("Unknown protocol for local docker daemon: " + docker_local_location)

                response = docker_connection.create_container(
                    "ingi/inginious-agent", environment=environment, detach=True, name=agent_name, volumes=volumes
                )
                container_id = response["Id"]

                # Start the container
                docker_connection.start(
                    container_id, network_mode="host", binds=binds, restart_policy={"Name": "always"}
                )

            agents.append(
                {
                    "host": daemon["remote_host"],
                    "port": daemon.get("remote_agent_port", 63456),
                    "ssh_port": daemon.get("remote_agent_ssh_port"),
                }
            )

        RemoteManualAgentJobManager.__init__(
            self, agents, image_aliases, task_directory, course_factory, task_factory, hook_manager, is_testing
        )