基于Python的linux服务器工具

code

#!/usr/bin/env python
# -*-coding:GBK -*-
# @Date    : 2019-01-10 10:47:54
# @Author  : Zcyu
# @Link    : none
# @Version : $7.0$``

import re
import shutil
import paramiko
from tkinter import *
import threading
from time import sleep, ctime

class Spec:
    def __init__(self, specFilePath):
        self.specFilePath = specFilePath

    def getSpecFile(self):
        self.specFile = open(self.specFilePath, 'r')

    def freeSpecFile(self):
        self.specFile.close()

    def getDeviceList(self, lineString):
        if lineString.startswith('deviceList'):
            self.deviceList = re.split(r'[=,;\s]', lineString)
            self.deviceList = [item for item in filter(lambda x:x != '', self.deviceList)]
            self.deviceList.remove(self.deviceList[0])

    def getValidString(self, lineString):
        return str((lineString.split('='))[1]).strip()

    def getServerHostname(self, lineString):
        if lineString.startswith('serverHostname'):
            self.serverHostname = self.getValidString(lineString)

    def getServerUsername(self, lineString):
        if lineString.startswith('serverUsername'):
            self.serverUsername = self.getValidString(lineString)

    def getServerPassword(self, lineString):
        if lineString.startswith('serverPassword'):
            self.serverPassword = self.getValidString(lineString)

    def getServerPort(self, lineString):
        if lineString.startswith('serverPort'):
            self.serverPort = self.getValidString(lineString)

    def getServerTrunkPath(self, lineString):
        if lineString.startswith('serverTrunkPath') and not lineString.startswith('serverTurnkPathOnWindows'):
            self.serverTrunkPath = self.getValidString(lineString)

    def getServerTrunkPathOnWindows(self, lineString):
        if lineString.startswith('serverTurnkPathOnWindows'):
            self.serverTurnkPathOnWindows = self.getValidString(lineString)

    def getServerPackagePath(self, lineString):
        if lineString.startswith('serverPackagePath'):
            self.serverPackagePath = self.getValidString(lineString)

    def getPermanentPackageName(self, lineString):
        if lineString.startswith('permanentPackageName'):
            self.permanentPackageName = self.getValidString(lineString)

    def getDeviceUsername(self, lineString):
        if lineString.startswith('deviceUsername'):
            self.deviceUsername = self.getValidString(lineString)

    def getDevicePassword(self, lineString):
        if lineString.startswith('devicePassword'):
            self.devicePassword = self.getValidString(lineString)

    def getDevicePort(self, lineString):
        if lineString.startswith('devicePort'):
            self.devicePort = self.getValidString(lineString)

    def getDevicePackagePath(self, lineString):
        if lineString.startswith('devicePackagePath'):
            self.devicePackagePath = self.getValidString(lineString)

    def getOtherParams(self):
        self.serverPackagePath = self.serverTrunkPath + '/package/vfoswind/vfos'
        self.serverPackagePathOnWindows = self.serverTurnkPathOnWindows + '/package/vfoswind/vfos'

    def getDebugFlag(self, lineString):
        if lineString.startswith('debugFlag'):
            self.debugFlag = int(self.getValidString(lineString))

    def specFileRead(self):

        self.getSpecFile()
        for eachline in self.specFile:
            self.getDebugFlag(eachline)

            self.getServerHostname(eachline)
            self.getServerUsername(eachline)
            self.getServerPassword(eachline)
            self.getServerPort(eachline)
            self.getServerTrunkPath(eachline)
            self.getServerTrunkPathOnWindows(eachline)
            self.getServerPackagePath(eachline)


            self.getDeviceUsername(eachline)
            self.getDevicePassword(eachline)
            self.getDevicePort(eachline)
            self.getDevicePackagePath(eachline)
            self.getDeviceList(eachline)

            self.getPermanentPackageName(eachline)

        self.freeSpecFile()

        self.getOtherParams()

    def specDisplay(self):

        print('================ SPEC LOAD ==================')
        print('specFilePath: ' + self.specFilePath)
        print('debugFlag: ' + str(self.debugFlag))

        print('')
        print('serverHostname: ' + self.serverHostname)
        print('serverUsername: ' + self.serverUsername)
        print('serverPassword: ' + self.serverPassword)
        print('serverPort: ' + self.serverPort)
        print('serverTrunkPath: ' + self.serverTrunkPath)
        print('serverPackagePath: ' + self.serverPackagePath)
        print('serverPackagePathOnWindows: ' + self.serverPackagePathOnWindows)

        print('')
        print('deviceUsername: ' + self.deviceUsername)
        print('devicePassword: ' + self.devicePassword)
        print('devicePort: ' + self.devicePort)
        print('deviceList: ' + str(self.deviceList))
        print('devicePackagePath: ' + self.devicePackagePath)
        print('')


