Beispiel #1
0
 def test(self):
     golden = read_file(
         os.path.join(os.path.dirname(os.path.abspath(__file__)),
                      "aptconfig_golden.txt"))
     config = aptconfig.DEFAULT_CONFIG
     config.update({"distribution": "lucid"})
     actual = aptconfig.render_to_sources_list(config)
     self.assertEqual(actual, golden)
Beispiel #2
0
def prepare(config):

    def flush_cache():
        if config["do_write_project_cache"]:
            call_no_print(
                ["mkdir", "-p", os.path.dirname(config["project_cache_path"])])
            with open(config["project_cache_path"], "wb") as fh:
                fh.write(json.dumps(config["project_cache"]))

    flush_cache()
    root_path = os.path.join(config["project_dir"], "root")
    flush_cache()
    if not os.path.exists(root_path):
        force_rm(root_path)
        mnt_path = config["mnt_path"]
        force_rm(mnt_path)
        call(["mkdir", "-p", root_path])
        call(["mkdir", "-p", mnt_path])
        call(["sudo", "mount", "--bind", root_path, mnt_path])
        call(["sudo", "debootstrap", config["ubuntu-codename"], mnt_path], 
             stdout=None, stderr=None, stdin=None)
        for relpath in ["proc", "dev", "dev/pts", "sys"]:
            src = os.path.join("/", relpath)
            dst = os.path.join(mnt_path, relpath)
            call(["sudo", "mkdir", "-p", dst])
            call(["sudo", "mount", "--bind", src, dst])
        resolvconf = os.path.join(mnt_path, "run/resolvconf/resolv.conf")
        force_rm(resolvconf)
        call(["sudo", "cp", "/etc/resolv.conf", resolvconf])
        call(["sudo", "bash", "-c", 'echo "$1" > "$2"', "-", 
              aptconfig.BLANK_SOURCES, 
              os.path.join(mnt_path, "etc/apt/sources.list")])
        base_sources_config = copy.deepcopy(aptconfig.DEFAULT_CONFIG)
        base_sources_config["distribution"] = config["ubuntu-codename"]
        base_sources = aptconfig.render_to_sources_list(base_sources_config)
        call(["sudo", "bash", "-c", 'echo "$1" > "$2"', "-", 
              base_sources, 
              os.path.join(mnt_path, "etc/apt/sources.list.d/base.list")])
        call(["sudo", "chroot", mnt_path, "apt-get", "update"], stdout=None)
        call(["sudo", "chroot", mnt_path, "apt-get", "remove", "--yes",
              "cloud-init"], stdout=None)
        call(["sudo", "chroot", mnt_path, "apt-get", "install", "--yes",
              "language-pack-en"], stdout=None)
        call(["sudo", "chroot", mnt_path, "apt-get", "install", "--yes",
              "openssh-server"], stdout=None)
        call(["sudo", "chroot", mnt_path, "adduser", "--gecos", "", 
              "--disabled-password", "--uid", "1000", "sysadmin"], stdout=None)
        call(["sudo", "mv", os.path.join(mnt_path, "home", "sysadmin"), 
              os.path.join(config["project_dir"], "home")])
        call(["sudo", "chroot", mnt_path, "adduser", "sysadmin", 
              "adm"], stdout=None)
        call(["sudo", "chroot", mnt_path, "adduser", "sysadmin", 
              "sudo"], stdout=None)
        call(["sudo", "chroot", mnt_path, "bash", "-c", 
              "rm -rf /etc/ssh/ssh_host_*"])
        call(["sudo", "chroot", mnt_path, "dpkg-reconfigure", 
              "openssh-server"], stdout=None)
        call(["cp", os.path.join(mnt_path, "etc", "ssh", 
                                 "ssh_host_ecdsa_key.pub"), 
              config["host_key_path"]])
        call(["bash", "-c", 'echo basebox $(cat "$1") > "$2"', "-",
              config["host_key_path"], config["host_key_path"] + ".known"])
        force_rm(config["ssh_key_path"])
        call(["ssh-keygen", "-P", "", "-f", config["ssh_key_path"]])
        for home_path in [os.path.join(mnt_path, "root"),
                          os.path.join(config["project_dir"], "home")]:
            
            ak_path = os.path.join(home_path, ".ssh", "authorized_keys")
            call(["sudo", "mkdir", "-p", os.path.dirname(ak_path)])
            force_rm(ak_path)
            call(["sudo", "cp", config["ssh_key_path"] + ".pub", ak_path])
            if os.path.basename(home_path) != "root":
                call(["sudo", "chown", "-R", "1000:1000", 
                      os.path.dirname(ak_path)])
        call(["sudo", "bash", "-c", 'echo "$1" > "$2"', "-",
              """\
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
  address 192.168.122.200
  netmask 255.255.255.0
  network 192.168.122.0
  gateway 192.168.122.1
  dns-nameservers 192.168.122.1
""", os.path.join(mnt_path, "etc", "network", "interfaces")])
        nopasswd_path = os.path.join(
            mnt_path, "etc", "sudoers.d", "sudo-nopasswd")
        call(["sudo", "bash", "-c", 'echo "$1" > "$2"', "-",
              """\
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
""", nopasswd_path])
        call(["sudo", "chmod", "0440", nopasswd_path])
        #### Run chef here?
        force_rm(mnt_path)
    if get_vm_state(config["vm_name"], on_no_state=lambda m: None) != "running":
        mnt_path = config["mnt_path"]
        force_rm(mnt_path)
        call(["mkdir", "-p", mnt_path])
        call(["sudo", "mount", "--bind", root_path, mnt_path])
        home_rw = os.path.join(config["project_dir"], "home")
        call(["mkdir", "-p", home_rw])
        home_mnt = os.path.join(mnt_path, "home", "sysadmin")
        force_rm(home_mnt)
        call(["sudo", "mkdir", "-p", home_mnt])
        call(["sudo", "mount", "--bind", home_rw, home_mnt])
        call(["virsh", "--connect", "lxc://", "destroy", config["vm_name"]],
             do_check=False)
        while True:
            if get_vm_state(config["vm_name"], 
                            on_no_state=lambda m: "shut off") == "shut off":
                break
            time.sleep(0.1)
        call(["virsh", "--connect", "lxc://", "undefine", config["vm_name"]],
             do_check=False)
        definition = """\
<domain type="lxc">
  <name>TEMPLATE: name</name>
  <memory>524288</memory>
  <os>
    <type arch="x86_64">exe</type>
    <init>/sbin/init</init>
  </os>
  <vcpu>2</vcpu>
  <clock offset="utc"/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/lib/libvirt/libvirt_lxc</emulator>
    <filesystem type="mount">
      <source dir="TEMPLATE: root_dir"/>
      <target dir="/"/>
    </filesystem>
    <interface type="bridge">
      <source bridge="virbr0"/>
    </interface>
    <console type="pty">
      <target port="0"/>
    </console>
  </devices>
</domain>
"""
        xml = lxml.etree.fromstring(definition)
        for match in xml.xpath(".//name"):
            match.text = config["vm_name"]
        for match in xml.xpath(".//filesystem//source"):
            match.attrib["dir"] = mnt_path
        xml_path = os.path.join(config["project_dir"], "libvirt.xml")
        call(["bash", "-c", 'echo "$1" > "$2"', "-",
              lxml.etree.tostring(xml), xml_path])
        call(["virsh", "--connect", "lxc://", "define", xml_path])
        call(["virsh", "--connect", "lxc://", "start", config["vm_name"]])
        print "~~~", " ".join(shell_escape(a) for a in get_ssh_argv(config))
    while True:
        rc = []
        call_no_print(get_ssh_argv(config, ["true"]), 
                      do_check=False, handle_rc=rc.append)
        rc = rc[0]
        if rc == 0:
            break
        time.sleep(0.1)