AlkantarClanX12
| Current Path : /www/capitalgmcbuickregina_830/public/wp-content/plugins/leadbox/pipeline/ |
| Current File : /www/capitalgmcbuickregina_830/public/wp-content/plugins/leadbox/pipeline/server-transfer.py |
import os
import re
import sys
import yaml
import time
import paramiko
import socket
from stat import S_ISDIR
environment = sys.argv[1]
basedir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
server_data_file = os.path.join(basedir, 'pipeline', 'server-data.yml')
if not sys.version_info < (3,):
unicode = str
basestring = str
def u(u_string):
"""
Convert a string to unicode working on both python 2 and 3.
:param u_string: a string to convert to unicode.
.. versionadded:: 0.1.5
"""
if isinstance(u_string, unicode):
return u_string
return u_string.decode('utf-8')
def s(s_string):
"""
Convert a byte stream to string working on both python 2 and 3.
:param s_string: a byte stream to convert to string.
.. versionadded:: 0.1.5
"""
if isinstance(s_string, bytes):
return s_string
return s_string.encode('utf-8')
class SSHSession(object):
# Usage:
# Detects DSA or RSA from key_file, either as a string filename or a
# file object. Password auth is possible, but I will judge you for
# using it. So:
# ssh=SSHSession('targetserver.com','root',key_file=open('mykey.pem','r'))
# ssh=SSHSession('targetserver.com','root',key_file='/home/me/mykey.pem')
# ssh=SSHSession('targetserver.com','root','mypassword')
# ssh.put('filename','/remote/file/destination/path')
# ssh.put_all('/path/to/local/source/dir','/path/to/remote/destination')
# ssh.get_all('/path/to/remote/source/dir','/path/to/local/destination')
# ssh.command('echo "Command to execute"')
def __init__(self, hostname, username='root', password=None, port=22):
#
# Accepts a file-like object (anything with a readlines() function)
# in either dss_key or rsa_key with a private key. Since I don't
# ever intend to leave a server open to a password auth.
#
self.client = paramiko.SSHClient()
self.client.load_system_host_keys()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(hostname=hostname, port=port, username=username,
password=password)
self.transport = self.client.get_transport()
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
def command(self, cmd):
# Breaks the command by lines, sends and receives
# each line and its output separately
#
# Returns the server response text as a string
alldata = u('')
stdin, stdout, stderr = self.client.exec_command(cmd)
while not stdout.channel.exit_status_ready():
# Print stdout data when available
if stdout.channel.recv_ready():
# Retrieve the first 1024 bytes
alldata = u(stdout.channel.recv(1024))
while stdout.channel.recv_ready():
# Retrieve the next 1024 bytes
alldata += u(stdout.channel.recv(1024))
return alldata
def put(self, localfile, remotefile):
# Copy localfile to remotefile, overwriting or creating as needed.
print(localfile, ' > ', remotefile)
self.sftp.put(localfile, remotefile)
def put_all(self, localpath, remotepath):
# recursively upload a full directory
os.chdir(os.path.split(localpath)[0])
parent = os.path.split(localpath)[1]
for walker in os.walk(parent):
try:
self.sftp.mkdir(os.path.join(remotepath, walker[0]))
except:
pass
for file in walker[2]:
self.put(os.path.join(walker[0], file), os.path.join(remotepath, walker[0], file))
def get(self, remotefile, localfile):
# Copy remotefile to localfile, overwriting or creating as needed.
self.sftp.get(remotefile,localfile)
def sftp_walk(self, remotepath):
# Kindof a stripped down version of os.walk, implemented for
# sftp. Tried running it flat without the yields, but it really
# chokes on big directories.
path = remotepath
files = []
folders = []
for f in self.sftp.listdir_attr(remotepath):
if S_ISDIR(f.st_mode):
folders.append(f.filename)
else:
files.append(f.filename)
yield path, folders, files
for folder in folders:
new_path = os.path.join(remotepath, folder)
for x in self.sftp_walk(new_path):
yield x
def get_all(self, remotepath, localpath):
# recursively download a full directory
# Harder than it sounded at first, since paramiko won't walk
#
# For the record, something like this would gennerally be faster:
# ssh user@host 'tar -cz /source/folder' | tar -xz
self.sftp.chdir(os.path.split(remotepath)[0])
parent = os.path.split(remotepath)[1]
try:
os.mkdir(localpath)
except:
pass
for walker in self.sftp_walk(parent):
try:
os.mkdir(os.path.join(localpath,walker[0]))
except:
pass
for file in walker[2]:
self.get(os.path.join(walker[0],file), os.path.join(localpath, walker[0], file))
def main():
with open(server_data_file, 'r') as d:
data = yaml.load(d, Loader=yaml.FullLoader)[environment]
ts = str(int(time.time()))
versionsdirpath = os.path.join(data['path'], 'deployments')
themetspath = os.path.join(versionsdirpath, 'plugin-'+ts)
plugindirpath = os.path.join(data['path'], 'public', 'wp-content', 'plugins')
themepath = os.path.join(plugindirpath, 'leadbox')
session = SSHSession(hostname=data['hostname'],
username=data['username'],
password=data['password'],
port=data['port'])
print()
print('Creating deployment directory')
print('mkdir -pv {0}'.format(themetspath))
print(session.command('mkdir -pv {0}'.format(themetspath)))
print()
print('Transfering files')
for f in ['Leadbox.php','media-uploader.js','update.php','readme.md', 'composer.json']:
destination = os.path.join(themetspath, f)
if os.path.exists(f):
session.put(f, destination)
for f in ['assets','classes', 'dist', 'integrations','vendor', 'languages', 'lib']:
td = os.path.join(basedir, f)
if os.path.exists(td):
session.put_all(td, themetspath)
#index_file = os.path.join(basedir,'index.php')
#if os.path.exists('index.php'):
# session.put('index.php', themetspath)
print()
print('Removing symbolic link')
print('rm -rvf {0}'.format(themepath))
print(session.command('rm -rvf {0}'.format(themepath)))
print()
print('Creating new symbolic link')
print('ln -svf {0} {1}'.format(themetspath, themepath))
print(session.command('ln -svf {0} {1}'.format(themetspath, themepath)))
print()
print('Removing old versions')
existentdirs = session.command('ls -1 {0} | grep plugin'.format(versionsdirpath))
print(existentdirs)
removedirs = list(filter(None, existentdirs.split('\n')))[:-3]
for d in removedirs:
print('rm -rvf {0}'.format(os.path.join(versionsdirpath, d)))
print(session.command('rm -rvf {0}'.format(os.path.join(versionsdirpath, d))))
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())