class SshConnection:
    def __init__(self, hostname, username, password, port=22):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.port = port

    def connect(self):
        transport = paramiko.Transport(self.hostname, self.port)

        # connect remote server
        transport.connect(username=self.username, password=self.password)
        self.__transport = transport

        # sftp transfer protocol
        self.sftp = paramiko.SFTPClient.from_transport(self.__transport)

    def close(self):
        self.__transport.close()

    def sendCmd(self, command, echoPrint=True):
        ssh = paramiko.SSHClient()
        ssh._transport = self.__transport

        stdin, stdout, stderr = ssh.exec_command(command)
        result = stdout.read()
        if echoPrint:
            print(str(result, encoding='utf-8'))

            errinfo = ""
            for line in stderr.readlines():
                errinfo += line
            print(str(errinfo))

    def upload(self, localDir, remoteDir):
        self.sftp.put(localDir, remoteDir)
        self.debugLog("upload file form" + localDir + " to " + remoteDir)

    def download(self, remoteDir, localDir):
        self.sftp.get(localDir, remoteDir)
        self.debugLog("download file form" + remoteDir + " to " + localDir)

    def deleteFile(self, file):
        cmdDeleteFile = "rm -rf " + file
        self.sendCmd(cmdDeleteFile)
        self.debugLog(cmdDeleteFile)

    def createFolder(self, folder):
        cmdCreateFolder = "mkdir " + folder
        self.sendCmd(cmdCreateFolder)
        self.debugLog(cmdCreateFolder)

    def copyAllFiles(self, sourceFilePath, DestFilePath):
        cmdCopyAllFiles = "cp -rf " + sourceFilePath + "* " + DestFilePath
        self.sendCmd(cmdCopyAllFiles)
        self.debugLog(cmdCopyAllFiles)

    def zipFile(self, package, sourceFilePath, sourceFileName):
        cmdZipFile = 'cd ' + sourceFilePath + '; tar -zcvf ' + package + ' ' + sourceFileName
        self.sendCmd(cmdZipFile, echoPrint=False)
        self.debugLog(cmdZipFile)

    def unZipFile(self, package, unZipPath):
        cmdUnzipFile = 'tar -zxvf ' + package + ' -C ' + unZipPath
        self.sendCmd(cmdUnzipFile, echoPrint=False)
        self.debugLog(cmdUnzipFile)

    def renameFile(self, previousFile, currentFile):
        cmdRenameFile = 'move ' + previousFile + ' ' + currentFile
        self.sendCmd(cmdRenameFile)
        self.debugLog(cmdRenameFile)

    def debugLog(self, command):
        if spec.debugFlag:
            print("[DEBUG " + self.hostname + "] " + command)


