作者:大眼妹PS珺珺 | 来源:互联网 | 2023-10-12 13:54
最近重新看了下salt-cp实现的过程,源代码逻辑相对简单,明白了salt-cp为什么只能针对文本文件、配置文件的拷贝。现在就来看看对应的代码吧源代码文件:saltclicp.py
最近重新看了下salt-cp实现的过程,源代码逻辑相对简单,明白了salt-cp为什么只能针对文本文件、配置文件的拷贝。现在就来看看对应的代码吧
源代码文件:
salt/cli/cp.py
class SaltCP(object):
def __init__(self, opts):
self.opts = opts
# 读取文件内容,返回单元素字典:文件名-->文件内容
def _file_dict(self, fn_):
‘‘‘
Take a path and return the contents of the file as a string
‘‘‘
if not os.path.isfile(fn_):
err = ‘The referenced file, {0} is not available.‘.format(fn_)
sys.stderr.write(err + ‘\n‘)
sys.exit(42)
with salt.utils.fopen(fn_, ‘r‘) as fp_:
data = fp_.read()
return {fn_: data}
# 用来迭代文件的,产生一个字典:文件名-->文件内容
def _load_files(self):
‘‘‘
Parse the files indicated in opts[‘src‘] and load them into a python
object for transport
‘‘‘
files = {}
for fn_ in self.opts[‘src‘]:
if os.path.isfile(fn_):
# 更新字典
files.update(self._file_dict(fn_))
elif os.path.isdir(fn_):
print(fn_ + ‘ is a directory, only files are supported.‘)
#files.update(self._recurse_dir(fn_))
# files: {‘filename1‘:content,‘filename2‘:content}
return files
# 调用的是salt.client.LocalClient的方法cmd,调用cp.recv函数拷贝
def run(self):
‘‘‘
Make the salt client call
‘‘‘
arg = [self._load_files(), self.opts[‘dest‘]]
local = salt.client.LocalClient(self.opts[‘conf_file‘])
args = [self.opts[‘tgt‘],
‘cp.recv‘,
arg,
self.opts[‘timeout‘],
]
selected_target_option = self.opts.get(‘selected_target_option‘, None)
if selected_target_option is not None:
args.append(selected_target_option)
ret = local.cmd(*args)
pprint.pprint(ret)
从代码可以看出,拷贝文件前,需要读取文件的内容,并以{file:data}的形式返回。
然后调用salt.client.LocalClient的cmd方法并调用cp.recv函数拷贝。
cp.recv对应代码如下:
def recv(files, dest):
‘‘‘
Used with salt-cp, pass the files dict, and the destination.
This function receives small fast copy files from the master via salt-cp.
It does not work via the CLI.
‘‘‘
ret = {}
for path, data in files.items():
if os.path.basename(path) == os.path.basename(dest) and not os.path.isdir(dest):
final = dest
elif os.path.isdir(dest):
final = os.path.join(dest, os.path.basename(path))
elif os.path.isdir(os.path.dirname(dest)):
final = dest
else:
return ‘Destination unavailable‘
try:
salt.utils.fopen(final, ‘w+‘).write(data)
ret[final] = True
except IOError:
ret[final] = False
return ret
我们可以直接以下面的形式调用这个api
opts = {
‘tgt‘: ‘192.168.110.132‘, # target
‘src‘: [‘file1‘,‘file2‘,] # 需要拷贝的文件路劲
‘conf_file‘: ‘/opt/app/salt/etc/master‘, # master的配置文件
‘dest‘: ‘/mnt‘, # 目标目录
‘timeout‘: 5, # 过期时间
}
cp = salt.cli.cp.SaltCP(opts)
cp.run()
# 最终调用是这样的形式
local.cmd(‘192.168.110.132‘,‘cp.recv‘,[{‘/root/data‘:content},‘/mnt‘],5)
看完之后,才知道salt-cp的实现原理这么简单,简单的只能拷贝配置文件、文本文件、小文件。对于大文件的拷贝,后面会有方法。
本文出自 “fly天地” 博客,请务必保留此出处http://liuping0906.blog.51cto.com/2516248/1553252
salt的api学习记录---salt-cp命令的执行过程