def bootstrap(**kwargs): """Digital Oceans FreeBSD droplets are pretty much already pre-bootstrapped, including having python2.7 and sudo etc. pre-installed. the only thing we need to change is to allow root to login (without a password) enable pf and ensure it is running """ bu = BootstrapUtils() # (temporarily) set the user to `freebsd` original_host = env.host_string env.host_string = 'freebsd@%s' % env.instance.uid # copy DO bsdclout-init results: if bu.os_release.startswith('10'): sudo("""cat /etc/rc.digitalocean.d/droplet.conf > /etc/rc.conf""") sudo("""sysrc zfs_enable=YES""") sudo("""sysrc sshd_enable=YES""") # enable and start pf sudo("""sysrc pf_enable=YES""") sudo("""sysrc -f /boot/loader.conf pfload=YES""") sudo('kldload pf', warn_only=True) sudo('''echo 'pass in all' > /etc/pf.conf''') sudo('''echo 'pass out all' >> /etc/pf.conf''') sudo('''chmod 644 /etc/pf.conf''') sudo('service pf start') # overwrite sshd_config, because the DO version only contains defaults # and a line explicitly forbidding root to log in sudo("""echo 'PermitRootLogin without-password' > /etc/ssh/sshd_config""") # additionally, make sure the root user is unlocked! sudo('pw unlock root') # overwrite the authorized keys for root, because DO creates its entries to explicitly # disallow root login bootstrap_files = env.instance.config.get('bootstrap-files', 'bootstrap-files') put(path.abspath(path.join(env['config_base'], bootstrap_files, 'authorized_keys')), '/tmp/authorized_keys', use_sudo=True) sudo('''mv /tmp/authorized_keys /root/.ssh/''') sudo('''chown root:wheel /root/.ssh/authorized_keys''') sudo("""service sshd fastreload""") # revert back to root env.host_string = original_host # give sshd a chance to restart sleep(2) # clean up DO cloudinit leftovers run("rm -f /etc/rc.d/digitalocean") run("rm -rf /etc/rc.digitalocean.d") run("rm -rf /usr/local/bsd-cloudinit/") run("pkg remove -y avahi-autoipd || true") # allow overwrites from the commandline env.instance.config.update(kwargs) bu.ssh_keys = None bu.upload_authorized_keys = False
def fetch_assets(**kwargs): """ download bootstrap assets to control host. If present on the control host they will be uploaded to the target host during bootstrapping. """ # allow overwrites from the commandline env.instance.config.update(kwargs) BootstrapUtils().fetch_assets()
def bootstrap(**kwargs): """Digital Oceans FreeBSD droplets are pretty much already pre-bootstrapped, including having python2.7 and sudo etc. pre-installed. the only thing we need to change is to allow root to login (without a password) enable pf and ensure it is running """ # (temporarily) set the user to `freebsd` original_host = env.host_string env.host_string = 'freebsd@%s' % env.instance.uid # copy DO bsdclout-init results: sudo("""cat /etc/rc.digitalocean.d/droplet.conf > /etc/rc.conf""") sudo("""sysrc zfs_enable=YES""") sudo("""sysrc sshd_enable=YES""") # enable and start pf sudo("""sysrc pf_enable=YES""") sudo("""sysrc -f /boot/loader.conf pfload=YES""") sudo('kldload pf', warn_only=True) sudo('''echo 'pass in all' > /etc/pf.conf''') sudo('''echo 'pass out all' >> /etc/pf.conf''') sudo('''chmod 644 /etc/pf.conf''') sudo('service pf start') # overwrite sshd_config, because the DO version only contains defaults # and a line explicitly forbidding root to log in sudo("""echo 'PermitRootLogin without-password' > /etc/ssh/sshd_config""") sudo("""service sshd fastreload""") # revert back to root env.host_string = original_host # give sshd a chance to restart sleep(2) # clean up DO cloudinit leftovers run("rm /etc/rc.d/digitalocean") run("rm -r /etc/rc.digitalocean.d") run("rm -r /usr/local/bsd-cloudinit/") run("pkg remove -y avahi-autoipd") # allow overwrites from the commandline env.instance.config.update(kwargs) bu = BootstrapUtils() bu.ssh_keys = None bu.upload_authorized_keys = False
def bootstrap(**kwargs): """Digital Oceans FreeBSD droplets are pretty much already pre-bootstrapped, including having python2.7 and sudo etc. pre-installed. the only thing we need to change is to allow root to login (without a password) enable pf and ensure it is running """ # (temporarily) set the user to `freebsd` original_host = env.host_string env.host_string = "freebsd@%s" % env.instance.uid # copy DO bsdclout-init results: sudo("""cat /etc/rc.digitalocean.d/droplet.conf > /etc/rc.conf""") sudo("""sysrc zfs_enable=YES""") sudo("""sysrc sshd_enable=YES""") # enable and start pf sudo("""sysrc pf_enable=YES""") sudo("""sysrc -f /boot/loader.conf pfload=YES""") sudo("kldload pf", warn_only=True) sudo("""echo 'pass in all' > /etc/pf.conf""") sudo("""echo 'pass out all' >> /etc/pf.conf""") sudo("""chmod 644 /etc/pf.conf""") sudo("service pf start") # overwrite sshd_config, because the DO version only contains defaults # and a line explicitly forbidding root to log in sudo("""echo 'PermitRootLogin without-password' > /etc/ssh/sshd_config""") sudo("""service sshd fastreload""") # revert back to root env.host_string = original_host # give sshd a chance to restart sleep(2) # clean up DO cloudinit leftovers run("rm /etc/rc.d/digitalocean") run("rm -r /etc/rc.digitalocean.d") run("rm -r /usr/local/bsd-cloudinit/") run("pkg remove -y avahi-autoipd") # allow overwrites from the commandline env.instance.config.update(kwargs) bu = BootstrapUtils() bu.ssh_keys = None bu.upload_authorized_keys = False
def _bootstrap(): bu = BootstrapUtils() bu.generate_ssh_keys() bu.print_bootstrap_files() # gather infos if not bu.bsd_url: print( "Found no FreeBSD system to install, please specify bootstrap-bsd-url and make sure mfsbsd is running" ) return # get realmem here, because it may fail and we don't want that to happen # in the middle of the bootstrap realmem = bu.realmem print("\nFound the following disk devices on the system:\n %s" % ' '.join(bu.sysctl_devices)) if bu.first_interface: print( "\nFound the following network interfaces, now is your chance to update your rc.conf accordingly!\n %s" % ' '.join(bu.phys_interfaces)) else: print("\nWARNING! Found no suitable network interface!") template_context = { "ploy_jail_host_pkg_repository": "pkg+http://pkg.freeBSD.org/${ABI}/quarterly" } # first the config, so we don't get something essential overwritten template_context.update(env.instance.config) template_context.update(devices=bu.sysctl_devices, interfaces=bu.phys_interfaces, hostname=env.instance.id) rc_conf = bu.bootstrap_files['rc.conf'].read(template_context) if not rc_conf.endswith('\n'): print( "\nERROR! Your rc.conf doesn't end in a newline:\n==========\n%s<<<<<<<<<<\n" % rc_conf) return rc_conf_lines = rc_conf.split('\n') for interface in [ bu.first_interface, env.instance.config.get('ansible-dhcp_host_sshd_interface') ]: if interface is None: continue ifconfig = 'ifconfig_%s' % interface for line in rc_conf_lines: if line.strip().startswith(ifconfig): break else: if not yesno( "\nDidn't find an '%s' setting in rc.conf. You sure that you want to continue?" % ifconfig): return yes = env.instance.config.get('bootstrap-yes', False) if not (yes or yesno( "\nContinuing will destroy the existing data on the following devices:\n %s\n\nContinue?" % ' '.join(bu.devices))): return # install FreeBSD in ZFS root devices_args = ' '.join('-d %s' % x for x in bu.devices) system_pool_name = env.instance.config.get('bootstrap-system-pool-name', 'system') data_pool_name = env.instance.config.get('bootstrap-data-pool-name', 'tank') swap_arg = '' swap_size = env.instance.config.get('bootstrap-swap-size', '%iM' % (realmem * 2)) if swap_size: swap_arg = '-s %s' % swap_size system_pool_arg = '' system_pool_size = env.instance.config.get('bootstrap-system-pool-size', '20G') if system_pool_size: system_pool_arg = '-z %s' % system_pool_size run('destroygeom {devices_args} -p {system_pool_name} -p {data_pool_name}'. format(devices_args=devices_args, system_pool_name=system_pool_name, data_pool_name=data_pool_name)) run('{env_vars}{zfsinstall} {devices_args} -p {system_pool_name} -V 28 -u {bsd_url} {swap_arg} {system_pool_arg}' .format(env_vars=bu.env_vars, zfsinstall=bu.zfsinstall, devices_args=devices_args, system_pool_name=system_pool_name, bsd_url=bu.bsd_url, swap_arg=swap_arg, system_pool_arg=system_pool_arg), shell=False) # create partitions for data pool, but only if the system pool doesn't use # the whole disk anyway if system_pool_arg: for device in bu.devices: run('gpart add -t freebsd-zfs -l {data_pool_name}_{device} {device}' .format(data_pool_name=data_pool_name, device=device)) # mount devfs inside the new system if 'devfs on /rw/dev' not in bu.mounts: run('mount -t devfs devfs /mnt/dev') # setup bare essentials run('cp /etc/resolv.conf /mnt/etc/resolv.conf', warn_only=True) bu.create_bootstrap_directories() bu.upload_bootstrap_files(template_context) bootstrap_packages = ['python27'] if value_asbool(env.instance.config.get('firstboot-update', 'false')): bootstrap_packages.append('firstboot-freebsd-update') run('''touch /mnt/firstboot''') run('''sysrc -f /mnt/etc/rc.conf firstboot_freebsd_update_enable=YES''' ) # we need to install python here, because there is no way to install it via # ansible playbooks bu.install_pkg('/mnt', chroot=True, packages=bootstrap_packages) # set autoboot delay autoboot_delay = env.instance.config.get('bootstrap-autoboot-delay', '-1') run('echo autoboot_delay=%s >> /mnt/boot/loader.conf' % autoboot_delay) bu.generate_remote_ssh_keys() # reboot if value_asbool(env.instance.config.get('bootstrap-reboot', 'true')): with settings(hide('warnings'), warn_only=True): run('reboot')
def bootstrap(**kwargs): """ bootstrap an instance booted into mfsbsd (http://mfsbsd.vx.sk) """ env.shell = '/bin/sh -c' # default ssh settings for mfsbsd with possible overwrite by bootstrap-fingerprint fingerprint = env.instance.config.get( 'bootstrap-fingerprint', '02:2e:b4:dd:c3:8a:b7:7b:ba:b2:4a:f0:ab:13:f4:2d') env.instance.config['fingerprint'] = fingerprint env.instance.config['password-fallback'] = True env.instance.config['password'] = '******' # allow overwrites from the commandline env.instance.config.update(kwargs) bu = BootstrapUtils() bu.generate_ssh_keys() bu.print_bootstrap_files() # gather infos if not bu.bsd_url: print("Found no FreeBSD system to install, please specify bootstrap-bsd-url and make sure mfsbsd is running") return # get realmem here, because it may fail and we don't want that to happen # in the middle of the bootstrap realmem = bu.realmem print("\nFound the following disk devices on the system:\n %s" % ' '.join(bu.sysctl_devices)) if bu.first_interface: print("\nFound the following network interfaces, now is your chance to update your rc.conf accordingly!\n %s" % ' '.join(bu.phys_interfaces)) else: print("\nWARNING! Found no suitable network interface!") template_context = {} # first the config, so we don't get something essential overwritten template_context.update(env.instance.config) template_context.update( devices=bu.sysctl_devices, interfaces=bu.phys_interfaces, hostname=env.instance.id) rc_conf = bu.bootstrap_files['rc.conf'].read(template_context) if not rc_conf.endswith('\n'): print("\nERROR! Your rc.conf doesn't end in a newline:\n==========\n%s<<<<<<<<<<\n" % rc_conf) return rc_conf_lines = rc_conf.split('\n') for interface in [bu.first_interface, env.instance.config.get('ansible-dhcp_host_sshd_interface')]: if interface is None: continue ifconfig = 'ifconfig_%s' % interface for line in rc_conf_lines: if line.strip().startswith(ifconfig): break else: if not yesno("\nDidn't find an '%s' setting in rc.conf. You sure that you want to continue?" % ifconfig): return yes = env.instance.config.get('bootstrap-yes', False) if not (yes or yesno("\nContinuing will destroy the existing data on the following devices:\n %s\n\nContinue?" % ' '.join(bu.devices))): return # install FreeBSD in ZFS root devices_args = ' '.join('-d %s' % x for x in bu.devices) system_pool_name = env.instance.config.get('bootstrap-system-pool-name', 'system') data_pool_name = env.instance.config.get('bootstrap-data-pool-name', 'tank') swap_arg = '' swap_size = env.instance.config.get('bootstrap-swap-size', '%iM' % (realmem * 2)) if swap_size: swap_arg = '-s %s' % swap_size system_pool_arg = '' system_pool_size = env.instance.config.get('bootstrap-system-pool-size', '20G') if system_pool_size: system_pool_arg = '-z %s' % system_pool_size run('destroygeom {devices_args} -p {system_pool_name} -p {data_pool_name}'.format( devices_args=devices_args, system_pool_name=system_pool_name, data_pool_name=data_pool_name)) run('{zfsinstall} {devices_args} -p {system_pool_name} -V 28 -u {bsd_url} {swap_arg} {system_pool_arg}'.format( zfsinstall=bu.zfsinstall, devices_args=devices_args, system_pool_name=system_pool_name, bsd_url=bu.bsd_url, swap_arg=swap_arg, system_pool_arg=system_pool_arg)) # create partitions for data pool, but only if the system pool doesn't use # the whole disk anyway if system_pool_arg: for device in bu.devices: run('gpart add -t freebsd-zfs -l {data_pool_name}_{device} {device}'.format( data_pool_name=data_pool_name, device=device)) # mount devfs inside the new system if 'devfs on /rw/dev' not in bu.mounts: run('mount -t devfs devfs /mnt/dev') # setup bare essentials run('cp /etc/resolv.conf /mnt/etc/resolv.conf') bu.create_bootstrap_directories() bu.upload_bootstrap_files(template_context) # we need to install python here, because there is no way to install it via # ansible playbooks bu.install_pkg('/mnt', chroot=True, packages=['python27']) # set autoboot delay autoboot_delay = env.instance.config.get('bootstrap-autoboot-delay', '-1') run('echo autoboot_delay=%s >> /mnt/boot/loader.conf' % autoboot_delay) bu.generate_remote_ssh_keys() # reboot if value_asbool(env.instance.config.get('bootstrap-reboot', 'true')): with settings(hide('warnings'), warn_only=True): run('reboot')
def bootstrap(**kwargs): """ Bootstrap an EC2 instance that has been booted into an AMI from http://www.daemonology.net/freebsd-on-ec2/ """ # the user for the image is `ec2-user`, there is no sudo, but we can su to root w/o password original_host = env.host_string env.host_string = 'ec2-user@%s' % env.instance.uid bootstrap_files = env.instance.config.get('bootstrap-files', 'bootstrap-files') put('%s/authorized_keys' % bootstrap_files, '/tmp/authorized_keys') put(join(bsdploy_path, 'enable_root_login_on_daemonology.sh'), '/tmp/', mode='0775') run("""su root -c '/tmp/enable_root_login_on_daemonology.sh'""") # revert back to root env.host_string = original_host # give sshd a chance to restart sleep(2) run('rm /tmp/enable_root_login_on_daemonology.sh') # allow overwrites from the commandline env.instance.config.update(kwargs) bu = BootstrapUtils() bu.ssh_keys = None bu.upload_authorized_keys = False bu.bootstrap_files_yaml = 'daemonology-files.yml' bu.print_bootstrap_files() bu.create_bootstrap_directories() bu.upload_bootstrap_files({}) # we need to install python here, because there is no way to install it via # ansible playbooks bu.install_pkg('/', chroot=False, packages=['python27'])
def bootstrap(**kwargs): """ Bootstrap an EC2 instance that has been booted into an AMI from http://www.daemonology.net/freebsd-on-ec2/ Note: deprecated, current AMI images are basically pre-bootstrapped, they just need to be configured. """ # the user for the image is `ec2-user`, there is no sudo, but we can su to root w/o password original_host = env.host_string env.host_string = 'ec2-user@%s' % env.instance.uid bootstrap_files = env.instance.config.get('bootstrap-files', 'bootstrap-files') put('%s/authorized_keys' % bootstrap_files, '/tmp/authorized_keys') put(join(bsdploy_path, 'enable_root_login_on_daemonology.sh'), '/tmp/', mode='0775') run("""su root -c '/tmp/enable_root_login_on_daemonology.sh'""") # revert back to root env.host_string = original_host # give sshd a chance to restart sleep(2) run('rm /tmp/enable_root_login_on_daemonology.sh') # allow overwrites from the commandline env.instance.config.update(kwargs) bu = BootstrapUtils() bu.ssh_keys = None bu.upload_authorized_keys = False bu.bootstrap_files_yaml = 'daemonology-files.yml' bu.print_bootstrap_files() bu.create_bootstrap_directories() bu.upload_bootstrap_files({}) # we need to install python here, because there is no way to install it via # ansible playbooks bu.install_pkg('/', chroot=False, packages=['python27'])
def _bootstrap(): bu = BootstrapUtils() bu.generate_ssh_keys() bu.print_bootstrap_files() # gather infos if not bu.bsd_url: print("Found no FreeBSD system to install, please use 'special edition' or specify bootstrap-bsd-url and make sure mfsbsd is running") return # get realmem here, because it may fail and we don't want that to happen # in the middle of the bootstrap realmem = bu.realmem print("\nFound the following disk devices on the system:\n %s" % ' '.join(bu.sysctl_devices)) if bu.first_interface: print("\nFound the following network interfaces, now is your chance to update your rc.conf accordingly!\n %s" % ' '.join(bu.phys_interfaces)) else: print("\nWARNING! Found no suitable network interface!") template_context = {"ploy_jail_host_pkg_repository": "pkg+http://pkg.freeBSD.org/${ABI}/quarterly"} # first the config, so we don't get something essential overwritten template_context.update(env.instance.config) template_context.update( devices=bu.sysctl_devices, interfaces=bu.phys_interfaces, hostname=env.instance.id) rc_conf = bu.bootstrap_files['rc.conf'].read(template_context) if not rc_conf.endswith('\n'): print("\nERROR! Your rc.conf doesn't end in a newline:\n==========\n%s<<<<<<<<<<\n" % rc_conf) return rc_conf_lines = rc_conf.split('\n') for interface in [bu.first_interface, env.instance.config.get('ansible-dhcp_host_sshd_interface')]: if interface is None: continue ifconfig = 'ifconfig_%s' % interface for line in rc_conf_lines: if line.strip().startswith(ifconfig): break else: if not yesno("\nDidn't find an '%s' setting in rc.conf. You sure that you want to continue?" % ifconfig): return yes = env.instance.config.get('bootstrap-yes', False) if not (yes or yesno("\nContinuing will destroy the existing data on the following devices:\n %s\n\nContinue?" % ' '.join(bu.devices))): return # install FreeBSD in ZFS root devices_args = ' '.join('-d %s' % x for x in bu.devices) system_pool_name = env.instance.config.get('bootstrap-system-pool-name', 'system') data_pool_name = env.instance.config.get('bootstrap-data-pool-name', 'tank') swap_arg = '' swap_size = env.instance.config.get('bootstrap-swap-size', '%iM' % (realmem * 2)) if swap_size: swap_arg = '-s %s' % swap_size system_pool_arg = '' system_pool_size = env.instance.config.get('bootstrap-system-pool-size', '20G') if system_pool_size: system_pool_arg = '-z %s' % system_pool_size run('destroygeom {devices_args} -p {system_pool_name} -p {data_pool_name}'.format( devices_args=devices_args, system_pool_name=system_pool_name, data_pool_name=data_pool_name)) run('{env_vars}{zfsinstall} {devices_args} -p {system_pool_name} -V 28 -u {bsd_url} {swap_arg} {system_pool_arg}'.format( env_vars=bu.env_vars, zfsinstall=bu.zfsinstall, devices_args=devices_args, system_pool_name=system_pool_name, bsd_url=bu.bsd_url, swap_arg=swap_arg, system_pool_arg=system_pool_arg), shell=False) # create partitions for data pool, but only if the system pool doesn't use # the whole disk anyway if system_pool_arg: for device in bu.devices: run('gpart add -t freebsd-zfs -l {data_pool_name}_{device} {device}'.format( data_pool_name=data_pool_name, device=device)) # mount devfs inside the new system if 'devfs on /rw/dev' not in bu.mounts: run('mount -t devfs devfs /mnt/dev') # setup bare essentials run('cp /etc/resolv.conf /mnt/etc/resolv.conf', warn_only=True) bu.create_bootstrap_directories() bu.upload_bootstrap_files(template_context) bootstrap_packages = ['python27'] if value_asbool(env.instance.config.get('firstboot-update', 'false')): bootstrap_packages.append('firstboot-freebsd-update') run('''touch /mnt/firstboot''') run('''sysrc -f /mnt/etc/rc.conf firstboot_freebsd_update_enable=YES''') # we need to install python here, because there is no way to install it via # ansible playbooks bu.install_pkg('/mnt', chroot=True, packages=bootstrap_packages) # set autoboot delay autoboot_delay = env.instance.config.get('bootstrap-autoboot-delay', '-1') run('echo autoboot_delay=%s >> /mnt/boot/loader.conf' % autoboot_delay) bu.generate_remote_ssh_keys() # reboot if value_asbool(env.instance.config.get('bootstrap-reboot', 'true')): with settings(hide('warnings'), warn_only=True): run('reboot')