class CompileServer:
    def __init__(self, spec):
        self.hostname = spec.serverHostname
        self.username = spec.serverUsername
        self.password = spec.serverPassword
        self.port = spec.serverPort

        self.chmodCmdStr = 'chmod -R 777 *'

        self.serverPackagePath = spec.serverPackagePath
        self.serverPackagePathOnWindows = spec.serverPackagePathOnWindows
        self.serverTrunkPath = spec.serverTrunkPath
        self.platformBuildPath = spec.serverTrunkPath + '/fos/build'
        self.foswindBuildPath = spec.serverTrunkPath + '/product/vfoswind/build'
        self.permanentPackageName = spec.permanentPackageName

        self.ssh = SshConnection(hostname=self.hostname, username=self.username, password=self.password)

    def platformClean(self):

        cmdClean = './fbld.sh --build-select=12 --version=release --action=clean'

        print(">>>>>>>> " + cmdClean)
        self.ssh.sendCmd('cd ' + self.platformBuildPath + ';' + self.chmodCmdStr + ';' + cmdClean)

    def foswindClean(self):

        cmdClean = './build.sh --build-select=0 --fos-version=release -c'

        print(">>>>>>>> " + cmdClean)
        self.ssh.sendCmd('cd ' + self.foswindBuildPath + ';' + self.chmodCmdStr + ';' + cmdClean)

    def platformBuild(self):

        cmdBuild = './fbld.sh --build-select=12 --version=debug --action=nopatch --stdout=2'

        print(">>>>>>>> " + cmdBuild)
        self.ssh.sendCmd('cd ' + self.platformBuildPath + ';' + self.chmodCmdStr + ';' + cmdBuild)

    def foswindBuild(self):

        cmdBuild = './build.sh --build-select=0 --fos-version=debug --disable-patch'

        print(">>>>>>>> " + cmdBuild)
        self.ssh.sendCmd('cd ' + self.foswindBuildPath + ';' + self.chmodCmdStr + ';' + cmdBuild)

    def foswindPacket(self):

        cmdPacket = "./fpack.sh product=vfoswind device=vfos version=debug fpack_select=x86_64 pkgname=" + spec.permanentPackageName

        print(">>>>>>>> " + cmdPacket)
        self.ssh.sendCmd('cd ' + self.platformBuildPath + ';' + self.chmodCmdStr + ';' + cmdPacket)

    def foswindRenamePackageFile(self):

        for eachfile in os.listdir(self.serverPackagePathOnWindows):
            if eachfile.endswith(".tgz.md5"):
                os.rename(self.serverPackagePathOnWindows + '/' + eachfile,
                          self.serverPackagePathOnWindows + '/' +  self.permanentPackageName + '.md5')
            elif eachfile.endswith('.tgz'):
                os.rename(self.serverPackagePathOnWindows + '/' + eachfile,
                           self.serverPackagePathOnWindows + '/' + self.permanentPackageName)

    def clearPackageFolder(self, echoPrint=True):

        foldPath = self.serverPackagePath
        self.ssh.deleteFile(foldPath)
        self.ssh.createFolder(foldPath)

    def build(self, buildControlFlag):

        if "clean" == BUILDCHOICE[buildControlFlag - 1][0]:
            print("                Start from clean!!!          \n\n")
            self.platformClean()
            self.foswindClean()

            self.platformBuild()
            self.foswindBuild()

            self.foswindPacket()

        elif "build" == BUILDCHOICE[buildControlFlag - 1][0]:
            print("                Start from build!!!          \n\n")
            self.platformBuild()
            self.foswindBuild()

            self.foswindPacket()

        elif "packet" == BUILDCHOICE[buildControlFlag - 1][0]:
            print("                Start from packet!!!         \n\n")
            self.foswindPacket()

        elif "idle" == BUILDCHOICE[buildControlFlag - 1][0]:
            print("                Package reused!!!            \n\n")

        else:
            print("*********************************************\n\n")
            print("           Error occurs in tinker!!!         ")
            print("*********************************************\n")

    def zipSourceFile(self):

        sourceFileName = 'platform'
        sourceFilePath = spec.serverTrunkPath + '/fos'
        package = self.serverPackagePath + '/source.tar.gz'

        self.ssh.zipFile(package, sourceFilePath, sourceFileName)

    def zipAllFiles(self):

        sourceFileName = 'vfos'
        sourceFilePath = spec.serverPackagePath[:-4]
        package = self.serverPackagePath + '/allFiles.tar.gz'

        self.ssh.zipFile(package, sourceFilePath, sourceFileName)

class VfosWind:
    def __init__(self, hostname, spec):
        self.hostname = hostname
        self.port = spec.devicePort
        self.username = spec.deviceUsername
        self.password = spec.devicePassword

        self.chmodCmdStr = 'chmod -R 777 *'
        self.serverPackagePath = spec.serverPackagePath
        self.devicePackagePath = spec.devicePackagePath
        self.serverPackagePathOnWindows = spec.serverPackagePathOnWindows

        self.permanentPackageName = spec.permanentPackageName

        self.ssh = SshConnection(hostname=self.hostname, username=self.username, password=self.password)

    def fosReboot(self):

        cmd_reboot = 'reboot'

        print(">>>>>>>>[" + self.hostname + "]# " + cmd_reboot)
        self.ssh.sendCmd('cd ;' + cmd_reboot)

    def fosUpdate(self):

        cmd_update = './update.sh ' + self.permanentPackageName

        print(">>>>>>>>[" + self.hostname + "]# " + cmd_update)
        self.ssh.sendCmd('cd ' + self.devicePackagePath + ';' + self.chmodCmdStr + ';' + cmd_update)

    def fosStart(self):

        print("set up mpu and lpu here.")

    def clearPackageFolder(self):

        foldPath = self.devicePackagePath
        self.ssh.deleteFile(foldPath)
        self.ssh.createFolder(foldPath)

    def uploadPackageToDevice(self, echoPrint=True):

        self.ssh.upload(self.serverPackagePathOnWindows + '/allFiles.tar.gz',
                        self.devicePackagePath + '/allFiles.tar.gz')

    def unZipFile(self, echoPrint=True):

        allFilesPackage = self.devicePackagePath + '/allFiles.tar.gz'
        sourceFilePackage = self.devicePackagePath + '/source.tar.gz'
        unZipPath = self.devicePackagePath

        self.ssh.unZipFile(allFilesPackage, unZipPath)
        self.ssh.copyAllFiles(self.devicePackagePath + "/vfos/", self.devicePackagePath)
        self.ssh.deleteFile(self.devicePackagePath + "/vfos")
        self.ssh.unZipFile(sourceFilePackage, unZipPath)


