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
Exemple #2
0
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
Exemple #5
0
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')
Exemple #6
0
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'])
Exemple #8
0
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'])
Exemple #9
0
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')