salt的api学习记录---salt-cp命令的执行过程

最近重新看了下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的实现原理这么简单,简单的只能拷贝配置文件、文本文件、小文件。对于大文件的拷贝,后面会有方法。



你可能感兴趣的:(cmd,saltstack,salt-cp)