def install_horizon_service(state, host): apt.packages( {'Install openstack-dashboard'}, ['openstack-dashboard'], ) generate_horizon_config = files.template( state, host, {'Generate horizon config'}, get_template_path('local_settings.py.j2'), '/etc/openstack-dashboard/local_settings.py', ) server.shell( state, host, {'Give www-data access to the secret key'}, 'chown www-data /var/lib/openstack-dashboard/secret_key', ) init.service( state, host, {'Restart apache2'}, 'apache2', restarted=generate_horizon_config.changed, )
def _apt_install(state, host): apt.packages( state, host, {'Install apt requirements to use HTTPS'}, ['apt-transport-https', 'ca-certificates'], ) apt.key( state, host, {'Download the Docker apt key'}, ( 'https://download.docker.com/linux/' '{{ host.fact.lsb_release.id|lower }}/gpg' ), ) add_apt_repo = apt.repo( state, host, {'Add the Docker apt repo'}, ( 'deb [arch=amd64] https://download.docker.com/linux/' '{{ host.fact.lsb_release.id|lower }} ' '{{ host.fact.lsb_release.codename }} stable' ), filename='docker-ce-stable', ) apt.packages( state, host, {'Install Docker via apt'}, 'docker-ce', # Update apt if we added the repo update=add_apt_repo.changed, )
def install_controller_services(state, host): apt.packages( state, host, {'Install packages'}, [ 'apache2', 'mariadb-server', 'rabbitmq-server', 'memcached', 'python-memcache', 'python-pymysql', ], ) # MariaDB mariadb_configure = files.template( state, host, {'Generate MariaDB config'}, get_template_path('mysql.cnf.j2'), '/etc/mysql/mariadb.conf.d/99-openstack.cnf', ) init.service( state, host, {'Restart MariadB'}, 'mysql', restarted=mariadb_configure.changed, ) # RabbitMQ server.shell( state, host, {'Setup RabbitMQ user'}, ( 'rabbitmqctl add_user openstack {{ host.data.rabbitmq_password }} || true', 'rabbitmqctl set_permissions openstack ".*" ".*" ".*"', ), ) # Memcached memcached_configure = files.template( state, host, {'Generate memcached config'}, get_template_path('memcached.conf.j2'), '/etc/memcached.conf', ) init.service( state, host, {'Restart memcached'}, 'memcached', restarted=memcached_configure.changed, )
def install_nova_node(state, host, neutron=False, placement=False, ceilometer=False): apt.packages( state, host, {'Install nova-compute'}, ['nova-compute'], ) files.put( {'Upload interface.j2'}, get_template_path('interfaces.j2'), '/etc/nova/interfaces.j2', ) nova_configure = files.template( state, host, {'Generate nova config'}, get_template_path('nova-node.conf.j2'), '/etc/nova/nova.conf', neutron=neutron, placement=placement, ceilometer=ceilometer, ) nova_compute_configure = files.template( state, host, {'Generate nova-compute config'}, get_template_path('nova-compute.conf.j2'), '/etc/nova/nova-compute.conf', ) init.service( state, host, {'Restart nova-compute'}, 'nova-compute', restarted=nova_configure.changed or nova_compute_configure.changed, )
def install_glance_service(state, host): install_glance = apt.packages( state, host, {'Install glance'}, ['glance'], ) if install_glance.changed: create_database(state, host, 'glance') create_service_user(state, host, 'glance', 'image') create_service_endpoints(state, host, 'image', ':9292') generate_glance_api_config = files.template( state, host, {'Generate glance-api config'}, get_template_path('glance-api.conf.j2'), '/etc/glance/glance-api.conf', ) generate_glance_registry_config = files.template( state, host, {'Generate glance-registry config'}, get_template_path('glance-registry.conf.j2'), '/etc/glance/glance-registry.conf', ) server.shell( state, host, {'Sync the glance database'}, 'glance-manage db_sync', ) should_restart_glance = (generate_glance_api_config.changed or generate_glance_registry_config.changed) init.service( state, host, {'Restart glance-registry'}, 'glance-registry', restarted=should_restart_glance, ) init.service( state, host, {'Restart glance-api'}, 'glance-api', restarted=should_restart_glance, )
def install_ceilometer_agent(state, host): apt.packages( {'Install ceilometer-agent-compute'}, 'ceilometer-agent-compute', ) ceilometer_configure = files.template( state, host, {'Generate ceilometer config'}, get_template_path('ceilometer-node.conf.j2'), '/etc/ceilometer/ceilometer.conf', ) init.service( state, host, {'Restart ceilometer-agent-compute'}, 'ceilometer-agent-compute', restarted=ceilometer_configure.changed, )
def wireguard(state: Optional[State] = None, host: Optional[Host] = None) -> None: """Install wireguard.""" if host.fact.os == "Linux": if host.fact.linux_distribution["release_meta"]["ID"] in [ "debian", "ubuntu" ]: apt.packages(packages=["wireguard"], state=state, host=host) else: python.raise_exception(exception_class=NotImplementedError, state=state, host=host) else: python.raise_exception(exception_class=NotImplementedError, state=state, host=host) files.template( template_filename="templates/wg0.conf.j2", remote_filename="/etc/wireguard/wg0.conf", create_remote_dir=True, state=state, host=host, wg_private_key=environ["WG_PRIVATE_KEY"], wg_port=environ["WG_PORT"], wg_interface=environ["WG_INTERFACE"], wg_peer_1_public_key=environ["WG_PEER_1_PUBLIC_KEY"], wg_peer_2_public_key=environ["WG_PEER_2_PUBLIC_KEY"], ) server.sysctl(key="net.ipv4.ip_forward", value=1, state=state, host=host) server.sysctl(key="net.ipv6.conf.all.forwarding", value=1, state=state, host=host) server.shell(commands=["wg-quick up wg0"], success_exit_codes=[0, 1], state=state, host=host)
def install_openstack(state, host): # Install base apt packages apt.packages( state, host, {'Install software-properties-common'}, ['software-properties-common'], update=True, cache_time=3600, ) add_ppa = apt.ppa( state, host, {'Add the OpenStack PPA'}, 'cloud-archive:ocata', ) if add_ppa.changed: apt.update( state, host, {'Update apt'}, ) apt.upgrade( state, host, {'Upgrade apt packages'}, ) apt.packages( state, host, {'Install python-openstackclient'}, ['python-openstackclient'], latest=True, )
def install_chrony_node(state, host): apt.packages( state, host, {'Install chrony'}, ['chrony'], ) generate_chrony_config = files.template( state, host, {'Generate chrony config'}, get_template_path('chrony-node.conf.j2'), '/etc/chrony/chrony.conf', ) init.service( state, host, {'Restart chrony'}, 'chrony', restarted=generate_chrony_config.changed, )
def install_neutron_service(state, host, nova=False, placement=False): create_database(state, host, 'neutron') neutron_install = apt.packages( state, host, {'Install neutron network controller packages'}, [ 'neutron-server', 'neutron-plugin-ml2', ], ) if neutron_install.changed: create_service_user(state, host, 'neutron', 'network') create_service_endpoints(state, host, 'network', ':9696') neutron_configure = files.template( state, host, {'Generate neutron config'}, get_template_path('neutron-controller.conf.j2'), '/etc/neutron/neutron.conf', nova=nova, ) ml2_plugin_configure = files.template( state, host, {'Generate neutron ml2 plugin config'}, get_template_path('ml2_conf.ini.j2'), '/etc/neutron/plugins/ml2/ml2_conf.ini', ) server.shell( {'Sync the neutron database'}, ''' neutron-db-manage --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ upgrade head ''', ) init.service( state, host, {'Restart neutron-server'}, 'neutron-server', restarted=neutron_configure.changed or ml2_plugin_configure.changed, )
def install_ceilometer_service(state, host): ceilometer_install = apt.packages( state, host, {'Install ceilometer controller packages'}, [ 'ceilometer-collector', 'ceilometer-agent-central', 'ceilometer-agent-notification', 'python-ceilometerclient', ], ) if ceilometer_install.changed: create_service_user(state, host, 'ceilometer', 'metering') create_service_user(state, host, 'gnocchi', 'metric') create_service_endpoints(state, host, 'metric', ':8041') ceilometer_configure = files.template( state, host, {'Generate ceilometer config'}, get_template_path('ceilometer-controller.conf.j2'), '/etc/ceilometer/ceilometer.conf', ) # server.shell( # state, host, # {'Create ceilometer resoucres in gnocchi'}, # 'ceilometer-upgrade --skip-metering-database', # ) for service in ( 'ceilometer-agent-central', 'ceilometer-agent-notification', 'ceilometer-collector', ): init.service( state, host, {'Restart {0}'.format(service)}, service, restarted=ceilometer_configure, )
def _install_agent(state, host, agent_name, template_name, config_path): install = apt.packages( state, host, {'Install {0} package'.format(agent_name)}, [agent_name], ) configure = files.template( state, host, {'Generate neutron {0} agent config'.format(agent_name)}, get_template_path(template_name), config_path, ) init.service( state, host, {'Restart {0}'.format(agent_name)}, agent_name, restarted=install.changed or configure.changed, )
from pyinfra import host from pyinfra.modules import apt, server, yum SUDO = True if host.fact.linux_name in ['CentOS', 'RedHat']: yum.packages( {'Install some packages'}, ['cronie'], update=True, ) if host.fact.linux_name in ['Ubuntu']: apt.packages( {'Install some packages'}, ['cron'], update=True, ) # simple example for a crontab server.crontab( {'Backup /etc weekly'}, '/bin/tar cf /tmp/etc_bup.tar /etc', name='backup_etc', day_of_week=0, hour=1, minute=0, ) server.group( {'Create docker group'},
from pyinfra import host from pyinfra.modules import apt SUDO = True code_name = host.fact.linux_distribution['release_meta'].get( 'DISTRIB_CODENAME') print(host.fact.linux_name, code_name) if host.fact.linux_name in ['Debian', 'Ubuntu']: apt.packages( {'Install some packages'}, ['vim-addon-manager', 'vim', 'software-properties-common', 'wget'], update=True, ) apt.ppa( {'Add the Bitcoin ppa'}, 'ppa:bitcoin/bitcoin', ) # typically after adding a ppk, you want to update apt.update() # but you could just include the update in the apt install step # like this: apt.packages( {'Install Bitcoin'}, 'bitcoin-qt', update=True,
def install_nova_service(state, host, neutron=False, placement=False): create_database(state, host, 'nova') create_database(state, host, 'nova_api', name='nova') create_database(state, host, 'nova_cell0', name='nova') packages = [ 'nova-api', 'nova-conductor', 'nova-consoleauth', 'nova-novncproxy', 'nova-scheduler', ] if placement: packages.append('nova-placement-api') nova_install = apt.packages( state, host, {'Install nova compute controller packages'}, packages, ) if nova_install.changed: create_service_user(state, host, 'nova', 'compute') create_service_endpoints(state, host, 'compute', ':8774/v2.1/%\(tenant_id\)s') if packages: create_service_user(state, host, 'placement', 'placement') create_service_endpoints(state, host, 'placement', ':8778') nova_configure = files.template( state, host, {'Generate nova config'}, get_template_path('nova-controller.conf.j2'), '/etc/nova/nova.conf', neutron=neutron, placement=placement, ) server.shell( state, host, {'Sync the nova api database'}, 'nova-manage api_db sync', ) if nova_install.changed: server.shell( state, host, {'Setup nova cells and sync db'}, ( 'nova-manage cell_v2 map_cell0', 'nova-manage cell_v2 create_cell --name=cell1 --verbose', ), ) server.shell( state, host, {'Sync the nova database'}, 'nova-manage db sync', ) for service in ( 'nova-api', 'nova-consoleauth', 'nova-scheduler', 'nova-conductor', 'nova-novncproxy', ): init.service( state, host, {'Restart {0}'.format(service)}, service, restarted=nova_configure.changed, )
pkg.packages( {'Install Python, Pip & Git with pkg_add'}, ['py-pip', 'git'], ) # add_pkg does not automatically do this server.shell( {'Symlink pip to pip2.7'}, 'ln -sf /usr/local/bin/pip2.7 /usr/local/bin/pip', ) # Work with facts about the remote host if host.fact.linux_name in ('Ubuntu', 'Debian'): apt.packages( {'Install Pip & Git with apt'}, ['git', 'python-pip'], update=True, cache_time=3600, ) elif host.fact.linux_name in ('CentOS', 'Fedora'): if host.fact.linux_name == 'CentOS': # Both missing in the CentOS 7 Vagrant image yum.packages( {'Install wget & net-tools with yum'}, ['wget', 'net-tools'], ) # Manage remote rpm files yum.rpm( {'Install epel RPM'}, ('https://dl.fedoraproject.org/pub/epel/epel-release-latest-'
from pyinfra import host from pyinfra.modules import apt, files SUDO = True if host.fact.linux_name == 'Ubuntu': apt.packages( {'Install wget'}, ['wget'], update=True, ) # Full URL: # http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-netboot-3.11.2-x86_64.tar.gz # sha256 is here # http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-netboot-3.11.2-x86_64.tar.gz.sha256 tarfile = 'alpine-netboot-3.11.2-x86_64.tar.gz' tarfile_full_path = '/tmp/{}'.format(tarfile) sha256file = tarfile + '.sha256' sha256file_full_path = '/tmp/{}'.format(sha256file) # TODO: Check if download was successful files.download( {'Download `{}`'.format(tarfile)}, 'http://dl-cdn.alpinelinux.org/alpine/v3.11/releases/x86_64/{}'.format( tarfile), tarfile_full_path, ) files.download(
# Include other files local.include( 'tasks/bsd_python.py', hosts=inventory.get_group('bsd', []), ) # Work with facts about the remote host # Storing this fact to avoid typing it so much (because the example targets a whole bunch # of distros [& 2 OSs]). distro = host.fact.linux_distribution # apt package manager apt.packages( ['git', 'python-pip'], sudo=True, update=True, cache_time=3600, # Limit operations to certain hosts with when=... when=distro['name'] in ('Ubuntu', 'Debian'), ) # Or limit blocks of operations with state.when(...): with state.when(distro['name'] in ('CentOS', 'Fedora')): with state.when(distro['name'] == 'CentOS'): # Both missing in the CentOS 7 Vagrant image yum.packages( ['wget', 'net-tools'], sudo=True, ) # Manage remote rpm files yum.rpm((
sudo=SUDO) assert status is True # ensure the command executed OK if version not in str(stdout): raise Exception( '`{}` did not work as expected.stdout:{} stderr:{}'.format( command, stdout, stderr)) if host.fact.linux_name == 'Ubuntu': code_name = host.fact.linux_distribution['release_meta'].get( 'DISTRIB_CODENAME') print(host.fact.linux_name, code_name) apt.packages( {'Install packages'}, ['wget'], update=True, ) apt.key( {'Install VirtualBox key'}, 'https://www.virtualbox.org/download/oracle_vbox_2016.asc', ) apt.repo( {'Install VirtualBox repo'}, 'deb https://download.virtualbox.org/virtualbox/debian {} contrib'. format(code_name), ) # install kernel headers
from pyinfra.modules import apt, npm SUDO = True apt.packages( {'Install node'}, ['nodejs', 'npm'], update=True, ) npm.packages( {'Install some npm packages'}, ['react', 'express'], )
from pyinfra import host, state from pyinfra.modules import apt, files, mysql, python SUDO = True if host.fact.linux_distribution['name'] != 'Debian': # Raises an exception mid-deploy python.raise_exception( {'Ensure we are Debian'}, NotImplementedError, '`mysql.py` only works on Debian', ) apt.packages( {'Install mysql server & client'}, ['mysql-server'], update=True, cache_time=3600, ) # Setup a MySQL role & database # mysql.user( {'Create the pyinfra@localhost MySQL user'}, 'pyinfra', password='******', ) mysql.database( {'Create the pyinfra_stuff database'}, 'pyinfra_stuff',
# Include roles local.include( 'roles/bsd_role.py', hosts=inventory.bsd # optionally limit the role to a subset of hosts ) # Storing this fact to avoid typing it so much (because the example targets a whole bunch # of distros [& 2 OSs]). distro = host.fact.linux_distribution # Work with facts about the remote host if distro['name'] in ('Debian', 'Ubuntu'): # apt package manager apt.packages(['git', 'python-pip'], sudo=True, update=True, cache_time=3600) elif distro['name'] in ('CentOS', 'Fedora'): if distro['name'] == 'CentOS': # Manage remote rpm files yum.rpm( 'https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ host.fact.linux_distribution.major }}.noarch.rpm', sudo=True) # yum package manager yum.packages(['git', 'python-pip'], sudo=True) # Edit lines in files files.line('/etc/sysconfig/selinux', '^SELINUX=.*',
SUDO = True # If you change pxe_server value below then check/change Vagrantfile pxe_server = '192.168.0.240' interface = 'eth1' dhcp_start = '192.168.0.220' dhcp_end = '192.168.0.230' # setup pxe infra if host.fact.linux_name == 'Ubuntu': apt.packages( {'Install packages'}, ['dnsmasq', 'nfs-kernel-server', 'syslinux', 'pxelinux'], update=True, ) # configure dnsmasq files.template( {'Create dnsmasq configuration file'}, 'templates/dnsmasq.conf.j2', '/etc/dnsmasq.conf', pxe_server=pxe_server, interface=interface, dhcp_start=dhcp_start, dhcp_end=dhcp_end, ) # create necessary directories
from pyinfra import host from pyinfra.modules import apt, gem SUDO = True if host.fact.linux_name in ['Debian', 'Ubuntu']: apt.packages( {'Install rubygems'}, 'rubygems', ) gem.packages( {'Install rspec'}, 'rspec', )
SUDO = True if host.fact.linux_distribution['name'] != 'Ubuntu': # Raises an exception mid-deploy python.raise_exception( {'Ensure we are Ubuntu'}, NotImplementedError, '`postgresql.py` only works on Ubuntu', ) apt.packages( {'Install postgresql server & client'}, ['postgresql'], update=True, cache_time=3600, ) # Setup a PostgreSQL role & database # postgresql.role( {'Create the pyinfra PostgreSQL role'}, 'pyinfra', password='******', superuser=True, login=True, sudo_user='******', )
apk.packages( {'Install git'}, 'git', ) if host.fact.linux_name in ['CentOS']: yum.packages( {'Install git'}, 'git', update=True, ) if host.fact.linux_name in ['Ubuntu']: apt.packages( {'Install git'}, 'git', update=True, ) src_dir = '/usr/local/src' dest = src_dir + '/pyinfra' files.directory( {'Ensure the src_dir directory exists'}, src_dir, ) # Clone the pyinfra repo to do some pyinfra development git.repo( {'Clone repo'}, 'https://github.com/Fizzadar/pyinfra.git',
SUDO = True # If you change pxe_server value below then check/change Vagrantfile pxe_server = '192.168.0.240' dns_server = '192.168.0.1' interface = 'eth1' dhcp_start = '192.168.0.220' dhcp_end = '192.168.0.230' # setup pxe infra if host.fact.linux_name == 'Ubuntu': apt.packages( {'Install packages'}, ['dnsmasq'], update=True, ) tftp_dir = '/srv/tftp' files.directory( {'Ensure the `{}` exists'.format(tftp_dir)}, tftp_dir, ) tar_file = 'netboot.tar.gz' tar_file_full_path = '/tmp/{}'.format(tar_file) files.download( {'Download `{}`'.format(tar_file)}, 'http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/' 'installer-amd64/current/images/netboot/{}'.format(tar_file),
import os from subprocess import check_call from pyinfra import host from pyinfra.modules import apt, files, init, postgresql, server os.chdir(os.path.dirname('./' + __file__)) cwd = os.path.abspath('.') project_root = os.path.abspath('../..') apt.packages( {'Install prometheus'}, ['prometheus'], latest=True, sudo=True, ) files.put( {'Install prometheus config'}, 'prometheus.yml', '/etc/prometheus/prometheus.yml', mode='644', user='******', group='root', sudo=True, ) init.systemd( {'Restart prometheus service'}, 'prometheus', running=True,
def install_keystone_service(state, host): create_database(state, host, 'keystone') keystone_install = apt.packages( state, host, {'Install keystone'}, ['keystone'], ) files.template( state, host, {'Generate keystone config'}, get_template_path('keystone.conf.j2'), '/etc/keystone/keystone.conf', ) server.shell( state, host, {'Sync the keystone database'}, 'keystone-manage db_sync', ) # Bootstrap keystone: only do this if newly installed if keystone_install.changed: server.shell( state, host, ''' keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone keystone-manage credential_setup --keystone-user keystone --keystone-group keystone keystone-manage bootstrap \ --bootstrap-password {{ host.data.admin_password }} \ --bootstrap-admin-url http://{{ host.data.controller_host }}:35357/v3/ \ --bootstrap-internal-url http://{{ host.data.controller_host }}:35357/v3/ \ --bootstrap-public-url http://{{ host.data.controller_host }}:5000/v3/ \ --bootstrap-region-id RegionOne ''') update_apache_config = files.line( state, host, {'Set ServerName in apache2 config'}, '/etc/apache2/apache2.conf', 'ServerName.*', replace='ServerName {{ host.data.ssh_hostname }}', ) init.service( state, host, {'Restart apache2'}, 'apache2', restarted=update_apache_config.changed, ) if keystone_install.changed: server.shell( state, host, {'Create initial projects/users/roles'}, ( 'openstack project create --domain default service', 'openstack project create --domain default user', 'openstack user create --domain default --password hamble user-1', 'openstack role create user', 'openstack role add --project user --user user-1 user', ), env=make_admin_env(host), )
def check_docker_works(state, host): command = 'docker run hello-world' status, stdout, stderr = host.run_shell_command(state, command=command, sudo=SUDO) if not status or 'Hello from Docker!' not in stdout: raise Exception('`{}` did not work as expected'.format(command)) if host.fact.linux_name == 'Ubuntu': apt.packages( {'Ensure old docker packages are not present'}, [ 'docker', 'docker-engine', 'docker.io', 'containerd runc', ], present=False, ) apt.packages( {'Ensure Docker CE prerequisites are present'}, [ 'apt-transport-https', 'ca-certificates', 'curl', 'gnupg-agent', 'software-properties-common', ], update=True,