def android_studio(c): version = "3.2.1.0" release = "android-studio-ide-181.5056338-linux.zip" # install(c, "qemu-kvm android-tools libstdc++.i686 zlib.i686") print("Downloading Android Studio, this might take a while") if os.path.isfile(release) is False: wget.download( "https://dl.google.com/dl/android/studio/ide-zips/{}/{}".format( version, release)) c.put(release, remote='/tmp/') c.sudo("unzip -q /tmp/{} -d /opt/".format(release)) c.run("rm -r /tmp/{}".format(release)) append( "/usr/local/share/applications/android-studio.desktop", "[Desktop Entry]" "\nType=Application" "\nName=Android Studio" "\nIcon=/opt/android-studio/bin/studio.png" "\nExec=env _JAVA_OPTIONS=-Djava.io.tmpdir=/var/tmp " "/opt/android-studio/bin/studio.sh" "\nTerminal=false" "\nCategories=Development;IDE;", use_sudo=True, )
def vscode(c): # dotnet repo c.sudo("rpm --import https://packages.microsoft.com/keys/microsoft.asc") c.sudo("wget -q https://packages.microsoft.com/config/fedora/27/prod.repo") c.sudo("mv prod.repo /etc/yum.repos.d/microsoft-prod.repo") c.sudo("chown root:root /etc/yum.repos.d/microsoft-prod.repo") # VC Code repo append( "/etc/yum.repos.d/vscode.repo", "[code]\nname=Visual Studio Code" "\nbaseurl=https://packages.microsoft.com/yumrepos/vscode/\n" "enabled=1\ngpgcheck=1" "\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc", use_sudo=True, ) install(c, "code") # VS Code itself install(c, "mono-devel") install(c, "mono-addins-devel") # msbuild c.sudo("dnf copr -y disable @dotnet-sig/dotnet") install(c, "dotnet-sdk-2.1") install(c, "dotnet-runtime-2.1")
def do_disable_password_auth(c): ssh_config = '/etc/ssh/sshd_config' if (files.contains(c, ssh_config, '#?PasswordAuthentication (yes|no)')): c.run(f'sudo sed -i "s/#?PasswordAuthentication (yes|no)/PasswordAuthentication no/g" {ssh_config}') else: files.append(c, ssh_config, 'PasswordAuthentication no') c.run('sudo systemctl restart ssh')
def test_rsync_file(): # setup d = 'test_rsync' remote_f = 'remote\ file.txt' local_f = 'local_file.txt' directory(d) with cd(d): rm(remote_f) append(remote_f, 'Hello world') # download file src = '%s/%s' % (d, remote_f) rsync( remote_dir=src, local_dir=local_f, upload=False ) assert contains(local_f, 'Hello world', runner=local) is True # append to and upload file append(local_f, 'Hello from local', runner=local) rsync( remote_dir=src, local_dir=local_f, ) # check uploaded file with cd(d): assert contains(remote_f, 'Hello from local') is True # cleanup rm(local_f, runner=local) rmdir(d)
def do_disable_root_login(c): ssh_config = '/etc/ssh/sshd_config' if (files.contains(c, ssh_config, '#?PermitRootLogin (yes|no)', escape=False)): c.sudo(f'sed -i -E "s/#?PermitRootLogin (yes|no)/PermitRootLogin no/g" {ssh_config}') else: files.append(c, ssh_config, 'PermitRootLogin no') c.sudo('systemctl restart ssh')
def _update_settings(c, source_dir): # Disable debug settings_path = source_dir / "brynweb/settings.py" c.run(f"sed -i 's/DEBUG = True/DEBUG = False/g' {settings_path}") # Set allowed hosts hosts_find = "ALLOWED_HOSTS =.\\+$" hosts_replace = f'ALLOWED_HOSTS = ["{c.host}"]' c.run(f"sed -i 's/{hosts_find}/{hosts_replace}/g' {settings_path}") # Update SITE_SCHEME site_scheme_find = "SITE_SCHEME =.\\+$" site_scheme_replace = 'SITE_SCHEME = "https"' c.run(f"sed -i 's/{site_scheme_find}/{site_scheme_replace}/g' {settings_path}") # Update SITE_DOMAIN site_domain_find = "SITE_DOMAIN =.\\+$" site_domain_replace = f'SITE_DOMAIN = "{c.host}"' c.run(f"sed -i 's/{site_domain_find}/{site_domain_replace}/g' {settings_path}") # Create and import secret key secret_key_path = source_dir / "brynweb/secret_key.py" if not exists(c, secret_key_path): chars = "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)" key = "".join(random.SystemRandom().choice(chars) for _ in range(50)) append(c, secret_key_path, f'SECRET_KEY = "{key}"') append(c, settings_path, "\nfrom .secret_key import SECRET_KEY")
def append_to_file(ctx, filepath, contents): """Add contents to a file. :param ctx: :param str filepath: :param str contents: """ if not exists(ctx, filepath): touch(ctx, filepath) append(ctx, filepath, contents)
def _create_or_update_dotenv(c): print('Creating/Updating dotenv...') append(c, '.env', 'DJANGO_DEBUG_FALSE=y') append(c, '.env', f'SITENAME={c.host}') append(c, '.env', f'EMAIL_USER={APP_CONFIG["EMAIL_USER"]}') append(c, '.env', f'EMAIL_PASSWORD={APP_CONFIG["EMAIL_PASSWORD"]}') current_contents = c.run('cat .env', hide=True).stdout.strip() if 'DJANGO_SECRET_KEY' not in current_contents: new_secret = ''.join(random.SystemRandom().choices( 'abcdefghijklmnopqrstuvwxyz0123456789', k=50)) append(c, '.env', f'DJANGO_SECRET_KEY={new_secret}') print('Done\n')
def copy_pubkey(from_, to): """ Copy remote user ``from_``'s authorized keys to user ``to``. I.e. allow ``from_`` to SSH into the server as ``to``. """ with hide('stdout'): append( filename=_keyfile(to), # Leading newline to ensure keys stay separate text=['\n'] + sudo("cat %s" % _keyfile(from_)).splitlines(), runner=sudo)
def copy_pubkey(from_, to): """ Copy remote user ``from_``'s authorized keys to user ``to``. I.e. allow ``from_`` to SSH into the server as ``to``. """ with hide('stdout'): append( filename=_keyfile(to), # Leading newline to ensure keys stay separate text=['\n'] + sudo("cat %s" % _keyfile(from_)).splitlines(), runner=sudo )
def do_add_ssh_user(c, username, sshkeyfile, password=None): c.run(f'adduser {username} --disabled-password --gecos ""') do_add_user_to_group(c, username, 'sudo') if (password is not None): do_set_password(c, username, password) with open(sshkeyfile) as f: sshkey = f.read() homedir = f'/home/{username}' files.directory(c, f'hotexamples_com/.ssh', username, username, '700') authorized_key_file = f'hotexamples_com/.ssh/authorized_keys' if (not files.exists(c, authorized_key_file)): set_file(c, authorized_key_file, username, username, 600) files.append(c, authorized_key_file, sshkey) print(f'Successfully created {username} user on {c.host}')
def dconf(c): append(c, "/etc/dconf/profile/user", "service-db:keyfile/user") c.append( "/etc/dconf/profile/gdm", "user-db:user\n" "system-db:gdm\n" "file-db:/usr/share/gdm/greeter-dconf-defaults", use_sudo=True, ) c.sudo("mkdir /etc/dconf/db/gdm.d") c.append( "/etc/dconf/db/gdm.d/00-login-screen", "[org/gnome/login-screen]\n" "disable-user-list=true", use_sudo=True, ) c.sudo("dconf update")
def _create_or_update_dotenv(c): append('.env', 'PRODUCTION_MODE','y') append('.env', f"SITENAME={os.environ['HOST']}") current_contents = c.run("cat .env") if 'DJANGO_SECRET_KEY' not in current_contents: new_secret = ''.join(random.SystemRandom().choices('abcdefghijklmnopqrstuvwxyz0123456789', k=50)) append('.env', f"DJANGO_SECRET_KEY={new_secret}")
def _create_or_update_dotenv(c, sitename): append(c, '.env', 'DJANGO_DEBUG_FALSE=y') append(c, '.env', 'SITENAME={}'.format(sitename)) current_contents = c.run('cat .env') if 'DJANGO_SECRET_KEY' not in current_contents.stdout.strip(): new_secret = ''.join(random.SystemRandom().choices( 'abcdefghijklmnopqrstuvwxyz0123456789', k=50)) append(c, '.env', 'DJANGO_SECRET_KEY={}'.format(new_secret))
def _create_or_update_dotenv(c): print('add django debug env var') append(c, '.env', 'DJANGO_DEBUG_FALSE=y') print('add sitename env var') append(c, '.env', f'SITENAME={c.host}') print('check if secret key exists') if not contains(c, '.env', 'DJANGO_SECRET_KEY'): print('it does not, make a new one and add it') new_secret = ''.join(random.SystemRandom().choices( 'abcdefghijklmnopqrstuvwxyz0123456789', k=50 )) append(c, '.env', f'DJANGO_SECRET_KEY={new_secret}') else: print('it does')
def deploy(connection): site_folder = '/home/{}/sites/{}'.format(connection.user, connection.host) source_folder = site_folder + '/source' # create_directory_structure_if_necessary for subfolder in ('database', 'static', 'virtualenv', 'source'): connection.run('mkdir -p {}/{}'.format(site_folder, subfolder)) # add ssh key to github if not exists(connection, '~/.ssh/id_rsa.pub'): connection.run('ssh-keygen -t rsa -b 4096 -C "{}"'.format( config['github']['Email'])) connection.run(( 'curl -u "{username}:{password}" ' '--data "{{\\"title\\":\\"{host}\\",\\"key\\":\\"`cat ~/.ssh/id_rsa.pub`\\"}}" ' 'https://api.github.com/user/keys').format( username=config['github']['Username'], password=config['github']['Password'], host=connection.host)) # get_latest_source connection.run('ssh-keyscan github.com >> ~/.ssh/known_hosts') if exists(connection, source_folder + '/.git'): connection.run('cd {} && git fetch'.format(source_folder)) else: connection.run('git clone {} {}'.format(config['github']['Repo'], source_folder)) current_commit = connection.local('git log -n 1 --format=%H') connection.run('cd {} && git reset --hard {}'.format( source_folder, current_commit.stdout)) # update_settings settings_path = source_folder + '/superlists/settings.py' connection.run( 'sed "s/DEBUG = True/DEBUG=False/" {}'.format(settings_path)) connection.run( 'sed "s/ALLOWED_HOSTS = .+$/ALLOWED_HOSTS = [{}]/" {}'.format( connection.host, settings_path)) secret_key_file = source_folder + '/superlists/secret_key.py' if not exists(connection, secret_key_file): chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)' key = ''.join(random.SystemRandom().choice(chars) for _ in range(50)) append(connection, secret_key_file, 'SECRET_KEY = "{}"'.format(key)) append(connection, settings_path, '\nfrom .secret_key import SECRET_KEY') # update_virtualenv connection.run('sudo killall apt apt-get || true') connection.run('sudo apt update') connection.run('sudo apt install -y python3-pip') connection.run('sudo pip3 install virtualenv') virtualenv_folder = source_folder + '/../virtualenv' if not exists(connection, virtualenv_folder + '/bin/pip'): connection.run('virtualenv -p python3 {}'.format(virtualenv_folder)) connection.run('{}/bin/pip install -r {}/requirements.txt'.format( virtualenv_folder, source_folder)) # update_static_files connection.run( 'cd {} && ../virtualenv/bin/python3 manage.py collectstatic --noinput'. format(source_folder)) # update_database connection.run( 'cd {} && ../virtualenv/bin/python3 manage.py migrate --noinput'. format(source_folder)) # start nginx connection.run('sudo apt-get install -y nginx') connection.run('cd {} && sed "s/SITENAME/mm.mmflow.online/g; s/USER/{}/g" ' .format(source_folder, connection.user) + 'deploy_tools/nginx.template.conf ' + '| sudo tee /etc/nginx/sites-available/mm.mmflow.online') if not exists(connection, '/etc/nginx/sites-enabled/mm.mmflow.online'): connection.run( 'sudo ln -s /etc/nginx/sites-available/mm.mmflow.online '.format( source_folder) + '/etc/nginx/sites-enabled/mm.mmflow.online') connection.run('sudo service nginx start') connection.run('sudo service nginx reload') # start gunicorn connection.run( 'cd {} && sed "s/SITENAME/mm.mmflow.online/g; s/USER/{}/g" '.format( source_folder, connection.user) + 'deploy_tools/gunicorn-systemd.template.service | ' + 'sudo tee /lib/systemd/system/gunicorn-mm.mmflow.online.service') connection.run('sudo systemctl daemon-reload') connection.run('sudo systemctl restart gunicorn-mm.mmflow.online')