Exemple #1
0
    def _handle_configure(self, id_, image):
        """Configure the image (spin it up, let the user muck around in it, commit all changes
        back into the original image)
        """
        child_snapshots = master.models.Image.objects(base_image=image.id)
        if len(child_snapshots) > 0:
            self._log.warn("ERROR! ILLEGAL OPERATION! I WILL NOT MODIFY AN IMAGE WITH {} DEPENDENT SNAPSHOTS!".format(
                len(child_snapshots)
            ))
            image.status = {"name": "ready"}
            return

        vagrantfile = image.status.setdefault("vagrantfile", None)
        user_interaction = image.status.setdefault("user_interaction", False)

        vnc_info = self._vm_manager.configure_image(
            str(image.id),
            vagrantfile            = vagrantfile,
            user_interaction    = user_interaction,
            on_success            = self._set_image_ready,
            kvm                    = image.status["kvm"]
        )
        self._log.debug("got vnc info from configure image: {!r}".format(vnc_info))

        from master import Master
        Master.instance().update_status(vms=self._get_running_vms())

        image = master.models.Image.objects(id=image.id)[0]
        if user_interaction:
            image.status = {
                "name": "configuring",
                "vnc": vnc_info
            }
            image.save()
Exemple #2
0
    def _handle_create(self, id_, image):
        """Handle creating a new VM based on an existing VM
        """
        self._log.info("creating an image")

        base = image.base_image
        dest_name = image.name
        vagrantfile = image.status.setdefault("vagrantfile", None)
        user_interaction = image.status.setdefault("user_interaction", False)

        vnc_info = self._vm_manager.create_image(
            vagrantfile,
            base_name            = str(base.id),
            dest_name            = str(image.id),
            user_interaction    = user_interaction,
            on_success            = self._set_image_ready
        )

        from master import Master
        Master.instance().update_status(vms=self._get_running_vms())

        image = master.models.Image.objects(id=image.id)[0]
        if user_interaction:
            image.status = {
                "name": "configuring",
                "vnc": vnc_info
            }
            image.save()
Exemple #3
0
    def stop_job(self, job):
        """This is intended to be called once a job has been completed
		(not cancelled, but completed)
		"""
        self._log.info("stopping job: {}".format(job.id))

        if str(job.id) in self._job_handlers:
            with self._job_queue_lock:
                handler = self._job_handlers[str(job.id)]
                queue = self._job_amqp_queues[handler.queue_name]

                new_queue = []
                for priority, handler in queue.queue:
                    if handler.job.id == job.id:
                        continue
                    new_queue.append((priority, handler))

                queue.queue = new_queue

                Master.instance().update_status(queues=self._get_queues())

        AmqpManager.instance().queue_msg(json.dumps(
            dict(type="cancel", job=str(job.id))),
                                         "",
                                         exchange=Master.AMQP_BROADCAST_XCHG)

        job.reload()
        job.status = {"name": "finished"}
        job.timestamps["finished"] = time.time()
        job.save()

        self._log.info("stopped job: {}".format(job.id))

        self._cleanup_job(job)
Exemple #4
0
	def run_job(self, job):
		"""TODO: Docstring for run_job.

		:job: TODO
		:returns: TODO
		"""
		self._log.info("running job: {}".format(job.id))

		job.priority = self._safe_priority(job.priority)
		job.save()

		queue = job.queue
		if queue is None or queue == "":
			queue = self.AMQP_JOB_QUEUE

		handler = JobHandler(job, queue, self)
		self._job_handlers[str(job.id)] = handler

		with self._job_queue_lock:
			job_priority_queue = self._job_amqp_queues.setdefault(queue, PQ())
			# items are fetched by lowest priority value first, so we need to
			# invert the priorities
			job_priority_queue.put(((1000-job.priority), handler))

			Master.instance().update_status(queues=self._get_queues())
Exemple #5
0
    def run_job(self, job):
        """TODO: Docstring for run_job.

		:job: TODO
		:returns: TODO
		"""
        self._log.info("running job: {}".format(job.id))

        job.priority = self._safe_priority(job.priority)
        job.save()

        queue = job.queue
        if queue is None or queue == "":
            queue = self.AMQP_JOB_QUEUE

        handler = JobHandler(job, queue, self)
        self._job_handlers[str(job.id)] = handler

        with self._job_queue_lock:
            job_priority_queue = self._job_amqp_queues.setdefault(queue, PQ())
            # items are fetched by lowest priority value first, so we need to
            # invert the priorities
            job_priority_queue.put(((1000 - job.priority), handler))

            Master.instance().update_status(queues=self._get_queues())
