def copy_wp_config(when_exists='skip'): out.log('copy wp-config.php to wordpress directory', 'wordpress') #check if wp-config.php already exists if overwrite_allowed(engine.LOCAL_WP_DIR + '/wp-config.php', when_exists): #copy our config.php to the desired location run.local('cp php/wordpress/wp-config.php ' + engine.LOCAL_WP_DIR)
def pack_local_list(file_list): #tell out.log('packing a bunch of local files', 'tar') #validate files if not validate_files_list(file_list): out.log('Error: files need to be given relative to www dir.', 'tar', out.LEVEL_ERROR) engine.quit() #register tar file tar_file = engine.get_new_local_file('tar') #register list file list_file_content = "\n".join(file_list) list_file = engine.write_local_file(list_file_content, 'files') #assemble packing command. Always pack from www dir pack_command = 'tar cf ' + tar_file + ' -C ' + engine.LOCAL_WWW_DIR + ' --files-from ' + list_file #pack! run.local(pack_command) #and return packed file, of course return tar_file
def po(): out.log('looking for .po files recursively...', 'compile', out.LEVEL_VERBOSE) compiled_files = 0 files = [] for root, dirnames, filenames in os.walk(engine.LOCAL_WWW_DIR): for filename in fnmatch.filter(filenames, '*.po'): files.append(os.path.join(root, filename)) for po in files: mo = po[:-3] + '.mo' # needs to be refreshed if # 1. there is no .mo file # 2. the .mo file is out of date # 3. the .mo file is not placed in a folder named 'orig' if (not os.path.isfile(mo) or os.path.getmtime(po) > os.path.getmtime(mo)) and ( not os.path.split(os.path.dirname(po))[1] == 'orig'): out.log('compiling ' + po, 'compile') run.local('msgfmt -o ' + mo + ' ' + po) compiled_files += 1 else: out.log('skipping ' + po, 'compile', out.LEVEL_VERBOSE) out.log('all .mo files up to date.', 'compile')
def get(remote_file, local_file=None, verbose=False, permissions=None): #create new local file if not spcefied if local_file is None: #keep suffix suffix = engine.get_suffix(remote_file) local_file = engine.get_new_local_file(suffix) #print some info out.log(remote_file + " -> " + local_file, 'download') #get transfer system if engine.TRANSFER_SYSTEM == 'FTP': command = 'get ' + ftp_path(remote_file) + ' ' + local_file ftp.execute(command) elif engine.TRANSFER_SYSTEM == 'SSH': out.log("Error: TRANSFER_SYSTEM SSH not implemented yet", 'download', out.LEVEL_ERROR) engine.quit() else: out.log("Error: Unknown TRANSFER_SYSTEM " + engine.TRANSFER_SYSTEM, 'download', out.LEVEL_ERROR) engine.quit() #set permissions if permissions is not None: run.local('chmod ' + str(permissions) + ' ' + local_file) #return new filename return local_file
def clean_local_tmp_dir(): import run #create a file, so the removal does not fail tmp_file = write_local_file('this file is here to be cleaned up.') #unregister it, because it gets wiped by this cleanup already unregister_local_file(tmp_file) local_tmp_dir = get_local_tmp_dir() run.local('rm ' + local_tmp_dir + '/tmp_file_*')
def allow_write(location='local'): command = 'chmod -R a+w ./*' if location == 'local': command = 'cd ' + engine.LOCAL_WWW_DIR + ' && ' + command if location == 'local': run.local(command) if location == 'remote': run.remote(command)
def js(): run.local( 'cd ' + engine.LOCAL_MAKE_DIR + ' && make ' + engine.MAKEFILE_VARS + ' js', False) md5_file = append_md5(engine.path_join(engine.BUILD_URL, '/main.js'), copy_zipped=True) save_to_php(engine.LOCAL_WWW_DIR + '/' + engine.JS_INCLUDE_FILE, engine.force_absolute(md5_file))
def get_database_dump_file(compression = False, domain = None): import run #mysql dump filenames if not os.path.isdir(LOCAL_DB_DIR): run.local('mkdir -p ' + LOCAL_DB_DIR) description = get_database_file_description(domain) filename = os.path.abspath(LOCAL_DB_DIR + '/' + description + '-' + str(datetime.now()).replace(' ', '-') + '.sql') if compression: filename += '.gz' return filename
def execute(command): import run #out.log('executing ' + command, 'ssh', out.LEVEL_VERBOSE) #get in sync with all possibly buffered ftp commands engine.sync_ftp() #run the command ssh_command_line = 'ssh ' + engine.SSH_USER + '@' + engine.SSH_HOST + " 'cd " + engine.SSH_PATH_TO_WWW_DIR + ' && ' + command + "'" run.local(ssh_command_line, retry=3, halt_on_stderr=False)
def prepare(overwrite, upload=False): htaccess_file = os.path.abspath(engine.LOCAL_WWW_DIR + '/.htaccess') if os.path.isfile(htaccess_file): if overwrite == 'fail': out.log( '.htaccess already exists. Specify overwrite as parameter or delete the file manually before trying again.', 'htaccess', out.LEVEL_ERROR) engine.quit() if overwrite == 'overwrite': run.local('rm ' + htaccess_file) if upload: transfer.remove_remote('.htaccess')
def optimize_jpg(quality = 100): out.log('optimizing jpgs...', 'image') for root, dirnames, filenames in os.walk(engine.LOCAL_WWW_DIR): for filename in fnmatch.filter(filenames, '*.jpg'): if os.path.getsize(root + '/' + filename) > 20000: progressive = '--all-progressive' else: progressive = '' if quality < 100: quality = '-m' + str(quality) else: quality = '' run.local('jpegoptim ' + progressive + ' ' + quality + ' "' + root + '/' + filename + '"', ignore_exit_code = True)
def execute(command): out.log(command, 'ftp', out.LEVEL_VERBOSE) #write the command into file ftp_file = engine.write_local_file(command, 'ftp') #run the ftp file if engine.FTP_CLIENT == 'ftp': ftp_command_line = 'ftp -i ' + engine.FTP_PROTOCOL + '://' + engine.escape( engine.FTP_USER) + ':' + engine.escape( engine.FTP_PASSWORD) + '@' + engine.FTP_HOST + ' <' + ftp_file elif engine.FTP_CLIENT == 'sftp': ftp_command_line = 'sftp -b ' + ftp_file + ' ' + engine.escape( engine.FTP_USER) + '@' + engine.FTP_HOST run.local(ftp_command_line, retry=3)
def append_to_hosts(): try: engine.LOCAL_DOMAIN except: out.log( 'Your LOCAL_DOMAIN variable has not been set. Please specify a valid hostname and try again.' ) return out.log( 'appending ' + engine.LOCAL_DOMAIN + ' to ' + engine.LOCAL_ETC_HOSTS, 'apache') run.local('echo "127.0.0.1 ' + engine.LOCAL_DOMAIN + ' # appended by fabric deploy script." >>' + engine.LOCAL_ETC_HOSTS, sudo=True)
def execute(command, halt_on_output=False): import run #tell out.log(command, 'php', out.LEVEL_VERBOSE) #make sure the command file is online upload_command_file() #write command to file and upload it. We do it this way, althouth this is quite inefficient, but otherwise we'd have tremendous problems with escaping characters. #althouth, TODO: escape special characters in command script_content = '#!/bin/bash\n' + command filename = engine.write_remote_file(script_content, 'sh', permissions='777') #reserve a remote .log file output_file = engine.get_new_local_file('log', True) #run the command via php access and tell the server to put the commands output into the remote output file curl_command = 'curl --silent --output ' + output_file #account for basic auth if engine.NEED_BASIC_AUTH: curl_command += ' -u ' + engine.AUTH_USER + ':' + engine.AUTH_PASSWORD #continue assembling curl command curl_command += ' ' + engine.REMOTE_COMMAND_URL + '?cmd=' + filename #execute all buffered ftp commands engine.sync_ftp() #and go run.local(curl_command, halt_on_stdout=halt_on_output ) #halt_on_output strongly depends on the command #log output to screen if halt_on_output: log_level = out.LEVEL_ERROR if os.stat(output_file).st_size > 0: out.file(output_file, 'php exec', out.LEVEL_ERROR) out.log( 'error executing "' + command + '" via php command system.', 'php', out.LEVEL_ERROR) engine.quit() out.file(output_file, 'php exec', out.LEVEL_INFO) return output_file
def append_md5(filename, copy_zipped=False): suffix = engine.get_suffix(filename) base = filename[:-len(suffix)] md5hash = engine.md5sum(engine.path_join(engine.LOCAL_WWW_DIR, filename)) new_filename = base + md5hash + '.' + suffix run.local('cd ' + engine.LOCAL_WWW_DIR + ' && cp ' + engine.force_relative(filename) + ' ' + engine.force_relative(new_filename)) if copy_zipped: run.local('cd ' + engine.LOCAL_WWW_DIR + ' && cp ' + engine.force_relative(filename) + '.gz ' + engine.force_relative(new_filename) + '.gz') return new_filename
def export_local_db(compression=True): filename = engine.get_database_dump_file(domain='local') if compression: final_filename = gzip.compressed_filename(filename) else: final_filename = filename out.log('exporting local db to ' + final_filename, 'mysql') if (engine.MYSQL4_COMPATIBLE): run.local( engine.LOCAL_MYSQLDUMP_CMD + ' --compatible=mysql4 >' + filename, False) else: run.local(engine.LOCAL_MYSQLDUMP_CMD + '>' + filename, False) if compression: return gzip.compress_local(filename) else: return filename
def get_new_local_file(suffix = None, create_file = False): import run if suffix is None: suffix = 'tmp' #get filename in tmp dir global local_tmp_files tmp_dir = get_local_tmp_dir() filename = tmp_dir + '/tmp_file_' + str(datetime.now()).replace(' ', '_').replace('.','_') + '.' + suffix #register file in current namespace register_local_file(filename) if create_file: run.local('touch ' + filename) #return filename return filename
def create_live_file(upload=False): out.log('creating .htaccess.live', 'htaccess') ht_data = assemble_htaccess_data('live') if engine.NEED_BASIC_AUTH: #get absolute path to remote passwd and inject it into ht_data remote_passwd_file = engine.get_remote_www_dir_abspath() + '/.htpasswd' ht_data = ht_data.replace('[HTPASSWD_FILE]', remote_passwd_file) #create passwd file run.local('htpasswd -bc ' + engine.LOCAL_WWW_DIR + '/.htpasswd ' + engine.AUTH_USER + ' ' + engine.AUTH_PASSWORD, halt_on_stderr=False) transfer.put(engine.LOCAL_WWW_DIR + '/.htpasswd', '.htpasswd') #write local engine.write_local_file(ht_data, filename=engine.LOCAL_WWW_DIR + '/.htaccess.live') #write to remote if upload: engine.write_remote_file(ht_data, filename='.htaccess.live')
def pack_local(files): #tell out.log('packing locally: ' + files, 'tar') #validate files if not validate_files(files): out.log('Error: files need to be given relative to www dir.', 'tar', out.LEVEL_ERROR) engine.quit() #register tar file tar_file = engine.get_new_local_file('tar') #assemble packing command. Always pack from www dir pack_command = 'tar cf ' + tar_file + ' --exclude .tar -C ' + engine.LOCAL_WWW_DIR + ' ' + files #pack! run.local(pack_command) #and return packed file, of course return tar_file
def optimize_png(): out.log('optimizing pngs...', 'image') for root, dirnames, filenames in os.walk(engine.LOCAL_WWW_DIR): for filename in fnmatch.filter(filenames, '*.png'): original_name = root + '/' + filename optimized_name = root + '/' + filename[:-4] + '.opt.png' run.local('pngcrush -q -rem alla -nofilecheck -reduce -m 7 "' + original_name + '" "' + optimized_name + '"', halt_on_stderr = False) if os.path.isfile(optimized_name): new_size = os.path.getsize(optimized_name) old_size = os.path.getsize(original_name) if new_size < old_size: out.log('could reduce ' + original_name + ': ' + str(old_size) + ' --> ' + str(new_size) + ' bytes (' + str(100-100*new_size/old_size) + '%)', 'image') run.local('rm "' + original_name + '"') run.local('mv "' + optimized_name + '" "' + original_name + '"') else: out.log('could not reduce ' + original_name + ': (0%).', 'image') run.local('rm "' + optimized_name + '"') else: out.log('pngcrush did decide not to write an output file for ' + original_name, 'image')
def execute_local_file_nodb(filename): run.local(engine.LOCAL_MYSQL_NO_DB_CMD + '<' + filename, False)
def remove_local_directory_contents(directoy): out.log('remove content of local directory: ' + directory, 'transfer', out.LEVEL_VERBOSE) run.local('rm ' + directory + '/*')
def local_move(from_file, to_file): out.log('move local file: ' + from_file + ' -> ' + to_file, 'transfer', out.LEVEL_VERBOSE) run.local('mv ' + from_file + ' ' + to_file)
def create_local_directory(directory, permissions=None): out.log('create local directory: ' + directory, 'transfer', out.LEVEL_VERBOSE) run.local('mkdir -p ' + directory) if permissions is not None: run.local('chmod ' + str(permissions) + ' ' + directory)
def set_local_mode(file, mode): out.log('setting mode ' + str(mode) + ' on ' + file, 'transfer', out.LEVEL_VERBOSE) command = "chmod " + str(mode) + ' ' + file run.local(command)
def restart(): out.log('restarting server', 'apache') run.local('apachectl graceful', sudo=True)
def unpack_local(archive): out.log('unpacking locally: ' + archive, 'tar') unpack_command = 'tar xf ' + archive + ' -C ' + engine.LOCAL_WWW_DIR run.local(unpack_command)
def append_to_server_config(): try: engine.LOCAL_DOMAIN except: out.log( 'Your LOCAL_DOMAIN variable has not been set. Please specify a valid hostname and try again.' ) return out.log( 'appending virtual hosts and directory directive to ' + engine.LOCAL_HTTPD_CONF, 'apache') run.local('echo "# virtual host set up by fabric deploy script." >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "<VirtualHost *:80>" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " DocumentRoot ' + engine.LOCAL_WWW_DIR + '" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " ServerName ' + engine.LOCAL_DOMAIN + '" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "</VirtualHost>" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "<Directory ' + engine.LOCAL_WWW_DIR + '>" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " Options FollowSymLinks Multiviews" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " MultiviewsMatch Any" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " AllowOverride All" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo " Require all granted" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "</Directory>" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "# virtual host setup end" >>' + engine.LOCAL_HTTPD_CONF, sudo=True) run.local('echo "" >>' + engine.LOCAL_HTTPD_CONF, sudo=True)
def create_wp_salt(when_exists='skip'): out.log('creating wp-salt.php in wordpress directory...', 'wordpress') if overwrite_allowed(engine.LOCAL_WP_DIR + '/wp-salt.php', when_exists): run.local('echo "<?php">' + engine.LOCAL_WP_DIR + '/wp-salt.php') run.local('curl --silent ' + engine.WORDPRESS_SALT_URL + ' >>' + engine.LOCAL_WP_DIR + '/wp-salt.php')
def clean_build_dir(): import run run.local('rm -rf ' + LOCAL_BUILD_DIR)