def specLoad():

    specFilePath = "C:/FoswindToolSpec.txt"
    spec = Spec(specFilePath)
    spec.specFileRead()
    spec.specDisplay()
    return spec

def processCompileServer(spec, buildControlFlag):
    print("\n=============================================")
    print("[CompileServer] Host: " + spec.serverHostname)

    server = CompileServer(spec)
    server.ssh.connect()

    # server.clearPackageFolder()
    server.build(buildControlFlag)

    server.zipSourceFile()
    server.zipAllFiles()

    server.ssh.close()


def processFosWind(hostname):
    print("\n=============================================")
    print("[Foswind] Host: " + hostname)
    print("          Thread start at: " + ctime() + "\n")

    device = VfosWind(hostname=hostname, spec=spec)
    device.ssh.connect()

    device.clearPackageFolder()
    device.uploadPackageToDevice()
    device.unZipFile()
    device.fosUpdate()

    device.ssh.close()

    # print("Thread finish at: " + ctime())


def getChoice():
    buildControlFlag = v.get()
    for loop in range(len(vfosChoiceList)):
        vfosSetupList.append(vfosChoiceList[loop].get())

    # print("buildControlFlag: " + str(buildControlFlag) + "\n")
    window.destroy()

    processCompileServer(spec, buildControlFlag=buildControlFlag)

    print("=============================================")
    print("           Process remote foswind...         ")
    print("=============================================")

    threads = []

    loop = 0
    for eachDevice in spec.deviceList:
        if vfosSetupList[loop]:
            t = threading.Thread(
                target=processFosWind, args=(eachDevice,))
            threads.append(t)
        loop += 1

    for each_thread in threads:
        each_thread.start()

    for each_thread in threads:
        each_thread.join()

    print("\n")
    print("=============================================")
    print("All threads finish at: " + ctime())
    print("\n")

def guiWindow():
    Label(window, text='Start from:', compound='left', bg='Yellowgreen', font=("ºÚÌå", 20)).pack(fill=X)

    for choice, num in BUILDCHOICE:
        Radiobutton(window, text=choice, variable=v, value=num, bg='Beige',
                    indicatoron=True, width=28, height=2, font=("????", 16)).pack(fill=X)

    Label(window, text='Foswind list:', bg='Yellowgreen', font=("ºÚÌå", 20)).pack(fill=X)

    loop = 0
    for each_item in spec.deviceList:
        Checkbutton(window, text=each_item, indicatoron=True, width=28, height=2,
                    bg='Beige', font=("????", 16), variable=vfosChoiceList[loop]).pack(fill=X)
        loop += 1

    Button( window, text="OK", width=10, font=("????", 20), bg="Yellowgreen", command=getChoice).pack(fill=X)


def echoHold():
    rebuild_flag = 'A'
    while (rebuild_flag != 'Y') and (rebuild_flag != 'N'):

        print("\n\n>>>>>>")
        rebuild_flag = input("Restart Tool? Press Y To Restart, N To Exit:")
        if (rebuild_flag == 'N'):
            break
        else:
            print("\n\n<<<<<< Restart Tool!")
            return True
    return False


print("***********************************************")
print("Authored by Zcyu                               ")
print("                        Welcome                    ")
print("***********************************************")

print("\n")
print("=============================================")
print("starting at: " + ctime() + "\n\n")

vfosChoiceList = []
vfosSetupList = []

spec = specLoad()

ret = True
while ret:
    window = Tk()
    window.title("Authored by Zcyu...")

    v = IntVar()
    v.set(0)

    vfosChoiceList = []
    for i in range(len(spec.deviceList)):
        vfosChoiceList.append(IntVar())

    BUILDCHOICE = [("clean", 1),
                   ("build", 2),
                   ("packet", 3),
                   ("idle", 4)]

    guiWindow()
    mainloop()

    # Clear choice list and preapre for next
    vfosChoiceList = []
    vfosSetupList = []

    print("***********************************************")
    print("Authored by Zcyu                               ")
    print("              Thank you for using              ")
    print("***********************************************")

    ret = echoHold()


### spec
specFilePath = "C:/Spec.txt"
debugFlag = 1

serverHostname = 10.10.10.10
serverUsername = zcyu
serverPassword = zcyu
serverPort = 22
serverTrunkPath = zcyu/trunk
serverTurnkPathOnWindows = //10.10.10.10/zcyu/trunk
permanentPackageName = PACKAGE.tgz

deviceList = 10.20.20.20,10.20.20.21
deviceUsername = zcyu
devicePassword = zcyu
devicePort = 22
devicePackagePath = /home/package



©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。