def shutdown(args, config): must_be_root() names = ops.ls() for name in names: if ops.is_running(name): try: ops.stop(name) try: box_config = ops.get_box_config(name) except Exception as e: report.die("Cannot load '%s' config, is it broken? %s" % (name, e)) if os.path.exists(ops.get_box_home(name, "heaver_root_generated")): imager = image.get_image_operator(config["image"]) if box_config["datamounts"]: for mountpoint, source in box_config["datamounts"]: imager.disassemble_instance(source) imager.disassemble_instance(box_config["root"]) except ops.InvocationError as e: report.die("LXC is broken, cannot stop container %s: %s" % (name, e)) except ops.ContainerNotFound as e: # WTF? Should not happen (containers in ops.ls() already exists) report.die("Container %s just disappeared, panic!" % name) send_status_soft(args, config) print report.format(dict(status="OK", action="shutdown", id=name, message="Container %s stopped at shutdown" % name))
def stop(args, config): must_be_root() names = must_get_names(args) for name in names: try: ops.stop(name) try: box_config = ops.get_box_config(name) except Exception as e: report.die("Cannot load '%s' config, is it broken? %s" % (name, e)) if os.path.exists(ops.get_box_home(name, "heaver_root_generated")): imager = image.get_image_operator(config["image"]) if box_config["datamounts"]: for mountpoint, source in box_config["datamounts"]: imager.disassemble_instance(source) imager.disassemble_instance(box_config["root"]) except ops.InvocationError as e: report.die("LXC is broken, cannot stop container %s: %s" % (name, e)) except ops.ContainerNotFound as e: report.die("Container %s just disappeared, panic!" % name) try: running_flag = ops.get_box_home(name, "heaver_box_running") if os.path.exists(running_flag): os.unlink(running_flag) except Exception as e: pass # FIXME: should not happen, warn user/log? send_status_soft(args, config) print report.format(dict(status="OK", action="stop", id=name, message="Container %s stopped" % name))
def make_tarball(args, config): must_be_root() if not args.name: report.die("No container chosen (tarball cannot be feed with --all)") name = args.name if name not in ops.ls(): report.die("No such container: '%s'" % name) if ops.is_running(name): report.die("Container '%s' must be stopped for tarballing" % name) tar_path = args.tarball if tar_path == "<generated>": # make temporary path for tarball import tempfile try: tar_fd, tar_path = tempfile.mkstemp(dir=HEAVER_TMPDIR, prefix="%s.tar." % name) tar_file = os.fdopen(tar_fd, "w") except Exception as e: # FIXME: proper exceptions? report.die("Cannot create tarball of container '%s': '%s'" % (name, e)) else: try: tar_file = open(tar_path, "wb") except Exception as e: # FIXME: proper exceptions? # cannot open file - no directory or no write access report.die("Cannot create tarball of container '%s': %s" % (name, e)) box_config = ops.get_box_config(name) imager = image.get_image_operator(config["image"]) imager.assemble_instance(box_config["root"]) try: ops.write_tarball(name, tar_file) except Exception as e: # FIXME: proper exceptions? tar_file.close() os.unlink(tar_path) report.die("Cannot create tarball of container '%s': %s" % (name, e)) tar_file.close() print report.format(dict(status="OK", action="tarball", data=tar_path, message="Tarball of container '%s' created at '%s'" % (name, tar_path)))
def start(args, config): must_be_root() names = must_get_names(args) # start for name in names: try: try: box_config = ops.get_box_config(name) except Exception as e: report.die("Cannot load '%s' config, is it broken? %s" % (name, e)) if os.path.exists(ops.get_box_home(name, "heaver_root_generated")): imager = image.get_image_operator(config["image"]) imager.assemble_instance(box_config["root"]) if box_config["datamounts"]: root = box_config["root"] for mountpoint, source in box_config["datamounts"]: imager.assemble_instance(source) # since 'mountpoint' starts with / we need to remove it mountpoint = mountpoint.lstrip("/") mount_path = os.path.join(root, mountpoint) if not os.path.exists(mount_path): os.makedirs(mount_path) ops.start(name) except ops.InvocationError as e: report.die("LXC is broken, cannot start container %s: %s" % (name, e)) except ops.ContainerNotFound as e: report.die("Container %s just disappeared, panic!" % name) try: running_flag = ops.get_box_home(name, "heaver_box_running") open(running_flag, "w").close() except Exception as e: pass # FIXME: should not happen, warn user/log? send_status_soft(args, config) print report.format(dict(status="OK", action="start", id=name, message="Container %s started" % name))
def destroy(args, config): must_be_root() names = must_get_names(args) if args.all and not args.force: msg = ["Selected containers: %s" % ", ".join(names), "Are you sure to destroy all these (probably innocent) containers? [y/N] "] decision = raw_input("\n".join(msg)) if not (decision.lower() == "y" or decision.lower() == "yes"): print "Okay" return for name in names: box_root = None if not ops.exists(name): print report.format(dict(status="OK", action="destroy", id=name, message="Container %s already destroyed" % name)) continue try: box_config = ops.get_box_config(name) except Exception as e: report.die("Cannot load '%s' config, is it broken? %s" % (name, e)) root_generated = os.path.exists(ops.get_box_home(name, "heaver_root_generated")) root = box_config.get("root") try: # Free addresses, associated with box ips = [] for network in box_config["networks"].values(): for ip, mask in network["ips"]: ips.append(ip) free_addresses(config["net"]["used_ranges_path"], ips) except Exception as e: print "Cannot release assigned to box addresses:", e import traceback print traceback.format_exc() try: ops.destroy(name) except ops.ContainerBusy as e: report.die("Container busy: %s" % e) except ops.ContainerNotFound: pass except ops.InvocationError as e: report.die("LXC is broken, cannot destroy container %s: %s" % (name, e)) # remove root, if it was generated if root_generated: imager = image.get_image_operator(config["image"]) try: imager.destroy_instance(root) except Exception as e: report.die("Cannot remove root of container '%s': %s" % (name, e)) if box_config["datamounts"]: for mountpoint, source in box_config["datamounts"]: try: imager.destroy_instance(source) except Exception as e: report.die("Cannot remove datamount '%s' in container'%s': %s" % (source, name, e)) send_status_soft(args, config) print report.format(dict(status="OK", action="destroy", id=name, message="Container %s destroyed" % name))