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的實現原理這麼簡單,簡單的只能拷貝配置文件、文本文件、小文件。對於大文件的拷貝,後面會有方法。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章