python作业类Fabric主机管理程序开发(第九周)
作业需求:
1. 运行程序列出主机组或者主机列表
2. 选择指定主机或主机组
3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
4. 充分使用多线程或多进程
5. 不同主机的用户名密码、端口可以不同
思路解析:
1. 运用paramiko模块里的command和sftp方法执行命令传输文件
2. 指定主机和主机组,使用字典读取字典信息里的组和服务器信息,列出主机组和主机列表
3. 用threading模块控制paramiko模块里的command和sftp方法执行命令传输文件
4. 字典信息可以添加修改
程序核心代码
README
作者:yaobin
版本:简单Ftp示例版本 v0.1
开发环境: python3.6 程序介绍:
类 Fabric 主机管理程序开发:
1. 运行程序列出主机组或者主机列表
2. 选择指定主机或主机组
3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)
4. 充分使用多线程或多进程
5. 不同主机的用户名密码、端口可以不同 使用说明: /bin/fortress_machine ├─bin
│ fortress_machine.py #程序主目录
│ __init__.py
│
├─conf
│ │ server_list
│ │ setting.py
│ │ __init__.py
│ │
│
├─core
│ │ add_machine.py #添加server字典程序
│ │ basic_dict.py #初始化字典程序
│ │ fortress_main.py #交互程序
│ │ group_paramiko.py #组管理交互程序
│ │ group_sftp.py #组上传/下载交互程序
│ │ server_paramiko.py #server管理交互程序
│ │ server_sftp.py #server上传/下载交互程序
│ │ __init__.py
│ │
│ └─__pycache__
├─db
│ ├─download #文件下载目录
│ └─upload #文件上传目录
│ AutoResponder.xml
│
├─logs
│ __init__.py
│
└─model
│ prettytable.py PrettyTable模块
│ __init__.py
│
├─paramiko paramiko 模块
│
└─__pycache__
prettytable.cpython-36.pyc
__init__.cpython-36.pyc
add_machine.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''添加主机和主机组类'''
import os
import sys
import re
import pickle
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model.prettytable import PrettyTable class add_machine_list(object):
'''
add_machine类
'''
def __init__(self):
'''
构造函数
:param dict_file_object 字典文件
'''
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) #server_list_dict服务器字典变量
dict_file_object.close() def add_group_object(self):
'''
添加新群组新群组server字典函数
:return:
'''
self.view_server()
self.group_server_name = input('请输入要添加的组名称>>>>>>>>:') # 组名key input 打印组内机器
if self.group_server_name in self.server_list_dict['machine']:
print('%s组已经存在,请重新输入...' % self.group_server_name)
self.add_group_object()
else:
self.add_new_group_server(self.group_server_name)
self.group_server_object = {self.server_name: {'ip': self.server_name, 'port': self.server_port,
'username': self.server_username,
'passwd': self.server_passwd}} # 添加group
self.server_list_dict['machine'][self.group_server_name] = self.group_server_object
with open(setting.server_list_path, 'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(self.server_list_dict))
dict_file_object.close()
self.view_server() def add_server_object(self):
'''
添加组内server字典函数
:return:
'''
self.view_server()
self.group_server_name = input('请输入要添加server的组>>>>>>>>:')
if self.group_server_name in self.server_list_dict['machine']:
self.add_server(self.group_server_name)
server_object = {'ip': self.server_name, 'port': self.server_port, 'username': self.server_username,
'passwd': self.server_passwd} # 添加server
self.server_list_dict['machine'][self.group_server_name][self.server_name] = server_object
with open(setting.server_list_path, 'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(self.server_list_dict))
dict_file_object.close()
print('Server add done please check')
self.view_server()
else:
print('要添加server的组%s不存在请重新输入' % self.group_server_name)
self.add_server_object() def add_server(self,group_server_name):
'''
添加组内server函数
:param:group_server_name: groupname
:return:
'''
self.view_server()
try:
self.server_name = input('请输入要添加的server ip>>>>>>>>:') # 添加server 机器
server_name_re_rr = \
re.compile("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "" # 判断ip正则
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$")
res = server_name_re_rr.findall(self.server_name)
if res[0]: #如果有值判断是否正常
if self.server_name not in self.server_list_dict['machine'][self.group_server_name]:
while True:
try:
self.server_port = input('请输入要添加的server port>>>>>>>>:') # 判断port 1-65535
if int(self.server_port) >= 22 and int(self.server_port) < 65535:
self.server_username = input('请输入要添加的server username>>>>>>>>:')
self.server_passwd = input('请输入要添加的server passwd>>>>>>>>:')
break # 正常取完变量后才能结束
else:
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except ValueError: # 如果出现valueerror
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
else:
print('%s已经存在,请重新输入' % self.server_name)
self.add_server(self.group_server_name)
except IndexError as e:
print('%s输入不正确,请输入正确的ip地址'%self.server_name)
self.add_server(self.group_server_name) def add_new_group_server(self,group_server_name):
'''
添加新组server函数
:param group_server_name:要添加的组名
:return:
'''
self.view_server()
try:
self.server_name = input('请输入要添加的server ip>>>>>>>>:') # 添加server 机器
server_name_re_rr = \
re.compile("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "" # 判断ip正则
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + ""
"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$")
res = server_name_re_rr.findall(self.server_name)
if res[0]: # 如果有值判断是否正常
while True:
try:
self.server_port = input('请输入要添加的server port>>>>>>>>:') # 判断port 1-65535
if int(self.server_port) >= 22 and int(self.server_port) < 65535:
self.server_username = input('请输入要添加的server username>>>>>>>>:')
self.server_passwd = input('请输入要添加的server passwd>>>>>>>>:')
break # 正常取完变量后才能结束
else:
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except ValueError: # 如果出现valueerror
print('%s输入不正确,请输入22或22以上65535以下的数字' % self.server_port)
except IndexError as e:
print('%s输入不正确,请输入正确的ip地址' % self.server_name)
self.add_server(self.group_server_name)
self.view_server() def modifi_group(self,group,ip,port,username,passwd):
'''
修改server群组名和server群组内机器的方法,暂不做处理
:param group:
:param ip:
:param port:
:param username:
:param passwd:
:return:
''' def view_server(self):
'''
查看server函数
:return:
'''
view_ip = PrettyTable(['Group.', 'Ip', ])
for i in self.server_list_dict['machine']:
for s in self.server_list_dict['machine'][i]:
view_ip.add_row([i, s])
print('%s' % view_ip)
basic_dict.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
import pickle
from conf import setting
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
def basic_dict():
'''
初始化程序字典
:return:
'''
add_machine_dict = {'machine':{'group1':{'192.168.84.130':
{'ip':'192.168.84.130','port':'','username':'root','passwd':''}}}}
with open(setting.server_list_path,'wb') as dict_file_object:
dict_file_object.write(pickle.dumps(add_machine_dict))
dict_file_object.close()
fortress_main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''主交互程序'''
import os
import sys base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from model.prettytable import PrettyTable
from core import add_machine
from core import group_paramiko
from core import server_paramiko class fortress_machine(object):
'''
类Fabric主机管理程序
'''
def __init__(self):
'''
构造方法
'''
pass def cmd_choice(self):
'''
帮助函数
:return:
'''
cmd_choice = PrettyTable(['No.', '说明'])
cmd_choice.add_row(['', '组管理'])
cmd_choice.add_row(['', '主机管理'])
cmd_choice.add_row(['', ' 添加server'])
cmd_choice.add_row(['', ' 添加group'])
cmd_choice.add_row(['', ' 查看server'])
cmd_choice.add_row(['', '退出程序'])
print(cmd_choice) def user_choice(self):
'''
用户选择函数
:return:
'''
while True:
self.cmd_choice()
user_choice = input('Please input your choice>>>>>>:')
if user_choice == '':
print('Welcome ,The list of hosts is as follows ')
group_paramiko.fortress_main().choice()
if user_choice == '':
print('Welcome ,The list of hosts is as follows ')
server_paramiko.fortress_main().choice()
elif user_choice == '':
add_machine.add_machine_list().add_server_object()
elif user_choice == '':
add_machine.add_machine_list().add_add_group_object()
elif user_choice == '' or user_choice == 'q' or user_choice == 'exit':
add_machine.add_machine_list().view_server()
elif user_choice == '' or user_choice == 'q' or user_choice == 'exit':
sys.exit('程序退出')
else:
print('disallow %s please input again'%user_choice)
group_paramiko.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''类Fabric主机管理交互程序'''
import os
import sys
import pickle
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from core import add_machine
from model import paramiko
from core import group_sftp
from model.prettytable import PrettyTable class fortress_main(object):
'''fortress类'''
def __init__(self):
'''
构造函数
'''
self.semaphore = threading.BoundedSemaphore(1)
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def choice(self):
'''
输入函数
:return:
'''
add_machine.add_machine_list().view_server()
self.group_input = input('Please input group name >>>>>>>>:')
if self.group_input in self.server_list_dict['machine']:
self.group_send_command()
else:
print('There is no group named %s ' % self.group_input)
self.choice()
return self.group_input def ssh_group_cmd(self,command):
'''
组管理函数
:return:
'''
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.ssh.connect(self.server_ip, self.server_port, self.server_username, self.server_passwd)
self.t1 = threading.Thread(target=self.ssh_command(command))
self.t1.setDaemon(True)
self.t1.start() def ssh_connect(self,ip,port,username,passwd):
'''
批量激活主机函数
:param ip:
:param port:
:param username:
:param passwd:
:return:
'''
self.t = threading.Thread(target=self.ssh.connect,args=(ip, port, username,passwd))#开启线程
self.t.setDaemon(True) #设置守护线程
self.t.start() def ssh_command(self,command):
'''
发送ssh服务器命令
:param command:
:return:
'''
stdin, stdout, stderr = self.ssh.exec_command(command)
res, err = stdout.read(), stderr.read() # 定义俩个变量
self.semaphore.acquire()
result = res if res else err # 定义三元运算
print((self.server_ip).center(50,'-'))
print(result.decode())
self.ssh.close()
self.semaphore.release() def group_send_command(self):
'''
group发送指令函数
:return:
\ '''
while True:
command_input = input('please input command,input help for help >>>>>>>>:').strip() # 这里要调用命令
if len(command_input) == 0:
pass
elif len(command_input.split()) == 1:
if command_input == 'help':
self.help_page()
elif command_input == 'exit':
self.ssh.close()
exit()
else:
self.ssh_group_cmd(command_input)
elif len(command_input.split()) >= 2: # 命令分割
cmd_split = command_input.split()[0]
self.fileobject = command_input.split()[1] # 获取文件路径
self.filename = self.fileobject.split('/')[-1] # 获取文件名
if cmd_split == 'get': #未处理
group_sftp.group_ftp(self.group_input,self.fileobject,self.filename).download()
elif cmd_split == 'put':#未处理
group_sftp.group_ftp(self.group_input,self.fileobject,self.filename).upload()
elif cmd_split == 'help':
self.help_page()
else:
self.ssh_group_cmd(command_input)
else:
print('unsupported command')
self.help_page() def help_page(self):
'''
help页面
:return:
'''
help_page = PrettyTable(['Command.', 'Explain', ])
help_page.add_row(['get filename', ' download file'])
help_page.add_row(['put /path/filename', 'upload file'])
help_page.add_row(['other', 'send command'])
help_page.add_row(['exit ', 'exit program'])
help_page.add_row(['help ', ''])
print('%s' % help_page)
group_sftp.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
import os
import sys
import pickle
import platform
import threading
import time,random
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model import paramiko class group_ftp(object):
'''
serverftp类
'''
def __init__(self,group_input,fileobject,filename):
'''
构造函数
:param group_input:
:param server_input:
:param fileobject:
'''
self.group_input = group_input
self.fileobject = fileobject
self.filename = filename with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def upload(self):
'''
上传函数
:param command:
:return:
'''
try:
os.chdir(setting.upload_path)
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
t = threading.Thread(target=self.sftp.put, args=(self.filename, self.fileobject))
t.start()
except FileNotFoundError as e:
print('system error ', e) def download(self):
'''
下载函数
:param
:return:
'''
os.chdir(setting.download_path)
for s in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][s]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][s]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][s]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][s]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
try:
if platform.system() == 'Windows':
#self.sftp.get(self.fileobject, (setting.download_path + '\\' + self.filename))
t = threading.Thread(target=self.sftp.get,args=(self.fileobject, (setting.download_path + '\\' + self.filename)))
t.start()
#time.sleep(10)
else:
#self.sftp.get(self.fileobject, (setting.download_path + '/' + self.filename))
t = threading.Thread(target=self.sftp.get,
args=(self.fileobject, (setting.download_path + '\\' + self.filename)))
t.start()
if os.path.exists(setting.download_path + '\\' + self.filename):
print('file download complete')
else:
print('file download error')
except FileNotFoundError as e:
print('system error ', e)
os.remove(self.filename)
server_paramiko.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''类Fabric主机管理交互程序'''
import os
import sys
import pickle
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from core import add_machine
from core import server_sftp
from model import paramiko
from model.prettytable import PrettyTable class fortress_main(object):
'''fortress类''' def __init__(self):
'''
构造函数
'''
self.semaphore = threading.BoundedSemaphore(1)
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close() def choice(self):
'''
模式选择函数
:return:
'''
add_machine.add_machine_list().view_server()
self.group_input = input('Please input group name >>>>>>>>:')
self.server_input = input('Please input the server name you want to manage >>>>>>>>:')
if self.group_input in self.server_list_dict['machine']:
if self.server_input in self.server_list_dict['machine'][self.group_input]:
self.server_send_command()
else:
print('There is no server named %s please input again' % self.server_input)
self.choice()
else:
print('There is no group named %s please input again' % self.group_input)
self.choice()
return self.group_input,self.server_input def ssh_server_cmd(self,command):
'''
server管理函数
:return:
'''
self.server_ip = self.server_list_dict['machine'][self.group_input][self.server_input]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][self.server_input]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][self.server_input]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][self.server_input]['passwd']
self.ssh.connect(self.server_ip, self.server_port, self.server_username, self.server_passwd)
self.t1 = threading.Thread(target=self.ssh_command(command))
self.t1.setDaemon(True)
self.t1.start()
print('thread name is %s' % self.t1.getName()) def ssh_connect(self,ip,port,username,passwd):
'''
批量激活主机函数
:param ip:
:param port:
:param username:
:param passwd:
:return:
'''
self.t = threading.Thread(target=self.ssh.connect,args=(ip, port, username,passwd))#开启线程
self.t.setDaemon(True) #设置守护线程
self.t.start() def ssh_command(self,command):
'''
发送ssh服务器命令
:param command:
:return:
'''
stdin, stdout, stderr = self.ssh.exec_command(command)
res, err = stdout.read(), stderr.read() # 定义俩个变量
self.semaphore.acquire()
result = res if res else err # 定义三元运算
print((self.server_ip).center(50,'-'))
print(result.decode())
self.ssh.close()
self.semaphore.release() def server_send_command(self):
'''
server发送指令函数
:return:
'''
while True:
command_input = input('please input command,input help for help >>>>>>>>:').strip() # 这里要调用命令
if len(command_input) == 0:
pass
elif len(command_input.split()) == 1:
if command_input == 'help':
self.help_page()
elif command_input == 'exit':
self.ssh.close()
exit()
else:
self.ssh_server_cmd(command_input)
elif len(command_input.split()) >= 2: # 命令分割
cmd_split = command_input.split()[0]
self.fileobject = command_input.split()[1] # 获取文件路径
self.filename = self.fileobject.split('/')[-1] # 获取文件名
print(self.fileobject)
print(self.filename)
if cmd_split == 'get':
server_sftp.server_ftp(self.group_input,self.server_input,self.fileobject, self.filename).download()
elif cmd_split == 'put':
server_sftp.server_ftp(self.group_input,self.server_input,self.fileobject, self.filename).upload()
elif cmd_split == 'help':
self.help_page()
else:
self.ssh_server_cmd(command_input)
else:
print('unsupported command')
self.help_page() def help_page(self):
'''
help页面
:return:
'''
help_page = PrettyTable(['Command.', 'Explain', ])
help_page.add_row(['get filename', ' download file'])
help_page.add_row(['put /path/filename', 'upload file'])
help_page.add_row(['other', 'send command'])
help_page.add_row(['exit ', 'exit program'])
help_page.add_row(['help ', ''])
print('%s' % help_page)
server_sftp.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao import os
import sys
import pickle, json
import platform
import threading
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from conf import setting
from model import paramiko class server_ftp(object):
'''
serverftp类
'''
def __init__(self, group_input,server_input,fileobject,filename):
'''
构造函数
:param group_input:
:param server_input:
:param fileobject:
'''
self.group_input = group_input
self.server_input = server_input
self.fileobject = fileobject
self.filename = filename with open(setting.server_list_path, 'rb') as dict_file_object:
self.server_list_dict = pickle.load(dict_file_object) # server_list_dict服务器字典变量
dict_file_object.close()
if self.group_input in self.server_list_dict['machine']:
if self.server_input in self.server_list_dict['machine'][self.group_input]:
self.server_ip = self.server_list_dict['machine'][self.group_input][self.server_input]['ip']
self.server_port = int(self.server_list_dict['machine'][self.group_input][self.server_input]['port'])
self.server_username = self.server_list_dict['machine'][self.group_input][self.server_input]['username']
self.server_passwd = self.server_list_dict['machine'][self.group_input][self.server_input]['passwd']
self.transport = paramiko.Transport((self.server_ip, self.server_port))
self.transport.connect(username=self.server_username, password=self.server_passwd)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
else:
pass
else:
print('not allow')
def upload(self):
'''
上传函数
:param command:
:return:
'''
try:
os.chdir(setting.upload_path)
self.sftp.put(self.filename,self.fileobject)
except FileNotFoundError as e:
print('system error ', e) def download(self):
'''
下载函数
:param
:return:
'''
os.chdir(setting.download_path)
try:
if platform.system() == 'Windows':
self.sftp.get(self.fileobject, (setting.download_path + '\\' + self.filename))
else:
self.sftp.get(self.fileobject, (setting.download_path + '/' + self.filename))
if os.path.exists(setting.download_path + '\\' + self.filename):
print('file download complete')
else:
print('file download error')
except FileNotFoundError as e:
print('system error ', e)
os.remove(self.filename)
setting.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: Colin Yao
'''配置文件'''
import os
import sys
import platform base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir) if platform.system() == 'Windows':
server_list_path = os.path.dirname(os.path.abspath(__file__))+'\\'+'server_list'#主机列表字典路径变量
server_dict_path = os.path.dirname(os.path.abspath(__file__)) + '\\' + 'server_dict'
download_path = (base_dir+'\\'+'db\download') #下载路径变量
upload_path = (base_dir + '\\' + 'db\\upload') #上传路径变量
else:
server_list_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'server_list'
server_dict_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'server_dict'
download_path = (base_dir + '/' + 'db\download')
upload_path = (base_dir + '/' + 'db\\upload')
程序测试样图
python作业类Fabric主机管理程序开发(第九周)的更多相关文章
- python第五十二天---第九周作业 类 Fabric 主机管理程序
类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)4. 充分使用多线程或多进程5. 不同 ...
- python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)
类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...
- python 学习分享-实战篇类 Fabric 主机管理程序开发
# 类 Fabric 主机管理程序开发: # 1. 运行程序列出主机组或者主机列表 # 2. 选择指定主机或主机组 # 3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载) # 4. 充分 ...
- 类 Fabric 主机管理程序开发
类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载4. 充分使用多线程或多进程5. 不同主 ...
- paramiko类Fabric主机管理
环境:Linux python3.5 要求:类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/ ...
- python作业Select版本FTP(第十周)
SELECT版FTP: 使用SELECT或SELECTORS模块实现并发简单版FTP 允许多用户并发上传下载文件 思路解析: 1. 使用IO多路复用的知识使用SELECTORS封装好的SELECTOR ...
- 老男孩Day10作业:主机管理程序
一.作业需求: 1, 运行程序列出主机组或者主机列表 2,选择指定主机或主机组 3,选择主机或主机组传送文件(上传/下载) 4,充分使用多线程或多进程 5,不同主机的用户名,密码,端口可以不同 6,可 ...
- python作业模拟计算器开发(第五周)
作业需求: 模拟计算器开发: 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/1 ...
- python 作业
Linux day01 计算机硬件知识整理 作业要求:整理博客,内容如下 编程语言的作用及与操作系统和硬件的关系 应用程序->操作系统->硬件 cpu->内存->磁盘 cpu与 ...
随机推荐
- java 基础 --Collection(Set)
注意: 如果hashSet存储自定义对象,一定要重写hashCode()&&equals() 如果TreeSet存储自定义对象,让元素所属的类实现自然排序接口Comparable,并重 ...
- 剖析Vue原理&实现双向绑定MVVM-2
vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化得不能再简化的代码实现一个简单的 hello world 示例. 一 ...
- nodejs之Buffer
Buffer是什么? 简单点理解,buff就是固定长度的uint8array.(es6已实现TypedArray). 由于是固定长度所以没有了splice,concat方法. 由于是固定类型所以没有了 ...
- SolrPerformanceFactors--官方文档
原文地址:http://wiki.apache.org/solr/SolrPerformanceFactors Contents Schema Design Considerations indexe ...
- jmeter3.2生成图形html遇到的问题Error in NonGUIDriver java.lang.IllegalArgumentException: Results file:log is not empty
遇到Creating summariser <summary> Error in NonGUIDriver java.lang.IllegalArgumentException: Resu ...
- wireshark系列之wireshark简介
前言:为什么要学wireshark?工欲善其事必先利其器,wireshark是一款工具软件,主要作用是抓取数据封包,可以帮助我们更加直观更加具象的学习各种网路协议(http.TLS.TCP.UDP.I ...
- 洛谷 P2574 XOR的艺术
刚刚学了,线段树,一道线段树入门题试试水 下面是题面 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个 ...
- [BZOJ4540][HNOI2016]序列 莫队
4540: [Hnoi2016]序列 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...
- Unity3D手游开发日记(7) - 适合移动平台的天气效果
腾讯的天涯明月刀的天气很棒,以前我也在CE3的基础上做了一个效果差不多的,但是在手机上,还是斜下固定视角的游戏,是否还需要一个天气系统? 而且没有G-Buffer的支持,很多牛逼效果实现不了,比如角色 ...
- bzoj3306: 树(dfs序+倍增+线段树)
比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...