def update_config(cfg_name, cfg_list): """ Update xml files """ lines = [] header = text_strip_margin( """ |<?xml version="1.0"?> |<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> | |<!-- Put site-specific property overrides in this file. --> | |<configuration> |""") lines.append(header) for entry in cfg_list: property = text_strip_margin( """ | <property> | <name>{0}</name> | <value>{1}</value> | </property> |""".format(entry, cfg_list[entry])) lines.append(property) footer = '</configuration>\n' lines.append(footer) file = '/usr/lib/hadoop/conf/' + cfg_name + '.xml' text = '\n'.join(lines) + '\n' file_write(file, text, sudo=True)
def install_usb_wifi(ssid, psk): """ Configures a generic USB WiFi device for DHCP. This overwrites /etc/network/interfaces, so any changes you have made will be lost; eth0 is reset to DHCP. usage: install_usb_wifi:ssid=<MY_SSID>,psk=<MY_PSK> """ puts(green("Installing USB WiFi device")) wpa_conf = text_strip_margin(""" |network={{ | ssid="{ssid}" | proto=RSN | key_mgmt=WPA-PSK | pairwise=CCMP TKIP | group=CCMP TKIP | psk="{psk}" |}} """.format(ssid=ssid, psk=psk)) interfaces = text_strip_margin(""" |auto lo |iface lo inet loopback |iface eth0 inet dhcp |auto wlan0 |iface wlan0 inet dhcp |wpa-conf /etc/wpa.conf """) sudo("ifdown --force wlan0; true") sudo_file_write("/etc/network/interfaces", interfaces) sudo_file_write("/etc/wpa.conf", wpa_conf) sudo("ifup wlan0")
def _condition_ubuntu_network(self): text = text_strip_margin(""" |# This file describes the network interfaces available on your system |# and how to activate them. For more information, see interfaces(5). | |# The loopback network interface |auto lo |iface lo inet loopback |""") file_path = "/mnt/etc/network/interfaces" with mode_sudo(): file_write(file_path, text) for iface in self.interfaces['add']: bootp = self.interfaces['add'][iface]['bootp'] if bootp == 'dhcp': text = text_strip_margin(""" |# {iface} |auto {iface} |iface {iface} inet dhcp |""".format(iface=iface)) with mode_sudo(): file_append(file_path, text) elif bootp == 'static': address = self.interfaces['add'][iface]['address'] netmask = self.interfaces['add'][iface]['netmask'] text = text_strip_margin(""" |# {iface} |auto {iface} |iface {iface} inet static | address {addr} | netmask {mask} |""".format(iface=iface, addr=address, mask=netmask)) with mode_sudo(): file_append(file_path, text) try: gateway = self.interfaces['add'][iface]['gateway'] except: gateway = None if gateway: text = " gateway {g}\n".format(g=gateway) with mode_sudo(): file_append(file_path, text) try: dnsserver = self.interfaces['add'][iface]['dnsserver'] except: dnsserver = None if dnsserver: text = " dns-nameservers {d}\n".format(d=dnsserver) with mode_sudo(): file_append(file_path, text) else: raise TypeError("network_config: {0} is not supported.\n".format(iface))
def _condition_centos_network(self): for iface in self.interfaces['add']: file_path = "/mnt/etc/sysconfig/network-scripts/ifcfg-" + iface bootp = self.interfaces['add'][iface]['bootp'] if bootp == 'dhcp': text = text_strip_margin(""" |#TEEFAA-BEGIN |# The contents below are automatically generated by Teefaa. Do not modify. |DEVICE="{iface}" |BOOTPROTO="dhcp" |NM_CONTROLLED="no" |ONBOOT="yes" |TYPE="Ethernet" |#TEEFAA-END |""".format(iface=iface)) with mode_sudo(): file_write(file_path, text) elif bootp == 'static': address = self.interfaces['add'][iface]['address'] netmask = self.interfaces['add'][iface]['netmask'] text = text_strip_margin(""" |# The contents below are automatically generated by Teefaa. Do not modify. |NM_CONTROLLED=no |BOOTPROTO=none |ONBOOT=yes |IPADDR={addr} |NETMASK={mask} |DEVICE={iface} |PEERDNS=no |""".format(iface=iface, addr=address, mask=netmask)) with mode_sudo(): file_write(file_path, text) try: gateway = self.interfaces['add'][iface]['gateway'] text = "GATEWAY=" + gateway + '\n' with mode_sudo(): file_append(file_path, text) except: pass try: dnsserver = self.interfaces['add'][iface]['dnsserver'] except: dnsserver = None if dnsserver: text = "DNS1={d}\n".format(d=dnsserver) with mode_sudo(): file_append(file_path, text)
def _condition_ubuntu_fstab(self): time.sleep(1) file_path = "/mnt/etc/fstab" label_type = self.disk_config['label_type'] device = self.disk_config['device'] system_format = self.disk_config['system']['format'] if label_type == 'mbr': num = 0 elif label_type == 'gpt': num = 1 text = text_strip_margin(""" |#TEEFAA-BEGIN |# /etc/fstab: static file system information. |# |# Use 'blkid' to print the universally unique identifier for a |# device; this may be used with UUID= as a more robust way to name devices |# that works even if disks are added and removed. See fstab(5). |# |# <file system> <mount point> <type> <options> <dump> <pass> |proc /proc proc nodev,noexec,nosuid 0 0 |{device}{swap_num} none swap sw 0 0 |{device}{system_num} / {system_format} errors=remount-ro 0 1 |#TEEFAA-END |""".format(device=device, swap_num=num+1, system_num=num+2, system_format=system_format)) with mode_sudo(): file_write(file_path, text)
def _condition_ubuntu_mtab(self): time.sleep(1) file_path = "/mnt/etc/mtab" label_type = self.disk_config['label_type'] device = self.disk_config['device'] system_format = self.disk_config['system']['format'] if label_type == 'mbr': num = 0 elif label_type == 'gpt': num = 1 text = text_strip_margin(""" |{device}{system_num} / {system_format} rw,errors=remount-ro 0 0 |proc /proc proc rw,noexec,nosuid,nodev 0 0 |sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0 |none /sys/fs/fuse/connections fusectl rw 0 0 |none /sys/kernel/debug debugfs rw 0 0 |none /sys/kernel/security securityfs rw 0 0 |udev /dev devtmpfs rw,mode=0755 0 0 |devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=0620 0 0 |tmpfs /run tmpfs rw,noexec,nosuid,size=10%,mode=0755 0 0 |none /run/lock tmpfs rw,noexec,nosuid,nodev,size=5242880 0 0 |none /run/shm tmpfs rw,nosuid,nodev 0 0 |rpc_pipefs /run/rpc_pipefs rpc_pipefs rw 0 0 |""".format(device=device, system_num=num+2, system_format=system_format)) with mode_sudo(): file_write(file_path, text)
def _condition_centos_fstab(self): time.sleep(1) file_path = "/mnt/etc/fstab" label_type = self.disk_config['label_type'] device = self.disk_config['device'] system_format = self.disk_config['system']['format'] if label_type == 'mbr': num = 0 elif label_type == 'gpt': num = 1 text = text_strip_margin(""" |#TEEFAA-BEGIN |# /etc/fstab |# Created by Teefaa |# |# Accessible filesystems, by reference, are maintained under '/dev/disk' |# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info |# |{device}{system_num} / {system_format} defaults 1 1 |{device}{swap_num} swap swap defaults 0 0 |tmpfs /dev/shm tmpfs defaults 0 0 |devpts /dev/pts devpts gid=5,mode=620 0 0 |sysfs /sys sysfs defaults 0 0 |proc /proc proc defaults 0 0 |#TEEFAA-END |""".format(device=device, swap_num=num+1, system_num=num+2, system_format=system_format)) with mode_sudo(): file_write(file_path, text)
def _do_provision(self, args): if args.no_reboot: print("Starts provisioning without reboot.") else: execute(boot_installer) check_ssh() execute(make_partition) time.sleep(2) execute(make_swap) time.sleep(2) execute(make_fs) time.sleep(2) execute(mount_partition) time.sleep(2) execute(install_snapshot) time.sleep(2) execute(condition) time.sleep(2) execute(install_grub) time.sleep(2) print("Done.") if args.no_reboot: text = text_strip_margin(""" | |IMPORTANT: | Remove Teefaa ISO image, or change PXE config | to boot the machine with localdisk, then reboot. |""") print(text) else: execute(boot_disk)
def install_motd(): """ Installs a succulent ascii-art MOTD. In colour! The raspberry was by RPi forum user b3n, taken from http://www.raspberrypi.org/phpBB3/viewtopic.php?f=2&t=5494 """ puts(green("Installing succulent MOTD")) motd = text_strip_margin(""" | |{g} .~~. .~~. |{g} ". \ " " / ." |{r} .~ .~~~..~. |{r} : .~."~".~. : {b} __ {o} _ |{r} ~ ( ) ( ) ~ {b} _______ ____ ___ / / ___ __________ __ {o}___ (_) |{r} ( : "~".~."~" : ) {b} / __/ _ `(_-</ _ \/ _ \/ -_) __/ __/ // / {o}/ _ \/ / |{r} ~ .~ ( ) ~. ~ {p} /_/ \_,_/___/ .__/_.__/\__/_/ /_/ \_, / {o}/ .__/_/ |{r} ( : "~" : ) {p} /_/ /___/ {o}/_/ |{r} "~ .~~~. ~" |{r} "~" |{n} | |""".format( g="[32m", r="[31m", b="[34m", o="[33m", p="[35m", n="[m", )) with hide("output", "running"): sudo_file_write("/etc/motd", motd)
def install_motd(): """ Installs a succulent ascii-art MOTD. In colour! The raspberry was by RPi forum user b3n, taken from http://www.raspberrypi.org/phpBB3/viewtopic.php?f=2&t=5494 """ puts(green("Installing succulent MOTD")) motd = text_strip_margin(""" | |{g} .~~. .~~. |{g} ". \ " " / ." |{r} .~ .~~~..~. |{r} : .~."~".~. : {b} __ {o} _ |{r} ~ ( ) ( ) ~ {b} _______ ____ ___ / / ___ __________ __ {o}___ (_) |{r} ( : "~".~."~" : ) {b} / __/ _ `(_-</ _ \/ _ \/ -_) __/ __/ // / {o}/ _ \/ / |{r} ~ .~ ( ) ~. ~ {p} /_/ \_,_/___/ .__/_.__/\__/_/ /_/ \_, / {o}/ .__/_/ |{r} ( : "~" : ) {p} /_/ /___/ {o}/_/ |{r} "~ .~~~. ~" |{r} "~" |{n} | |""".format( g="[32m", r="[31m", b="[34m", o="[33m", p="[35m", n="[m", ) ) with hide("output", "running"): sudo_file_write("/etc/motd", motd)
def _clean_tmp(self): text = text_strip_margin(""" |The system copy is still stored on /tmp/teefaa on {h}. |Right now, Teefaa doesn't delete it for security reason. |So please go check and delete it as needed. |""".format(h=env.host_string)) print(text)
def _condition_centos_hostname(self): file_path = "/mnt/etc/sysconfig/network" text = text_strip_margin(""" |NETWORKING=yes |HOSTNAME={h} |""".format(h=self.hostname)) with mode_sudo(): file_write(file_path, text)
def _update_grub_conf(self): device = self.device rootp = self.rootp distro = self.distro cmd = ['ls', '-t1', '/mnt/boot/vmlinuz*'] output = sudo(' '.join(cmd)) kernel = output.split('\n')[0].split('/')[3].rstrip('\r') cmd = ['ls', '-t1', '/mnt/boot/initramfs*'] output = sudo(' '.join(cmd)) ramdisk = output.split('\n')[0].split('/')[3].rstrip('\r') if device == '/dev/sda': hd = 'hd0' elif device == '/dev/sdb': hd = 'hd1' elif device == '/dev/sdc': hd = 'hd2' else: raise TypeError, "the device is not support." num = rootp - 1 kernel_options = ['rd_NO_LUKS', 'LANG=en_US.UTF-8', 'rd_NO_MD', 'SYSFONT=latarcyrheb-sun16', 'crashkernel=auto', 'KEYBOARDTYPE=pc', 'KEYTABLE=us', 'rd_NO_DM', 'notsc', 'clocksource=acpi_pm'] file_path = "/mnt/boot/grub/grub.conf" text = text_strip_margin(""" |# grub.conf generated by Teefaa |#boot={device} |default=0 |timeout=5 |splashimage=({hd},{num})/boot/grub/splash.xpm.gz |hiddenmenu |title {distro} ({kernel}) | root ({hd},{num}) | kernel /boot/{kernel} ro root={device}{rootp} {options} | initrd /boot/{ramdisk} |""".format( device=device, hd=hd, num=num, kernel=kernel, ramdisk=ramdisk, distro=distro, rootp=rootp, options=' '.join(kernel_options))) with mode_sudo(): file_write(file_path, text, mode=600)
def install_mpd(): """ Installs MPD and configures it for the 3.5mm audio output. Allows passwordless connection from any host on port 6600. """ package_ensure("mpc") package_ensure("mpd") package_ensure("ufw") with hide("output", "running"): sudo("ufw allow proto tcp from any to any port 6600") sudo("ufw --force enable") mpd = text_strip_margin(""" |music_directory "/var/lib/mpd/music" |playlist_directory "/var/lib/mpd/playlists" |db_file "/var/lib/mpd/tag_cache" |log_file "/var/log/mpd/mpd.log" |pid_file "/var/run/mpd/pid" |state_file "/var/lib/mpd/state" |sticker_file "/var/lib/mpd/sticker.sql" |user "mpd" |port "6600" |filesystem_charset "UTF-8" |id3v1_encoding "UTF-8" |follow_outside_symlinks "yes" |follow_inside_symlinks "yes" |zeroconf_enabled "yes" |zeroconf_name "Raspberry Pi" |volume_normalization "yes" |max_connections "10" |input { | plugin "curl" |} |audio_output { | type "alsa" | name "3.5mm Headphone Jack" | device "hw:0,0" | format "44100:16:2" | mixer_device "default" | mixer_control "PCM" | mixer_index "0" |} |audio_output { | type "alsa" | name "USB Audio" | device "hw:0,0" | format "44100:16:2" | mixer_device "software" | mixer_control "PCM" | mixer_index "1" |} |mixer_type "software" """) sudo_file_write("/etc/mpd.conf", mpd) sudo("/etc/init.d/mpd restart")
def print_logo(): text = text_strip_margin(""" | | _|_|_|_|_| _|_| | |_| _|_| _|_| _| _|_|_| _|_|_| | |_| _|_|_|_| _|_|_|_| _|_|_|_| _| _| _| _| | |_| _| _| _| _| _| _| _| | |_| _|_|_| _|_|_| _| _|_|_| _|_|_| |""") print(text) time.sleep(1)
def _run_squashfs(self): print("Starts making a snapshot of machine '{0}'...".format(env.host_string)) self._install_required_packages() self._copy_system_to_tmp() self._make_squashfs() self._download_squashfs() self._clean_tmp() text = text_strip_margin(""" |Done... | |Snapshot is downloaded and saved as {f}. |""".format(f=self.save_as)) print(text)
def _create_vagrantfile(self): if not os.path.isfile(self.vagrantfile): text = text_strip_margin(""" |Vagrant.configure("2") do |config| | config.vm.define :{host} do |{host}| | {host}.vm.box = 'tf-ubuntu-12.04' | {host}.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box' | {host}.vm.hostname = '{host}' | end |end |""".format(host=self.hostname)) with open(self.vagrantfile, 'w') as f: f.write(text)
def _update_menu_cfg(self): """ Update menu.cfg """ menu_cfg_file = "isolinux/menu.cfg" new_menu_cfg = text_strip_margin(""" |DEFAULT Teefaa |TIMEOUT 10 |TOTALTIMEOUT 20 | |LABEL Teefaa | MENU LABEL Teefaa | KERNEL /live/vmlinuz | APPEND initrd=/live/initrd.img boot=live config quiet noprompt noeject |""") do_sudo(['chmod', 'u+w', menu_cfg_file]) file_write(menu_cfg_file, new_menu_cfg, sudo=True)
def _condition_centos_mtab(self): time.sleep(1) file_path = "/mnt/etc/mtab" label_type = self.disk_config['label_type'] device = self.disk_config['device'] system_format = self.disk_config['system']['format'] if label_type == 'mbr': num = 0 elif label_type == 'gpt': num = 1 text = text_strip_margin(""" |{device}{system_num} / {system_format} rw 0 0 |proc /proc proc rw 0 0 |sysfs /sys sysfs rw 0 0 |devpts /dev/pts devpts rw,gid=5,mode=620 0 0 |tmpfs /dev/shm tmpfs rw,rootcontext="system_u:object_r:tmpfs_t:s0" 0 0 |none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0 |""".format(device=device, system_num=num+2, system_format=system_format)) with mode_sudo(): file_write(file_path, text)
def DoIt(): print green("DoIt started") print yellow("Installing packages") cuisine.package_update() cuisine.package_ensure("linux-image-generic-lts-trusty") cuisine.package_ensure("wget") print yellow("Installing docker") sudo("wget -qO- https://get.docker.com/ | sh") print yellow("Adding ubuntu to the docker group") try: cuisine.group_user_ensure("docker", "ubuntu") except: pass print yellow("Creating mldb storage") sudo("install -d -o ubuntu -g ubuntu /mldb_data") print yellow("Setting up the mldb start on boot") confTmpl = cuisine.text_strip_margin( """ |# On the first boot, this will pull the latest mldb Container |# subsequent executions will keep running the same (pulled) version |description "MLDB Container" |author "mldb.ai inc." |start on filesystem and started docker |stop on runlevel [!2345] |respawn |script | /usr/bin/docker run -a stdin -a stdout -a stderr -v /mldb_data:/mldb_data -e MLDB_IDS="1000" -p 127.0.0.1:80:80 quay.io/datacratic/mldb:latest |end script | """): cuisine.file_write("/etc/init/mldb.conf", confTmpl, mode = "644", owner = "root", group = "root", sudo = True, check = True) print yellow("Configuring banner") confTmpl = cuisine.text_strip_margin( """ | The Virtual Appliance has booted, but you do not need to log into the | Virtual Appliance to use MLDB. | | Once MLDB is up and running inside the Virtual Appliance, you will be | able to connect to it via HTTP as per the documentation. | | Note that MLDB can take a few minutes to initialize the first time you | launch the Virtual Appliance. | | """) cuisine.file_write("/etc/issue", confTmpl, mode = "644", owner = "root", group = "root", sudo = True, check = True) print yellow("Removing grub delay") sudo('echo "GRUB_TIMEOUT=0\n" >> /etc/default/grub') sudo("update-grub") print yellow("Cleaning up...") sudo("cat /dev/null > /home/ubuntu/.ssh/authorized_keys")
def _create_teefaafile(self): dot_teefaa = os.path.abspath(self.dot_teefaa_dir) vbox_name = self._check_vbox_name() text = text_strip_margin(""" |ssh_config: {d}/ssh_config_{host} |ssh_key: {d}/ssh_key | |iso_config: | base_iso: debian-live-7.5-amd64-standard.iso | base_iso_url: http://ftp.acc.umu.se/debian-cd/current-live/amd64/iso-hybrid/debian-live-7.5.0-amd64-standard.iso | builder: | hostname: {host} | distro: ubuntu | iso_path: {d}/teefaa-debian-live.iso | |snapshot_config: | snapshot_url: https://s3-us-west-2.amazonaws.com/teefaaimg/ubuntu-12.04.squashfs | snapshot_path: {d}/ubuntu-12.04.squashfs | os: | distro: ubuntu | ver: 12.04 | #snapshot_url: https://s3-us-west-2.amazonaws.com/teefaaimg/centos-6.5.squashfs | #snapshot_path: {d}/centos-6.5.squashfs | #os: | # distro: centos | # ver: 6.5 | hostname: {host} | #exclude: | # - /path/to/exclude/dir | |# VirtualBox |host_config: | hostname: {host} | power_driver: virtualbox | power_driver_config: | vbox_name: {name} | boot_driver: virtualbox | boot_driver_config: | installer_boot: iso | iso_file: {d}/teefaa-debian-live.iso | |# Baremetal |#host_config: |# hostname: host1 |# power_driver: ipmi |# power_driver_config: |# ipmi_password: XXXXXXXXXX |# ipmi_user: ipmiadmin |# bmc_address: <ip address> |# boot_driver: pxe |# boot_driver_config: |# pxe_server: <hostname> |# pxe_server_user: <username> |# boot_config_file: /tftpboot/pxelinux.cfg/01-11-22-aa-bb-cc-dd |# installer_boot_config_file: /tftpboot/pxelinux.cfg/netboot |# disk_boot_config_file: /tftpboot/pxelinux.cfg/localboot | |disk_config: | label_type: mbr | device: /dev/sda | swap: | size: 2 | system: | size: 10 | format: ext4 | data: | size: -1 | dir: /data | format: xfs | |network_config: | add: | eth0: | bootp: dhcp |# eth1: |# bootp: static |# address: 192.168.32.101 |# netmask: 255.255.255.0 |# gateway: 192.168.32.254 |# dnsserver: 192.168.32.1 |""".format(d=dot_teefaa, host=self.hostname, name=vbox_name)) teefaafile = self.hostname + "/Teefaafile.yml" with open(teefaafile, 'w') as f: f.write(text)