#!/usr/bin/python2 # # Copyright (C) 2015 vmware inc. # # Author: Touseef Liaqat import os import glob import modules.commons from installer import Installer from actionresult import ActionResult class OstreeInstaller(Installer): def __init__(self, install_config, maxy = 0, maxx = 0, iso_installer = False, rpm_path = "../stage/RPMS", log_path = "../stage/LOGS", ks_config = None): Installer.__init__(self, install_config, maxy, maxx, iso_installer, rpm_path, log_path, ks_config) self.repo_config = {} self.repo_read_conf() def get_ostree_repo_url(self): self.default_repo = 'default_repo' in self.install_config and self.install_config['default_repo']; if not self.default_repo: self.ostree_repo_url = self.install_config['ostree_repo_url'] self.ostree_ref = self.install_config['ostree_repo_ref'] def repo_read_conf(self): with open("ostree-release-repo.conf") as repo_conf: for line in repo_conf: name, value = line.partition("=")[::2] self.repo_config[name] = value.strip(' \n\t\r') def pull_repo(self, repo_url, repo_ref): if self.default_repo: self.run("ostree remote add --repo={}/ostree/repo --set=gpg-verify=false photon {}".format(self.photon_root, repo_url), "Adding OSTree remote") self.run("ostree pull-local --repo={}/ostree/repo {}".format(self.photon_root, self.local_repo_path), "Pulling OSTree repo") self.run("mv {}/ostree/repo/refs/heads {}/ostree/repo/refs/remotes/photon".format(self.photon_root, self.photon_root)) self.run("mkdir -p {}/ostree/repo/refs/heads".format(self.photon_root, self.photon_root)) else: self.run("ostree remote add --repo={}/ostree/repo --set=gpg-verify=false photon {}".format(self.photon_root, repo_url), "Adding OSTree remote") self.run("ostree pull --repo={}/ostree/repo photon {}".format(self.photon_root, repo_ref), "Pulling OSTree remote repo") def deploy_ostree(self, repo_url, repo_ref): self.run("ostree admin --sysroot={} init-fs {}".format(self.photon_root, self.photon_root), "Initializing OSTree filesystem") self.pull_repo(repo_url, repo_ref) self.run("ostree admin --sysroot={} os-init photon ".format(self.photon_root), "OSTree OS Initializing") self.run("ostree admin --sysroot={} deploy --os=photon photon:{}".format(self.photon_root, repo_ref), "Deploying") def do_systemd_tmpfiles_commands(self, commit_number): prefixes = ["/var/home", "/var/roothome", "/var/lib/rpm", "/var/opt", "/var/srv", "/var/userlocal", "/var/mnt", "/var/spool/mail"] for prefix in prefixes: command = "systemd-tmpfiles --create --boot --root={}/ostree/deploy/photon/deploy/{}.0 --prefix={}".format(self.photon_root, commit_number, prefix) self.run(command) def mount_devices_in_deployment(self, commit_number): for command in ["mount -t bind -o bind,defaults /dev {}/ostree/deploy/photon/deploy/{}.0/dev", "mount -t devpts -o gid=5,mode=620 devpts {}/ostree/deploy/photon/deploy/{}.0/dev/pts", "mount -t tmpfs -o defaults tmpfs {}/ostree/deploy/photon/deploy/{}.0/dev/shm", "mount -t proc -o defaults proc {}/ostree/deploy/photon/deploy/{}.0/proc", "mount -t bind -o bind,defaults /run {}/ostree/deploy/photon/deploy/{}.0/run", "mount -t sysfs -o defaults sysfs {}/ostree/deploy/photon/deploy/{}.0/sys" ]: self.run(command.format(self.photon_root, commit_number)) def get_commit_number(self, ref): fileName = os.path.join(self.photon_root, "ostree/repo/refs/remotes/photon/{}".format(ref)) commit_number = None with open (fileName, "r") as file: commit_number = file.read().replace('\n', '') return commit_number def unsafe_install(self, params): self.org_photon_root = self.photon_root sysroot_ostree = os.path.join(self.photon_root, "ostree") sysroot_boot = os.path.join(self.photon_root, "boot") loader0 = os.path.join(sysroot_boot, "loader.0") loader1 = os.path.join(sysroot_boot, "loader.1") boot0 = os.path.join(sysroot_ostree, "boot.0") boot1 = os.path.join(sysroot_ostree, "boot.1") boot01 = os.path.join(sysroot_ostree, "boot.0.1") boot11 = os.path.join(sysroot_ostree, "boot.1.1") self.get_ostree_repo_url() self.window.show_window() self.progress_bar.initialize("Initializing installation...") self.progress_bar.show() self.execute_modules(modules.commons.PRE_INSTALL) disk = self.install_config['disk']['disk'] self.run("sgdisk -d 1 -d 2 -n 1::+2M -n 2::+300M -n 3: -p {}".format(disk), "Updating partition table for OSTree") self.run("sgdisk -t1:ef02 {}".format(disk)) self.run("mkfs -t ext4 {}2".format(disk)) self.run("mkfs -t ext4 {}3".format(disk)) self.run("mount {}3 {}".format(disk, self.photon_root)) self.run("mkdir -p {} ".format(sysroot_boot)) self.run("mount {}2 {}".format(disk, sysroot_boot)) #Setup the disk self.run("dd if=/dev/zero of={}/swapfile bs=1M count=64".format(self.photon_root)) self.run("chmod 600 {}/swapfile".format(self.photon_root)) self.run("mkswap -v1 {}/swapfile".format(self.photon_root)) self.run("swapon {}/swapfile".format(self.photon_root)) if self.default_repo: self.run("rm -rf /installer/boot") self.run("mkdir -p {}/repo".format(self.photon_root)) self.progress_bar.show_loading("Unpacking local OSTree repo") self.run("tar --warning=none -xf /mnt/cdrom/ostree-repo.tar.gz -C {}/repo".format(self.photon_root)) self.local_repo_path = "{}/repo".format(self.photon_root) self.ostree_repo_url = self.repo_config['OSTREEREPOURL'] self.ostree_ref = self.repo_config['OSTREEREFS'] self.progress_bar.update_loading_message("Unpacking done") self.deploy_ostree(self.ostree_repo_url, self.ostree_ref) self.run("swapoff -a") self.run("rm {}/swapfile".format(self.photon_root)) commit_number = self.get_commit_number(self.ostree_ref) self.do_systemd_tmpfiles_commands(commit_number) self.mount_devices_in_deployment(commit_number) deployment = os.path.join(self.photon_root, "ostree/deploy/photon/deploy/" + commit_number + ".0/") deployment_boot = os.path.join(deployment, "boot") deployment_sysroot = os.path.join(deployment, "sysroot") self.run("mv {} {}".format(loader1, loader0)) self.run("mv {} {}".format(boot1, boot0)) self.run("mv {} {}".format(boot11, boot01)) self.run("mount --bind {} {}".format(sysroot_boot, deployment_boot)) self.run("mount --bind {} {}".format(self.photon_root, deployment_sysroot)) self.run("chroot {} bash -c \"grub2-install /dev/sda\"".format(deployment)) self.run("chroot {} bash -c \"grub2-mkconfig -o /boot/grub2/grub.cfg\"".format(deployment)) self.run("mv {} {}".format(loader0, loader1)) self.run("mv {} {}".format(boot0, boot1)) self.run("mv {} {}".format(boot01, boot11)) self.run("chroot {} bash -c \"ostree admin instutil set-kargs root=/dev/sda3 \"".format(deployment)) sysroot_grub2_grub_cfg = os.path.join(self.photon_root, "boot/grub2/grub.cfg") self.run("ln -sf ../loader/grub.cfg {}".format(sysroot_grub2_grub_cfg)) self.run("mv {} {}".format(loader1, loader0)) self.run("mv {} {}".format(boot1, boot0)) self.run("mv {} {}".format(boot11, boot01)) deployment_fstab = os.path.join(deployment, "etc/fstab") self.run("echo \"/dev/sda3 / ext4 defaults 1 1 \" >> {} ".format(deployment_fstab), "Adding / mount point in fstab") self.run("echo \"/dev/sda2 /boot ext4 defaults 1 2 \" >> {} ".format(deployment_fstab), "Adding /boot mount point in fstab") self.run("mount --bind {} {}".format(deployment, self.photon_root)) self.progress_bar.update_loading_message("Starting post install modules") self.execute_modules(modules.commons.POST_INSTALL) self.progress_bar.update_loading_message("Unmounting disks") self.run("{} {} {}".format(self.unmount_disk_command, '-w', self.photon_root)) self.progress_bar.update_loading_message("Ready to restart") self.progress_bar.hide() self.window.addstr(0, 0, 'Congratulations, Photon RPM-OSTree Host has been installed in {0} secs.\n\nPress any key to continue to boot...'.format(self.progress_bar.time_elapsed)) if self.ks_config == None: self.window.content_window().getch() return ActionResult(True, None)