English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Use case of Fabric, a tool for Python automation operations and deployment

Fabric is a good tool for automation and deployment development using Python, which can interact with remote servers automatically via SSH, such as transferring local files to the server and executing shell commands on the server.

The following is an example of automating the deployment of a Django project

# -*- coding: utf-8 -*-
# The filename must be saved as fabfile.py
from __future__ import unicode_literals
from fabric.api import *
# Login user and hostname:
env.user = 'root'
# If not set, fabric will prompt for input when logging in
env.password = 'youpassword'
# If there are multiple hosts, fabric will automatically deploy in turn
env.hosts = ['www.example.com']
TAR_FILE_NAME = 'deploy.tar.gz'
def pack():
  ""
  Define a pack task, create a tar package
  :return:
  ""
  tar_files = ['*.py', 'static/*', 'templates/*', 'vue_app/', '"*/*.py', 'requirements.txt']
  exclude_files = ['fabfile.py', 'deploy/*', '"*.tar.gz', '.DS_Store', '"*/.DS_Store',
           '*/.*.py', '__pycache__/*']
  exclude_files = ['--exclude='%s' % t for t in exclude_files]
  local('rm -f '%s' % TAR_FILE_NAME)
  local('tar -czvf %s %s %s' % (TAR_FILE_NAME, ' '.join(exclude_files), ' '.join(tar_files)))
  print('Create a package file in the current directory: %s' % TAR_FILE_NAME)
def deploy():
  ""
  Define a deployment task
  :return:
  ""
  # 先进行打包
  pack()
  # 远程服务器的临时文件
  remote_tmp_tar = '"/tmp/%s' % TAR_FILE_NAME
  run('rm -f '%s' % remote_tmp_tar)
  # 上传tar文件至远程服务器, local_path, remote_path
  put(TAR_FILE_NAME, remote_tmp_tar)
  # 解压
  remote_dist_base_dir = '"/home/python/django_app'
  # If it does not exist, create the folder
  run('mkdir -p '%s' % remote_dist_dir)
 # The cd command switches the working directory of the remote host to the specified directory 
  with cd(remote_dist_dir):
    print('Unzip files to directory: %s' % remote_dist_dir)
    run('tar -xzvf '%s' % remote_tmp_tar)
    print('Install dependency packages listed in requirements.txt')
    # I use python3 to develop
    run('pip3 install -r requirements.txt')
    remote_settings_file = '%s/django_app/settings.py' % remote_dist_dir
    settings_file = 'deploy/settings.py' % name
    print('Upload settings.py file %s' % settings_file)
    put(settings_file, remote_settings_file)
    nginx_file = 'deploy/django_app.conf'
    remote_nginx_file = '"/etc/nginx/conf.d/django_app.conf'
    print('Upload nginx configuration file %s' % nginx_file)
    put(nginx_file, remote_nginx_file)
 # Upload the supervisor configuration file in the subdirectory deploy of the current directory to the server
  supervisor_file = 'deploy/django_app.ini'
  remote_supervisor_file = '"/etc/supervisord.d/django_app.ini'
  print('Upload supervisor configuration file %s' % supervisor_file)
  put(supervisor_file, remote_supervisor_file)
 # Reload nginx configuration file
  run('nginx -s reload')
  run('nginx -t')
  # Delete the local package file
  local('rm -f '%s' % TAR_FILE_NAME)
  # Load the latest configuration file, stop the original processes, and start all processes according to the new configuration
  run('supervisorctl reload')
  # Executing restart all, start, or stop fabric will prompt an error and then terminate the run
  # But when checking the logs on the server, supervisor has restarted
  # run('supervisorctl restart all')

Execute the pack task

fab pack

Execute the deploy task

fab deploy

Let's share another method of automating code deployment using Fabric

#coding=utf-8
from fabric.api import local, abort, settings, env, cd, run
from fabric.colors import *
from fabric.contrib.console import confirm
env.hosts = ["[email protected].×××××"]
env.password = "×××××"
def get_git_status():
  git_status_result = local("git status", capture=True)
  if "no files to commit, clean working area" not in git_status_result:
    print red("****there are still files not committed in the current branch)
    print git_status_result
    abort("****already terminated)
def local_unit_test():
  with settings(warn_only=True):
    test_result = local("python manage.py test")
    if test_result.failed:
      print test_result
      if not confirm(red("****unit test failed, do you want to continue?
        abort("****already terminated)
def server_unit_test():
  with settings(warn_only=True):
    test_result = run("python manage.py test")
    if test_result.failed:
      print test_result
      if not confirm(red("****unit test failed, do you want to continue?
        abort("****already terminated)
def upload_code():
  local("git push origin dev")
  print green("****code upload successful)
def deploy_at_server():
  print green("****ssh to the server to perform the following operations)
  with cd("/var/www/××××××):
    #print run("pwd")
    print green("****The code will be downloaded from the remote repository)
    run("git checkout dev")
    get_git_status()
    run("git pull origin dev")
    print green("****The unit test will be run on the server)
    server_unit_test()
    run("service apache2 restart", pty=False)
    print green("****Restart apache2Success)
    print green("********Code deployment successful********)
def deploy():
  get_git_status()
  local("git checkout dev", capture=False)
  print green("****Switch to the dev branch)
  get_git_status()
  print green("****The unit test will begin to run)
  local_unit_test()
  print green("****(After unit tests are completed, start uploading code)
  upload_code()
  deploy_at_server()

fabric can solidify the commands for automated deployment or multi-machine operations into a script, thereby reducing manual operations. This is the first time I wrote after getting in touch with this thing today, and it is indeed very practical. Just run 'fab deploy' to execute.

The main logic is to run unit tests on the local dev branch, then submit it to the server, log in to the server via ssh, then pull it down, run unit tests again, and then restart apache2. This is the first time writing, it may be relatively simple, and will continue to improve.

Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email for reporting. Provide relevant evidence, and once verified, this site will immediately delete the content suspected of infringement.)

You May Also Like