Exemple #6
0
	def _handle_configure(self, id_, image):
		"""Configure the image (spin it up, let the user muck around in it, commit all changes
		back into the original image)
		"""
		vagrantfile = image.status.setdefault("vagrantfile", None)
		user_interaction = image.status.setdefault("user_interaction", False)

		vnc_info = self._vm_manager.configure_image(
			str(image.id),
			vagrantfile			= vagrantfile,
			user_interaction	= user_interaction,
			on_success			= self._set_image_ready,
			kvm					= image.status["kvm"]
		)
		self._log.debug("got vnc info from configure image: {!r}".format(vnc_info))

		from master import Master
		Master.instance().update_status(vms=self._get_running_vms())

		image = master.models.Image.objects(id=image.id)[0]
		if user_interaction:
			image.status = {
				"name": "configuring",
				"vnc": vnc_info
			}
			image.save()
Exemple #7
0
    def _handle_iso_create(self, id_, image):
        """Handle creating a new VM from scratch using the iso provided in
        the state object.
        """
        self._log.info("creating new image using iso")

        iso_id = bson.ObjectId(image.status["iso"])
        iso_file = master.models.TmpFile.objects(id=iso_id)[0]

        if iso_file.path.startswith("/"):
            iso_file.path = iso_file.path[1:]

        iso_path = os.path.join("/tmp/talus", iso_file.path)
        if not os.path.exists(iso_path):
            self._log.warn("cannot locate iso {!r} for image {!r} creation".format(
                iso_file.path,
                image.name,
            ))
            iso_file.delete()
            image.status = {
                "name": "iso-create error",
            }
            image.save()
            return

        vnc_info = self._vm_manager.create_from_iso(
            iso_path    = iso_path,
            #vagrantfile = image.status.setdefault("vagrantfile", None),
            image_name  = str(image.id),
            username    = image.username,
            password    = image.password,
            on_success  = self._set_image_ready,
        )

        from master import Master
        Master.instance().update_status(vms=self._get_running_vms())

        if os.path.exists(iso_file.path):
            os.remove(iso_file.path)
        iso_file.delete()

        image.status = {
            "name": "configuring",
            "vnc": vnc_info,
        }
        image.save()

        self._log.info("new VM is starting up with iso {!r}, ready for initial configuration\n    {!r}".format(
            os.path.basename(iso_path),
            vnc_info,
        ))
Exemple #8
0
	def cancel_job(self, job):
		"""Cancel the job ``job``

		:job: The job object to cancel
		:returns: None

		"""
		# TODO forcefully cancel the job (notify all slaves via amqp that
		# this job.id needs to be forcefully cancelled
		self._log.info("cancelling job: {}".format(job.id))

		if str(job.id) in self._job_handlers:
			with self._job_queue_lock:
				handler = self._job_handlers[str(job.id)]
				queue = self._job_amqp_queues[handler.queue_name]

				new_queue = []
				while queue.qsize() > 0:
					priority,handler = queue.get()
					# leave this one out (the one we're cancelling)
					if handler.job.id == job.id:
						continue
					new_queue.append((priority, handler))

				for item in new_queue:
					queue.put(item)

				Master.instance().update_status(queues=self._get_queues())
		else:
			self._log.debug("job to cancel ({}) not in job handlers, sending cancel message to amqp anyways".format(job.id))

		AmqpManager.instance().queue_msg(
			json.dumps(dict(
				type	= "cancel",
				job		= str(job.id)
			)),
			"",
			exchange=Master.AMQP_BROADCAST_XCHG
		)

		job.reload()
		job.status = {
			"name": "cancelled"
		}
		job.timestamps["cancelled"] = time.time()
		job.save()

		self._log.info("cancelled job: {}".format(job.id))

		self._cleanup_job(job)
