def php_setup(): """ Setup /etc/php/php.ini """ php_ini_path = os.path.join(DEST_DIR, 'etc/php/php.ini') with open(php_ini_path, 'r') as php_ini: lines = php_ini.readlines() # PHP extensions that will be activated so_extensions = [ "mysql", "mcrypt", "mssql", "mysqli", "openssl", "iconv", "imap", "zip", "bz2"] php_ini_path = os.path.join(DEST_DIR, 'etc/php/php.ini') with open(php_ini_path, 'r') as php_ini: lines = php_ini.readlines() with open(php_ini_path, 'w') as php_ini: for line in lines: # Uncomment extensions for so_ext in so_extensions: ext = ";extension={0}.so".format(so_ext) if line.startswith(ext): line = line[1:] # Add PhpMyAdmin system path (/etc/webapps/ and /usr/share/webapps/) # to make sure PHP can access and read files under those directories if "open_basedir =" in line: line = ("open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:" "/usr/share/webapps/:/etc/webapps/\n") php_ini.write(line) cmd = ["systemctl", "enable", "php-fpm"] chroot_call(cmd)
def nginx_setup(): """ Setup Nginx web server """ cmd = ["systemctl", "enable", "nginx"] chroot_call(cmd) # We need to tell nginx to run php using php-fpm. path = os.path.join(DEST_DIR, "etc/nginx/nginx.conf") with open(path, 'r') as nginx_conf: lines = nginx_conf.readlines() sections = {"http": False, "server": False, "location": False} with open(path, 'w') as nginx_conf: for line in lines: if "http {" in line: sections["http"] = True if sections["http"] and "server {" in line: sections["server"] = True if sections["http"] and sections["server"] and "#location ~ \.php$ {" in line: nginx_conf.write(" location ~ \.php$ {\n") nginx_conf.write(" fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;\n") nginx_conf.write(" fastcgi_index index.php;\n") nginx_conf.write(" root /usr/share/nginx/html;\n") nginx_conf.write(" include fastcgi.conf;\n") nginx_conf.write(" }\n\n") sections = {"http": False, "server": False, "location": False} nginx_conf.write(line)
def enable_services(services): """ Enables all services that are in the list 'services' """ for name in services: path = os.path.join(DEST_DIR, "usr/lib/systemd/system/{0}.service".format(name)) if os.path.exists(path): chroot_call(["systemctl", "-f", "enable", name]) logging.debug("Service '%s' has been enabled.", name) else: logging.warning("Can't find service %s", name)
def alsa_mixer_setup(): """ Sets ALSA mixer settings """ alsa_commands = [ "Master 70% unmute", "Front 70% unmute" "Side 70% unmute" "Surround 70% unmute", "Center 70% unmute", "LFE 70% unmute", "Headphone 70% unmute", "Speaker 70% unmute", "PCM 70% unmute", "Line 70% unmute", "External 70% unmute", "FM 50% unmute", "Master Mono 70% unmute", "Master Digital 70% unmute", "Analog Mix 70% unmute", "Aux 70% unmute", "Aux2 70% unmute", "PCM Center 70% unmute", "PCM Front 70% unmute", "PCM LFE 70% unmute", "PCM Side 70% unmute", "PCM Surround 70% unmute", "Playback 70% unmute", "PCM,1 70% unmute", "DAC 70% unmute", "DAC,0 70% unmute", "DAC,1 70% unmute", "Synth 70% unmute", "CD 70% unmute", "Wave 70% unmute", "Music 70% unmute", "AC97 70% unmute", "Analog Front 70% unmute", "VIA DXS,0 70% unmute", "VIA DXS,1 70% unmute", "VIA DXS,2 70% unmute", "VIA DXS,3 70% unmute", "Mic 70% mute", "IEC958 70% mute", "Master Playback Switch on", "Master Surround on", "SB Live Analog/Digital Output Jack off", "Audigy Analog/Digital Output Jack off", ] for alsa_command in alsa_commands: cmd = ["amixer", "-q", "-c", "0", "sset"] cmd.extend(alsa_command.split()) chroot_call(cmd) # Save settings logging.debug("Saving ALSA settings...") chroot_call(["alsactl", "store"]) logging.debug("ALSA settings saved.")
def run(params, dest_dir="/install"): """ Setup ufw """ cmd = ["ufw"] cmd.extend(params) if not _UFW: # Could not import ufw module (missing?) # Will call ufw command directly try: chroot_call(cmd, dest_dir) except OSError as os_error: logging.warning(os_error) return app_action = False # Remember, will have to take --force into account if we use it with 'app' idx = 1 if len(cmd) > 1 and cmd[1].lower() == "--dry-run": idx += 1 if len(cmd) > idx and cmd[idx].lower() == "app": app_action = True res = "" try: cmd_line = ufw.frontend.parse_command(cmd) ui = ufw.frontend.UFWFrontend(cmd_line.dryrun) if app_action and 'type' in cmd_line.data and cmd_line.data[ 'type'] == 'app': res = ui.do_application_action(cmd_line.action, cmd_line.data['name']) else: bailout = False if cmd_line.action == "enable" and not cmd_line.force and \ not ui.continue_under_ssh(): res = _("Aborted") bailout = True if not bailout: if 'rule' in cmd_line.data: res = ui.do_action(cmd_line.action, cmd_line.data['rule'], cmd_line.data['iptype'], cmd_line.force) else: res = ui.do_action(cmd_line.action, "", "", cmd_line.force) except (ValueError, ufw.UFWError) as ufw_error: logging.error(ufw_error) # Error using ufw module # Will call ufw command directly try: chroot_call(cmd, dest_dir) except OSError as os_error: logging.warning(os_error) return logging.debug(res)
def mariadb_setup(): """ Runs MariaDB setup """ cmd = [ "mysql_install_db", "--user=mysql", "--basedir=/usr", "--datadir=/var/lib/mysql" ] chroot_call(cmd) cmd = ["systemctl", "enable", "mysqld"] chroot_call(cmd)
def mariadb_setup(): """ Setup MariaDB database server """ cmd = [ "mysql_install_db", "--user=mysql", "--basedir=/usr", "--datadir=/var/lib/mysql"] chroot_call(cmd) cmd = ["systemctl", "enable", "mysqld"] chroot_call(cmd)
def run_mkconfig(self): """ Create grub.cfg file using grub-mkconfig """ logging.debug("Generating grub.cfg...") # Make sure that /dev and others are mounted (binded). special_dirs.mount(self.dest_dir) # if self.settings.get("zfs"): # # grub-mkconfig does not properly detect the ZFS filesystem, # # so it is necessary to edit grub.cfg manually. # zfs_pool_name = self.settings.get("zfs_pool_name") # grub_cfg_path = os.path.join(self.dest_dir, "boot/grub/grub.cfg") # with open(grub_cfg_path, "w") as grub_cfg: # grub_cfg.write('set timeout=2\n') # grub_cfg.write('set default=0\n\n') # grub_cfg.write('# (0) Antergos Linux\n') # grub_cfg.write('\tmenuentry "Antergos Linux (zfs)" {\n') # # grub_cfg.write('\tsearch --no-floppy --label --set=root {0}\n'.format(zfs_pool_name)) # grub_cfg.write('\tlinux /vmlinuz-linux zfs={0} rw\n'.format(zfs_pool_name)) # grub_cfg.write('\tinitrd /initramfs-linux.img\n') # grub_cfg.write('}\n') # else: # Add -l option to os-prober's umount call so that it does not hang self.apply_osprober_patch() logging.debug("Running grub-mkconfig...") locale = self.settings.get("locale") cmd = 'LANG={0} grub-mkconfig -o /boot/grub/grub.cfg'.format(locale) cmd_sh = ['sh', '-c', cmd] if not chroot_call(cmd_sh, self.dest_dir, timeout=300): msg = ("grub-mkconfig does not respond. Killing grub-mount and" "os-prober so we can continue.") logging.error(msg) call(['killall', 'grub-mount']) call(['killall', 'os-prober'])
def apache_setup(): """ Configure Apache web server """ # Allow site virtualization httpd_path = os.path.join(DEST_DIR, 'etc/httpd/conf/httpd.conf') with open(httpd_path, 'a') as httpd_conf: httpd_conf.write('IncludeOptional conf/sites-enabled/*.conf\n') httpd_conf.write('IncludeOptional conf/mods-enabled/*.conf\n') # We create config directories dirs = [ "etc/httpd/conf/sites-available", "etc/httpd/conf/sites-enabled", "etc/httpd/conf/mods-enabled" ] for path in dirs: path = os.path.join(DEST_DIR, path) os.makedirs(path, mode=0o755, exist_ok=True) # Copy a2ensite and a2dissite scripts scripts = ["a2ensite", "a2dissite"] for script in scripts: try: src = os.path.join("/usr/share/cnchi/scripts", script) dst = os.path.join(DEST_DIR, 'usr/local/bin', script) shutil.copy2(src, dst) os.chmod(dst, 0o755) except (FileExistsError, shutil.Error) as file_error: logging.warning(file_error) # Create localhost.conf in /etc/httpd/conf/sites-available/ localhost_path = os.path.join( DEST_DIR, "etc/httpd/conf/sites-available/localhost.conf") with open(localhost_path, 'a') as localhost_conf: localhost_conf.write('\n# phpmyadmin alias and directory setup\n') localhost_conf.write( 'Alias /phpmyadmin "/usr/share/webapps/phpMyAdmin"\n') localhost_conf.write('<Directory "/usr/share/webapps/phpMyAdmin">\n') localhost_conf.write(' DirectoryIndex index.html index.php\n') localhost_conf.write(' AllowOverride All\n') localhost_conf.write(' Options FollowSymlinks\n') localhost_conf.write(' Require all granted\n') localhost_conf.write('</Directory>\n') # We activate the virtual localhost site chroot_call(["a2ensite", "localhost"]) chroot_call(["systemctl", "enable", "httpd"])
def install(self): """ Installs rEFInd boot loader https://wiki.archlinux.org/index.php/REFInd#Scripted_configuration """ logging.debug("Installing and configuring rEFInd bootloader...") cmd = ["refind-install"] self.settings.set('bootloader_installation_successful', False) if chroot_call(cmd, self.dest_dir, timeout=300) != False: # This script will attempt to find the kernel in /boot and # automatically generate refind_linux.conf. # The script will only set up the most basic kernel # parameters, so be sure to check the file it created for # correctness. cmd = ["refind-mkrlconf"] if chroot_call(cmd, self.dest_dir, timeout=300) != False: self.settings.set('bootloader_installation_successful', True) logging.debug("rEFIind installed.")
def apache_setup(): """ Configure Apache web server """ # Allow site virtualization httpd_path = os.path.join(DEST_DIR, 'etc/httpd/conf/httpd.conf') with open(httpd_path, 'a') as httpd_conf: httpd_conf.write('IncludeOptional conf/sites-enabled/*.conf\n') httpd_conf.write('IncludeOptional conf/mods-enabled/*.conf\n') # We create config directories dirs = [ "etc/httpd/conf/sites-available", "etc/httpd/conf/sites-enabled", "etc/httpd/conf/mods-enabled"] for path in dirs: path = os.path.join(DEST_DIR, path) os.makedirs(path, mode=0o755, exist_ok=True) # Copy a2ensite and a2dissite scripts scripts = ["a2ensite", "a2dissite"] for script in scripts: try: src = os.path.join("/usr/share/cnchi/scripts", script) dst = os.path.join(DEST_DIR, 'usr/local/bin', script) shutil.copy2(src, dst) os.chmod(dst, 0o755) except (FileExistsError, shutil.Error) as file_error: logging.warning(file_error) # Create localhost.conf in /etc/httpd/conf/sites-available/ localhost_path = os.path.join(DEST_DIR, "etc/httpd/conf/sites-available/localhost.conf") with open(localhost_path, 'a') as localhost_conf: localhost_conf.write('\n# phpmyadmin alias and directory setup\n') localhost_conf.write('Alias /phpmyadmin "/usr/share/webapps/phpMyAdmin"\n') localhost_conf.write('<Directory "/usr/share/webapps/phpMyAdmin">\n') localhost_conf.write(' DirectoryIndex index.html index.php\n') localhost_conf.write(' AllowOverride All\n') localhost_conf.write(' Options FollowSymlinks\n') localhost_conf.write(' Require all granted\n') localhost_conf.write('</Directory>\n') # We activate the virtual localhost site chroot_call(["a2ensite", "localhost"]) chroot_call(["systemctl", "enable", "httpd"])
def install_bios(self): """ Install Grub2 bootloader in a BIOS system """ grub_location = self.settings.get("bootloader_device") txt = _("Installing GRUB(2) BIOS boot loader in {0}").format(grub_location) logging.info(txt) # /dev and others need to be mounted (binded). # We call mount_special_dirs here just to be sure special_dirs.mount(self.dest_dir) grub_install = [ "grub-install", "--directory=/usr/lib/grub/i386-pc", "--target=i386-pc", "--boot-directory=/boot", "--recheck", ] # Use --force when installing in /dev/sdXY or in /dev/mmcblk if len(grub_location) > len("/dev/sdX"): grub_install.append("--force") grub_install.append(grub_location) chroot_call(grub_install, self.dest_dir) self.install_locales() self.run_mkconfig() grub_cfg_path = os.path.join(self.dest_dir, "boot/grub/grub.cfg") with open(grub_cfg_path) as grub_cfg: if "Antergos" in grub_cfg.read(): txt = _("GRUB(2) BIOS has been successfully installed.") logging.info(txt) self.settings.set("bootloader_installation_successful", True) else: txt = _("ERROR installing GRUB(2) BIOS.") logging.warning(txt) self.settings.set("bootloader_installation_successful", False)
def install_bios(self): """ Install Grub2 bootloader in a BIOS system """ grub_location = self.settings.get('bootloader_device') txt = _("Installing GRUB(2) BIOS boot loader in {0}").format( grub_location) logging.info(txt) # /dev and others need to be mounted (binded). # We call mount_special_dirs here just to be sure special_dirs.mount(self.dest_dir) grub_install = [ 'grub-install', '--directory=/usr/lib/grub/i386-pc', '--target=i386-pc', '--boot-directory=/boot', '--recheck' ] # Use --force when installing in /dev/sdXY or in /dev/mmcblk if len(grub_location) > len("/dev/sdX"): grub_install.append("--force") grub_install.append(grub_location) chroot_call(grub_install, self.dest_dir) self.install_locales() self.run_mkconfig() grub_cfg_path = os.path.join(self.dest_dir, "boot/grub/grub.cfg") with open(grub_cfg_path) as grub_cfg: if "Antergos" in grub_cfg.read(): txt = _("GRUB(2) BIOS has been successfully installed.") logging.info(txt) self.settings.set('bootloader_installation_successful', True) else: txt = _("ERROR installing GRUB(2) BIOS.") logging.warning(txt) self.settings.set('bootloader_installation_successful', False)
def run_mkconfig(self): """ Create grub.cfg file using grub-mkconfig """ logging.debug("Generating grub.cfg...") # Make sure that /dev and others are mounted (binded). special_dirs.mount(self.dest_dir) # Add -l option to os-prober's umount call so that it does not hang self.apply_osprober_patch() logging.debug("Running grub-mkconfig...") locale = self.settings.get("locale") cmd = "LANG={0} grub-mkconfig -o /boot/grub/grub.cfg".format(locale) cmd_sh = ["sh", "-c", cmd] if not chroot_call(cmd_sh, self.dest_dir, timeout=300): msg = "grub-mkconfig does not respond. Killing grub-mount and" "os-prober so we can continue." logging.error(msg) call(["killall", "grub-mount"]) call(["killall", "os-prober"])
def run_mkconfig(self): """ Create grub.cfg file using grub-mkconfig """ logging.debug("Generating grub.cfg...") # Make sure that /dev and others are mounted (binded). special_dirs.mount(self.dest_dir) # Add -l option to os-prober's umount call so that it does not hang self.apply_osprober_patch() logging.debug("Running grub-mkconfig...") locale = self.settings.get("locale") cmd = 'LANG={0} grub-mkconfig -o /boot/grub/grub.cfg'.format(locale) cmd_sh = ['sh', '-c', cmd] if not chroot_call(cmd_sh, self.dest_dir, timeout=300): msg = ("grub-mkconfig does not respond. Killing grub-mount and" "os-prober so we can continue.") logging.error(msg) call(['killall', 'grub-mount']) call(['killall', 'os-prober'])
def install(self): """ Install Systemd-boot bootloader to the EFI System Partition """ logging.debug("Cnchi will install the Systemd-boot (Gummiboot) loader") # Setup bootloader menu menu_dir = os.path.join(self.dest_dir, "boot/loader") os.makedirs(menu_dir, mode=0o755, exist_ok=True) menu_path = os.path.join(menu_dir, "loader.conf") with open(menu_path, 'w') as menu_file: menu_file.write("default antergos\n") menu_file.write("timeout 3\n") # Setup boot entries conf = {} options = "" if not self.settings.get('use_luks'): options = "root=UUID={0} rw quiet".format(self.uuids["/"]) else: luks_root_volume = self.settings.get('luks_root_volume') logging.debug("Luks Root Volume: %s", luks_root_volume) mapper = "/dev/mapper/{0}".format(luks_root_volume) luks_root_volume_uuid = fs.get_uuid(mapper) if (self.settings.get("partition_mode") == "advanced" and self.settings.get('use_luks_in_root')): # In advanced, if using luks in root device, # we store root device it in luks_root_device var root_device = self.settings.get('luks_root_device') self.uuids["/"] = fs.get_uuid(root_device) key = "" if not self.settings.get("luks_root_password"): key = "cryptkey=UUID={0}:ext2:/.keyfile-root" key = key.format(self.uuids["/boot"]) if not self.settings.get('use_lvm'): options = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" options = options.format(self.uuids["/"], luks_root_volume, key, luks_root_volume_uuid) else: # Quick fix for issue #595 (lvm+luks) options = "cryptdevice=UUID={0}:{1} {2} root=/dev/dm-1 rw quiet" options = options.format(self.uuids["/"], luks_root_volume, key) if self.settings.get("zfs"): zfs_pool_name = self.settings.get("zfs_pool_name") options += ' zfs={0}'.format(zfs_pool_name) conf['default'] = [] conf['default'].append("title\tReborn OS\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append("initrd\t/intel-ucode.img\n") conf['default'].append("initrd\t/initramfs-linux.img\n") conf['default'].append("options\t{0}\n\n".format(options)) conf['fallback'] = [] conf['fallback'].append("title\tReborn (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append("initrd\t/intel-ucode.img\n") conf['fallback'].append("initrd\t/initramfs-linux-fallback.img\n") conf['fallback'].append("options\t{0}\n\n".format(options)) if self.settings.get('feature_lts'): conf['lts'] = [] conf['lts'].append("title\tReborn LTS\n") conf['lts'].append("linux\t/vmlinuz-linux-lts\n") conf['lts'].append("initrd\t/intel-ucode.img\n") conf['lts'].append("initrd\t/initramfs-linux-lts.img\n") conf['lts'].append("options\t{0}\n\n".format(options)) conf['lts_fallback'] = [] conf['lts_fallback'].append("title\tReborn LTS (fallback)\n") conf['lts_fallback'].append("linux\t/vmlinuz-linux-lts\n") conf['lts_fallback'].append("initrd\t/intel-ucode.img\n") conf['lts_fallback'].append( "initrd\t/initramfs-linux-lts-fallback.img\n") conf['lts_fallback'].append("options\t{0}\n\n".format(options)) # Write boot entries entries_dir = os.path.join(self.dest_dir, "boot/loader/entries") os.makedirs(entries_dir, mode=0o755, exist_ok=True) entry_path = os.path.join(entries_dir, "antergos.conf") with open(entry_path, 'w') as entry_file: for line in conf['default']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['fallback']: entry_file.write(line) if self.settings.get('feature_lts'): entry_path = os.path.join(entries_dir, "antergos-lts.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-lts-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts_fallback']: entry_file.write(line) # Install bootloader logging.debug("Installing systemd-boot bootloader...") cmd = ['bootctl', '--path=/boot', 'install'] if chroot_call(cmd, self.dest_dir, 300) is False: self.settings.set('bootloader_installation_successful', False) else: self.settings.set('bootloader_installation_successful', True)
os.makedirs(entries_dir, mode=0o755, exist_ok=True) entry_path = os.path.join(entries_dir, "antergos.conf") with open(entry_path, 'w') as entry_file: for line in conf['default']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['fallback']: entry_file.write(line) if self.settings.get('feature_lts'): entry_path = os.path.join(entries_dir, "antergos-lts.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-lts-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts_fallback']: entry_file.write(line) # Install bootloader logging.debug("Installing systemd-boot bootloader...") cmd = ['bootctl', '--path=/boot', 'install'] if chroot_call(cmd, self.dest_dir, 300) is False: self.settings.set('bootloader_installation_successful', False) else: self.settings.set('bootloader_installation_successful', True)
def run(dest_dir, settings, mount_devices, blvm): """ Runs mkinitcpio """ cpu = get_cpu() # Add lvm and encrypt hooks if necessary hooks = [ 'base', 'udev', 'autodetect', 'modconf', 'block', 'keyboard', 'keymap' ] modules = [] files = [] # It is important that the plymouth hook comes before any encrypt hook plymouth_bin = os.path.join(dest_dir, "usr/bin/plymouth") if os.path.exists(plymouth_bin): hooks.append('plymouth') # It is important that the encrypt hook comes before the filesystems hook # (in case you are using LVM on LUKS, the order should be: encrypt lvm2 filesystems) if settings.get('use_luks'): if os.path.exists(plymouth_bin): hooks.append('plymouth-encrypt') else: hooks.append('encrypt') modules.extend(['dm_mod', 'dm_crypt', 'ext4']) arch = os.uname()[-1] if arch == 'x86_64': modules.extend(['aes_x86_64']) else: modules.extend(['aes_i586']) modules.extend(['sha256', 'sha512']) if blvm or settings.get('use_lvm'): hooks.append('lvm2') if 'swap' in mount_devices: hooks.append('resume') if settings.get('zfs'): # the zfs hook must come before the filesystems hook hooks.append('zfs') libgcc_path = '/usr/lib/libgcc_s.so.1' if os.path.exists(libgcc_path): files.append(libgcc_path) hooks.append('filesystems') crc32 = [ 'crc32', 'libcrc32c', 'crc32c_generic', 'crc32c-intel', 'crc32-pclmul' ] if settings.get('f2fs'): modules.append('f2fs') if settings.get('btrfs') or settings.get('f2fs'): modules.extend(crc32) if not settings.get('btrfs') and not settings.get('zfs'): # Use the fsck hook only if not using btrfs or zfs hooks.append('fsck') set_hooks_modules_and_files(dest_dir, hooks, modules, files) # Run mkinitcpio on the target system # Fix for bsdcpio error. See: http://forum.antergos.com/viewtopic.php?f=5&t=1378&start=20#p5450 locale = settings.get('locale') cmd = ['sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux'.format(locale)] chroot_call(cmd, dest_dir) if settings.get('feature_lts'): cmd = [ 'sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux-lts'.format(locale) ] chroot_call(cmd, dest_dir)
def change_user_password(user, new_password): """ Changes the user's password """ shadow_password = crypt.crypt(new_password, "$6${0}$".format(user)) chroot_call(["usermod", "-p", shadow_password, user])
def configure_system(self): """ Final install steps Set clock, language, timezone Run mkinitcpio Populate pacman keyring Setup systemd services ... and more """ self.queue_event("pulse", "start") self.queue_event("info", _("Configuring your new system")) self.auto_fstab() logging.debug("fstab file generated.") # If SSD was detected copy udev rule for deadline scheduler if self.ssd: self.set_scheduler() logging.debug("SSD udev rule copied successfully") # Copy configured networks in Live medium to target system if self.settings.get("network_manager") == "NetworkManager": self.copy_network_config() if self.desktop == "base": # Setup systemd-networkd for systems that won't use the # networkmanager or connman daemons (atm it's just base install) # Enable systemd_networkd services # https://github.com/Antergos/Cnchi/issues/332#issuecomment-108745026 self.enable_services(["systemd-networkd", "systemd-resolved"]) # Setup systemd_networkd # TODO: Ask user for SSID and passphrase if a wireless link is # found (here or inside systemd_networkd.setup() ?) from installation import systemd_networkd systemd_networkd.setup() logging.debug("Network configuration done.") # Copy mirror list mirrorlist_src_path = "/etc/pacman.d/mirrorlist" mirrorlist_dst_path = os.path.join(DEST_DIR, "etc/pacman.d/mirrorlist") try: shutil.copy2(mirrorlist_src_path, mirrorlist_dst_path) logging.debug("Mirror list copied.") except FileNotFoundError: logging.error("Can't copy mirrorlist file. File %s not found", mirrorlist_src_path) except FileExistsError: logging.warning("File %s already exists.", mirrorlist_dst_path) # Add Antergos repo to /etc/pacman.conf self.update_pacman_conf() logging.debug("pacman.conf has been created successfully") # Enable some useful services services = [] if self.desktop != "base": # In base there's no desktop manager ;) services.append(self.settings.get("desktop_manager")) # In base we use systemd-networkd (setup already done above) services.append(self.settings.get("network_manager")) services.extend(["ModemManager", "haveged"]) if self.method == "zfs": services.extend(["zfs", "zfs-mount"]) self.enable_services(services) # Enable timesyncd service if self.settings.get("use_timesyncd"): timesyncd_path = os.path.join(DEST_DIR, "etc/systemd/timesyncd.conf") try: with open(timesyncd_path, "w") as timesyncd: timesyncd.write("[Time]\n") timesyncd.write( "NTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org " "2.arch.pool.ntp.org 3.arch.pool.ntp.org\n" ) timesyncd.write("FallbackNTP=0.pool.ntp.org 1.pool.ntp.org " "0.fr.pool.ntp.org\n") except FileNotFoundError as err: logging.warning("Can't find %s file.", timesyncd_path) chroot_call(["timedatectl", "set-ntp", "true"]) # Set timezone zoneinfo_path = os.path.join("/usr/share/zoneinfo", self.settings.get("timezone_zone")) chroot_call(["ln", "-s", zoneinfo_path, "/etc/localtime"]) logging.debug("Timezone set.") # Wait FOREVER until the user sets his params # FIXME: We can wait here forever! while self.settings.get("user_info_done") is False: # Wait five seconds and try again time.sleep(5) # Set user parameters username = self.settings.get("username") fullname = self.settings.get("fullname") password = self.settings.get("password") hostname = self.settings.get("hostname") sudoers_dir = os.path.join(DEST_DIR, "etc/sudoers.d") if not os.path.exists(sudoers_dir): os.mkdir(sudoers_dir, 0o710) sudoers_path = os.path.join(sudoers_dir, "10-installer") try: with open(sudoers_path, "w") as sudoers: sudoers.write("{0} ALL=(ALL) ALL\n".format(username)) os.chmod(sudoers_path, 0o440) logging.debug("Sudo configuration for user %s done.", username) except IOError as io_error: # Do not fail if can't write 10-installer file. # Something bad must be happening, though. logging.error(io_error) # Configure detected hardware # NOTE: Because hardware can need extra repos, this code must run # always after having called the update_pacman_conf method if self.hardware_install: try: logging.debug("Running hardware drivers post-install jobs...") self.hardware_install.post_install(DEST_DIR) except Exception as ex: template = "Error in hardware module. An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logging.error(message) # Setup user default_groups = "lp,video,network,storage,wheel,audio" if self.vbox: # Why there is no vboxusers group? Add it ourselves. chroot_call(["groupadd", "vboxusers"]) default_groups += ",vboxusers,vboxsf" self.enable_services(["vboxservice"]) if self.settings.get("require_password") is False: # Prepare system for autologin. # LightDM needs the user to be in the autologin group. chroot_call(["groupadd", "autologin"]) default_groups += ",autologin" cmd = ["useradd", "-m", "-s", "/bin/bash", "-g", "users", "-G", default_groups, username] chroot_call(cmd) logging.debug("User %s added.", username) self.change_user_password(username, password) chroot_call(["chfn", "-f", fullname, username]) home_dir = os.path.join("/home", username) cmd = ["chown", "-R", "{0}:users".format(username), home_dir] chroot_call(cmd) # Set hostname hostname_path = os.path.join(DEST_DIR, "etc/hostname") if not os.path.exists(hostname_path): with open(hostname_path, "w") as hostname_file: hostname_file.write(hostname) logging.debug("Hostname set to %s", hostname) # User password is the root password self.change_user_password("root", password) logging.debug("Set the same password to root.") # Generate locales locale = self.settings.get("locale") self.queue_event("info", _("Generating locales...")) self.uncomment_locale_gen(locale) chroot_call(["locale-gen"]) locale_conf_path = os.path.join(DEST_DIR, "etc/locale.conf") with open(locale_conf_path, "w") as locale_conf: locale_conf.write("LANG={0}\n".format(locale)) locale_conf.write("LC_COLLATE={0}\n".format(locale)) # environment_path = os.path.join(DEST_DIR, "etc/environment") # with open(environment_path, "w") as environment: # environment.write('LANG={0}\n'.format(locale)) self.queue_event("info", _("Adjusting hardware clock...")) self.auto_timesetting() self.queue_event("info", _("Configuring keymap...")) if self.desktop != "base": self.set_keyboard_conf() self.set_vconsole_conf() # Install configs for root chroot_call(["cp", "-av", "/etc/skel/.", "/root/"]) self.queue_event("info", _("Configuring hardware...")) # Copy generated xorg.conf to target if os.path.exists("/etc/X11/xorg.conf"): src = "/etc/X11/xorg.conf" dst = os.path.join(DEST_DIR, "etc/X11/xorg.conf") shutil.copy2(src, dst) # Configure ALSA # self.alsa_mixer_setup() # logging.debug("Updated Alsa mixer settings") # Set pulse # if os.path.exists(os.path.join(DEST_DIR, "usr/bin/pulseaudio-ctl")): # chroot_run(['pulseaudio-ctl', 'normal']) # Set fluidsynth audio system (in our case, pulseaudio) self.set_fluidsynth() logging.debug("Updated fluidsynth configuration file") # Workaround for pacman-key bug FS#45351 # https://bugs.archlinux.org/task/45351 # We have to kill gpg-agent because if it stays around we can't # reliably unmount the target partition. logging.debug("Stopping gpg agent...") chroot_call(["killall", "-9", "gpg-agent"]) # FIXME: Temporary workaround for spl and zfs packages if self.method == "zfs": zfs_version = self.get_zfs_version() logging.debug("Installing zfs modules v%s...", zfs_version) chroot_call(["dkms", "install", "spl/{0}".format(zfs_version)]) chroot_call(["dkms", "install", "zfs/{0}".format(zfs_version)]) # Let's start without using hwdetect for mkinitcpio.conf. # It should work out of the box most of the time. # This way we don't have to fix deprecated hooks. # NOTE: With LUKS or LVM maybe we'll have to fix deprecated hooks. self.queue_event("info", _("Configuring System Startup...")) mkinitcpio.run(DEST_DIR, self.settings, self.mount_devices, self.blvm) logging.debug("Running Cnchi post-install script") keyboard_layout = self.settings.get("keyboard_layout") keyboard_variant = self.settings.get("keyboard_variant") # Call post-install script to fine tune our setup script_path_postinstall = os.path.join(self.settings.get("cnchi"), "scripts", POSTINSTALL_SCRIPT) cmd = [ "/usr/bin/bash", script_path_postinstall, username, DEST_DIR, self.desktop, locale, str(self.vbox), keyboard_layout, ] # Keyboard variant is optional if keyboard_variant: cmd.append(keyboard_variant) call(cmd, timeout=300) logging.debug("Post install script completed successfully.") # Patch user-dirs-update-gtk.desktop self.patch_user_dirs_update_gtk() logging.debug("File user-dirs-update-gtk.desktop patched.") # Set lightdm config including autologin if selected if self.desktop != "base": self.setup_display_manager() # Configure user features (firewall, libreoffice language pack, ...) self.setup_features() # Encrypt user's home directory if requested # FIXME: This is not working atm if self.settings.get("encrypt_home"): self.queue_event("info", _("Encrypting user home dir...")) encfs.setup(username, DEST_DIR) logging.debug("User home dir encrypted") # Install boot loader (always after running mkinitcpio) if self.settings.get("bootloader_install"): try: self.queue_event("info", _("Installing bootloader...")) from installation.boot import loader boot_loader = loader.Bootloader(DEST_DIR, self.settings, self.mount_devices) boot_loader.install() except Exception as ex: template = "Cannot install bootloader. An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) logging.error(message) # Create an initial database for mandb self.queue_event("info", _("Updating man pages...")) chroot_call(["mandb", "--quiet"]) # Initialise pkgfile (pacman .files metadata explorer) database logging.debug("Updating pkgfile database") chroot_call(["pkgfile", "--update"]) # Copy installer log to the new installation logging.debug("Copying install log to /var/log.") self.copy_log() self.queue_event("pulse", "stop") self.queue_event("progress_bar", "hide")
def run(dest_dir, settings, mount_devices, blvm): """ Runs mkinitcpio """ cpu = get_cpu() # Add lvm and encrypt hooks if necessary hooks = [ "base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap" ] modules = [] # It is important that the plymouth hook comes before any encrypt hook plymouth_bin = os.path.join(dest_dir, "usr/bin/plymouth") if os.path.exists(plymouth_bin): hooks.append("plymouth") # It is important that the encrypt hook comes before the filesystems hook # (in case you are using LVM on LUKS, the order should be: encrypt lvm2 filesystems) if settings.get("use_luks"): if os.path.exists(plymouth_bin): hooks.append("plymouth-encrypt") else: hooks.append("encrypt") modules.extend(["dm_mod", "dm_crypt", "ext4"]) arch = os.uname()[-1] if arch == 'x86_64': modules.extend(["aes_x86_64"]) else: modules.extend(["aes_i586"]) modules.extend(["sha256", "sha512"]) if settings.get("f2fs"): modules.append("f2fs") if blvm or settings.get("use_lvm"): hooks.append("lvm2") if "swap" in mount_devices: hooks.append("resume") if settings.get("zfs"): # the zfs hook must come before the filesystems hook hooks.append("zfs") hooks.append("filesystems") if settings.get('btrfs'): if cpu is 'genuineintel': modules.append('crc32c-intel') else: modules.append('crc32c') if not settings.get('btrfs') and not settings.get("zfs"): # Use the fsck hook only if not using btrfs or zfs hooks.append("fsck") set_hooks_and_modules(dest_dir, hooks, modules) # Run mkinitcpio on the target system # Fix for bsdcpio error. See: http://forum.antergos.com/viewtopic.php?f=5&t=1378&start=20#p5450 locale = settings.get('locale') cmd = ['sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux'.format(locale)] chroot_call(cmd, dest_dir) if settings.get('feature_lts'): cmd = [ 'sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux-lts'.format(locale) ] chroot_call(cmd, dest_dir)
def install(self): """ Install Systemd-boot bootloader to the EFI System Partition """ logging.debug("Cnchi will install the Systemd-boot (Gummiboot) loader") # Setup bootloader menu menu_dir = os.path.join(self.dest_dir, "boot/loader") os.makedirs(menu_dir, mode=0o755, exist_ok=True) menu_path = os.path.join(menu_dir, "loader.conf") with open(menu_path, 'w') as menu_file: menu_file.write("default antergos") # Setup boot entries conf = {} options = "" if not self.settings.get('use_luks'): options = "root=UUID={0} rw quiet".format(self.uuids["/"]) else: luks_root_volume = self.settings.get('luks_root_volume') logging.debug("Luks Root Volume: %s", luks_root_volume) mapper = "/dev/mapper/{0}".format(luks_root_volume) luks_root_volume_uuid = fs.get_uuid(mapper) if (self.settings.get("partition_mode") == "advanced" and self.settings.get('use_luks_in_root')): # In advanced, if using luks in root device, # we store root device it in luks_root_device var root_device = self.settings.get('luks_root_device') self.uuids["/"] = root_device key = "" if not self.settings.get("luks_root_password"): key = "cryptkey=UUID={0}:ext2:/.keyfile-root" key = key.format(self.uuids["/boot"]) options = "cryptdevice=UUID={0}:{1} {2} root=UUID={3} rw quiet" options = options.format( self.uuids["/"], luks_root_volume, key, luks_root_volume_uuid) if self.settings.get("zfs"): zfs_pool_name = self.settings.get("zfs_pool_name") options += ' zfs={0}'.format(zfs_pool_name) conf['default'] = [] conf['default'].append("title\tAntergos\n") conf['default'].append("linux\t/vmlinuz-linux\n") conf['default'].append("initrd\t/initramfs-linux.img\n") conf['default'].append("options\t{0}\n\n".format(options)) conf['fallback'] = [] conf['fallback'].append("title\tAntergos (fallback)\n") conf['fallback'].append("linux\t/vmlinuz-linux\n") conf['fallback'].append("initrd\t/initramfs-linux-fallback.img\n") conf['fallback'].append("options\t{0}\n\n".format(options)) if self.settings.get('feature_lts'): conf['lts'] = [] conf['lts'].append("title\tAntergos LTS\n") conf['lts'].append("linux\t/vmlinuz-linux-lts\n") conf['lts'].append("initrd\t/initramfs-linux-lts.img") conf['lts'].append("options\t{0}\n\n".format(options)) conf['lts_fallback'] = [] conf['lts_fallback'].append("title\tAntergos LTS (fallback)\n") conf['lts_fallback'].append("linux\t/vmlinuz-linux-lts\n") conf['lts_fallback'].append("initrd\t/initramfs-linux-lts-fallback.img") conf['lts_fallback'].append("options\t{0}\n\n".format(options)) # Write boot entries entries_dir = os.path.join(self.dest_dir, "boot/loader/entries") os.makedirs(entries_dir, mode=0o755, exist_ok=True) entry_path = os.path.join(entries_dir, "antergos.conf") with open(entry_path, 'w') as entry_file: for line in conf['default']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['fallback']: entry_file.write(line) if self.settings.get('feature_lts'): entry_path = os.path.join(entries_dir, "antergos-lts.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts']: entry_file.write(line) entry_path = os.path.join(entries_dir, "antergos-lts-fallback.conf") with open(entry_path, 'w') as entry_file: for line in conf['lts_fallback']: entry_file.write(line) # Install bootloader logging.debug("Installing systemd-boot bootloader...") cmd = ['bootctl', '--path=/boot', 'install'] if chroot_call(cmd, self.dest_dir, 300) is False: self.settings.set('bootloader_installation_successful', False) else: self.settings.set('bootloader_installation_successful', True)
def run(dest_dir, settings, mount_devices, blvm): """ Runs mkinitcpio """ cpu = get_cpu() # Add lvm and encrypt hooks if necessary hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] modules = [] # It is important that the plymouth hook comes before any encrypt hook plymouth_bin = os.path.join(dest_dir, "usr/bin/plymouth") if os.path.exists(plymouth_bin): hooks.append("plymouth") # It is important that the encrypt hook comes before the filesystems hook # (in case you are using LVM on LUKS, the order should be: encrypt lvm2 filesystems) if settings.get("use_luks"): if os.path.exists(plymouth_bin): hooks.append("plymouth-encrypt") else: hooks.append("encrypt") modules.extend(["dm_mod", "dm_crypt", "ext4"]) arch = os.uname()[-1] if arch == 'x86_64': modules.extend(["aes_x86_64"]) else: modules.extend(["aes_i586"]) modules.extend(["sha256", "sha512"]) if settings.get("f2fs"): modules.append("f2fs") if blvm or settings.get("use_lvm"): hooks.append("lvm2") if "swap" in mount_devices: hooks.append("resume") if settings.get("zfs"): # the zfs hook must come before the filesystems hook hooks.append("zfs") hooks.append("filesystems") if settings.get('btrfs'): if cpu is 'genuineintel': modules.append('crc32c-intel') else: modules.append('crc32c') if not settings.get('btrfs') and not settings.get("zfs"): # Use the fsck hook only if not using btrfs or zfs hooks.append("fsck") set_hooks_and_modules(dest_dir, hooks, modules) # Run mkinitcpio on the target system # Fix for bsdcpio error. See: http://forum.antergos.com/viewtopic.php?f=5&t=1378&start=20#p5450 locale = settings.get('locale') cmd = ['sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux'.format(locale)] chroot_call(cmd, dest_dir) if settings.get('feature_lts'): cmd = ['sh', '-c', 'LANG={0} /usr/bin/mkinitcpio -p linux-lts'.format(locale)] chroot_call(cmd, dest_dir)
def setup(ssid=None, passphrase=None): """ Configure system-networkd for base installs """ # For compatibility with resolv.conf, delete the existing file and # create the following symbolic link: source = os.path.join("/run/systemd/resolve/resolv.conf") link_name = os.path.join(DEST_DIR, "etc/resolv.conf") # Delete /etc/resolv.conf if it already exists if os.path.exists(link_name): os.unlink(link_name) # Creates the symlink try: os.symlink(source, link_name) except OSError as os_error: logging.warning(os_error) # Get interface names (links) links = [] links_wireless = [] try: cmd = ['networkctl', 'list'] output = subprocess.check_output(cmd).decode().split('\n') for line in output: fields = line.split() if len(fields) > 0: link = fields[1] if link.startswith("eth") or link.startswith("enp"): links.append(link) elif link.startswith("wlp"): links.append(link) links_wireless.append(link) except subprocess.CalledProcessError as process_error: logging.warning( "systemd-networkd configuration failed: %s", process_error) return logging.debug( "Found [%s] links and [%s] are wireless", " ".join(links), " ".join(links_wireless)) # Setup DHCP by default for all interfaces found for link in links: fname = "etc/systemd/network/{0}.network".format(link) wired_path = os.path.join(DEST_DIR, fname) with open(wired_path, 'w') as wired_file: wired_file.write( "# {0} adapter using DHCP (written by Cnchi)\n".format(link)) wired_file.write("[Match]\n") wired_file.write("Name={0}\n\n".format(link)) wired_file.write("[Network]\n") wired_file.write("DHCP=ipv4\n") logging.debug("Created %s configuration file", wired_path) # One needs to have configured a wireless adapter with another service # such as wpa_supplicant and the corresponding service is required to be enabled. # /etc/wpa_supplicant/wpa_supplicant-interface.conf. # systemctl enable wpa_supplicant@interface # Setup wpa_supplicant. We need the SID and the passphrase # TODO: Ask for different sid's or passphrases for each interface if ssid is not None and passphrase is not None: for link in links_wireless: conf_path = os.path.join( DEST_DIR, "etc/wpa_supplicant/wpa_supplicant-{0}.conf".format(link)) try: conf = subprocess.check_output( ["wpa_passphrase", ssid, passphrase]) with open(conf_path, "w") as conf_file: conf_file.write(conf) except subprocess.CalledProcessError as process_error: logging.warning(process_error) cmd = ["systemctl", "enable", "wpa_supplicant@{0}".format(link)] chroot_call(cmd)
def setup(ssid=None, passphrase=None): """ Configure system-networkd for base installs """ # For compatibility with resolv.conf, delete the existing file and # create the following symbolic link: source = os.path.join("/run/systemd/resolve/resolv.conf") link_name = os.path.join(DEST_DIR, "etc/resolv.conf") # Delete /etc/resolv.conf if it already exists if os.path.exists(link_name): os.unlink(link_name) # Creates the symlink try: os.symlink(source, link_name) except OSError as os_error: logging.warning(os_error) # Get interface names (links) links = [] links_wireless = [] try: cmd = ['networkctl', 'list'] output = subprocess.check_output(cmd).decode().split('\n') for line in output: fields = line.split() if len(fields) > 0: link = fields[1] if link.startswith("eth") or link.startswith("enp"): links.append(link) elif link.startswith("wlp"): links.append(link) links_wireless.append(link) except subprocess.CalledProcessError as process_error: logging.warning("systemd-networkd configuration failed: %s", process_error) return logging.debug( "Found [%s] links and [%s] are wireless", " ".join(links), " ".join(links_wireless)) # Setup DHCP by default for all interfaces found for link in links: fname = "etc/systemd/network/{0}.network".format(link) wired_path = os.path.join(DEST_DIR, fname) with open(wired_path, 'w') as wired_file: wired_file.write("# {0} adapter using DHCP (written by Cnchi)\n".format(link)) wired_file.write("[Match]\n") wired_file.write("Name={0}\n\n".format(link)) wired_file.write("[Network]\n") wired_file.write("DHCP=ipv4\n") logging.debug("Created %s configuration file", wired_path) # One needs to have configured a wireless adapter with another service # such as wpa_supplicant and the corresponding service is required to be enabled. # /etc/wpa_supplicant/wpa_supplicant-interface.conf. # systemctl enable wpa_supplicant@interface # Setup wpa_supplicant. We need the SID and the passphrase # TODO: Ask for different sid's or passphrases for each interface if ssid is not None and passphrase is not None: for link in links_wireless: conf_path = os.path.join( DEST_DIR, "etc/wpa_supplicant/wpa_supplicant-{0}.conf".format(link)) try: conf = subprocess.check_output(["wpa_passphrase", ssid, passphrase]) with open(conf_path, "w") as conf_file: conf_file.write(conf) except subprocess.CalledProcessError as process_error: logging.warning(process_error) cmd = ["systemctl", "enable", "wpa_supplicant@{0}".format(link)] chroot_call(cmd)
def run(params, dest_dir="/install"): """ Setup ufw """ cmd = ["ufw"] cmd.extend(params) if not _UFW: # Could not import ufw module (missing?) # Will call ufw command directly try: chroot_call(cmd, dest_dir) except OSError as os_error: logging.warning(os_error) return app_action = False # Remember, will have to take --force into account if we use it with 'app' idx = 1 if len(cmd) > 1 and cmd[1].lower() == "--dry-run": idx += 1 if len(cmd) > idx and cmd[idx].lower() == "app": app_action = True res = "" try: cmd_line = ufw.frontend.parse_command(cmd) ui = ufw.frontend.UFWFrontend(cmd_line.dryrun) if app_action and 'type' in cmd_line.data and cmd_line.data['type'] == 'app': res = ui.do_application_action(cmd_line.action, cmd_line.data['name']) else: bailout = False if cmd_line.action == "enable" and not cmd_line.force and \ not ui.continue_under_ssh(): res = _("Aborted") bailout = True if not bailout: if 'rule' in cmd_line.data: res = ui.do_action( cmd_line.action, cmd_line.data['rule'], cmd_line.data['iptype'], cmd_line.force) else: res = ui.do_action( cmd_line.action, "", "", cmd_line.force) except (ValueError, ufw.UFWError) as ufw_error: logging.error(ufw_error) # Error using ufw module # Will call ufw command directly try: chroot_call(cmd, dest_dir) except OSError as os_error: logging.warning(os_error) return logging.debug(res)