Exemple #9
0
	def cancel_job(self, job):
		"""Cancel the job ``job``

		:job: The job object to cancel
		:returns: None

		"""
		# TODO forcefully cancel the job (notify all slaves via amqp that
		# this job.id needs to be forcefully cancelled
		self._log.info("cancelling job: {}".format(job.id))

		if str(job.id) in self._job_handlers:
			with self._job_queue_lock:
				handler = self._job_handlers[str(job.id)]
				queue = self._job_amqp_queues[handler.queue_name]

				new_queue = []
				while queue.qsize() > 0:
					priority,handler = queue.get()
					# leave this one out (the one we're cancelling)
					if handler.job.id == job.id:
						continue
					new_queue.append((priority, handler))

				for item in new_queue:
					queue.put(item)

				Master.instance().update_status(queues=self._get_queues())
		else:
			self._log.debug("job to cancel ({}) not in job handlers, sending cancel message to amqp anyways".format(job.id))

		AmqpManager.instance().queue_msg(
			json.dumps(dict(
				type	= "cancel",
				job		= str(job.id)
			)),
			"",
			exchange=Master.AMQP_BROADCAST_XCHG
		)

		job.reload()
		job.status = {
			"name": "cancelled"
		}
		job.timestamps["cancelled"] = time.time()
		job.save()

		self._log.info("cancelled job: {}".format(job.id))

		self._cleanup_job(job)
Exemple #10
0
    def _handle_import(self, id_, image):
        """This is the initial step when importing an image from the API. The API
        will insert a new Image document into the database with status["name"] set to
        "importing"
        """
        self._log.info("importing an image")

        image_to_import = bson.ObjectId(image.status["tmpfile"])
        tmp_file = master.models.TmpFile.objects(id=image_to_import)[0]

        if tmp_file.path.startswith("/"):
            tmp_file.path = tmp_file.path[1:]

        image_path = os.path.join("/tmp/talus", tmp_file.path)
        if not os.path.exists(image_path):
            self._log.warn("Cannot import image: {!r}, image to import not found ({})".format(
                image.name,
                tmp_file.path
            ))
            tmp_file.delete()
            image.status = {
                "name": "import_error"
            }
            image.save()
            return

        vnc_info = self._vm_manager.import_image(
            image_path,
            str(image.id), # image name
            user_interaction    = True,
            username            = image.username,
            password            = image.password,
            on_success            = self._set_image_ready
        )

        from master import Master
        Master.instance().update_status(vms=self._get_running_vms())

        if os.path.exists(tmp_file.path):
            os.remove(tmp_file.path)
        tmp_file.delete()

        image.status = {
            "name": "configuring",
            "vnc": vnc_info
        }
        image.save()

        self._log.info("image is imported and running, ready for initial configuration:\n\t{!r}".format(vnc_info))
Exemple #11
0
	def stop_job(self, job):
		"""This is intended to be called once a job has been completed
		(not cancelled, but completed)
		"""
		self._log.info("stopping job: {}".format(job.id))

		if str(job.id) in self._job_handlers:
			with self._job_queue_lock:
				handler = self._job_handlers[str(job.id)]
				queue = self._job_amqp_queues[handler.queue_name]

				new_queue = []
				for priority,handler in queue.queue:
					if handler.job.id == job.id:
						continue
					new_queue.append((priority, handler))

				queue.queue = new_queue

				Master.instance().update_status(queues=self._get_queues())

		AmqpManager.instance().queue_msg(
			json.dumps(dict(
				type	= "cancel",
				job		= str(job.id)
			)),
			"",
			exchange=Master.AMQP_BROADCAST_XCHG
		)

		job.reload()
		job.status = {
			"name": "finished"
		}
		job.timestamps["finished"] = time.time()
		job.save()

		self._log.info("stopped job: {}".format(job.id))

		self._cleanup_job(job)
Exemple #12
0
    def _handle_configure(self, id_, image):
        """Configure the image (spin it up, let the user muck around in it, commit all changes
		back into the original image)
		"""
        vagrantfile = image.status.setdefault("vagrantfile", None)
        user_interaction = image.status.setdefault("user_interaction", False)

        vnc_info = self._vm_manager.configure_image(
            str(image.id),
            vagrantfile=vagrantfile,
            user_interaction=user_interaction,
            on_success=self._set_image_ready,
            kvm=image.status["kvm"])
        self._log.debug(
            "got vnc info from configure image: {!r}".format(vnc_info))

        from master import Master
        Master.instance().update_status(vms=self._get_running_vms())

        image = master.models.Image.objects(id=image.id)[0]
        if user_interaction:
            image.status = {"name": "configuring", "vnc": vnc_info}
            image.save()
Exemple #13
0
 def _on_worker_exited(self):
     from master import Master
     Master.instance().update_status(vms=self._get_running_vms())