# -*- coding: utf-8 -*- # Copyright 2010-2016 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import pexpect import sys import os import tempfile from calculate.lib.utils.ip import check_port from calculate.lib.utils.files import readFile class ProfileSyncerError(Exception): pass class ProfileSyncer(): def __init__(self, hostname, port, username, passwd): self.hostname = hostname self.port = port self.username = username self.passwd = passwd self.exitstatus = None def check(self): return check_port(self.hostname, self.port) def create_process(self, source, target, *params): #подключение к домену и синхрозизация self.process = pexpect.spawn('/usr/bin/rsync', ['--rsh=/usr/bin/ssh -o "ControlMaster no" -o "StrictHostKeyChecking no" -p{port} {username}@{hostname}'.format( port=self.port, hostname=self.hostname, username=self.username), '--info=progress2'] + list(params) + [source, target]) def readfile(self, filename): tmp_fn = tempfile.mktemp() for i in self.sync(filename, tmp_fn): pass if self.exitstatus == 0: data = readFile(tmp_fn) if os.path.exists(tmp_fn): os.unlink(tmp_fn) return data raise ProfileSyncerError("Profile server not found") def exists(self, filename): env = dict(os.environ) env["LANG"] = "C" #подключение к домену и синхрозизация self.process = pexpect.spawn('/usr/bin/rsync', ['--rsh=/usr/bin/ssh -o "ControlMaster no" -o "StrictHostKeyChecking no" -p{port} {username}@{hostname}'.format( port=self.port, hostname=self.hostname, username=self.username), '--list-only', filename], env=env) i = self.process.expect(['[Pp]assword', '(\d+)%', pexpect.EOF]) if i == 0: self.process.sendline("{}\n".format(self.passwd)) self.process.wait() data = self.process.read() self.process.close() return b"No such file or directory (2)" not in data def sync(self, source, target, *params): num = -1 self.create_process(source, target, *params) while True: i = self.process.expect(['[Pp]assword', '(\d+)%', pexpect.EOF]) if i == 0: self.process.sendline("{}\n".format(self.passwd)) elif i == 1: newnum = int(self.process.match.group(1)) if newnum > num: num = newnum yield newnum else: self.output = self.process.before self.process.close() existatus = self.process.exitstatus #error 24 - "files vanished" is not fatal self.exitstatus = existatus if existatus != 24 else 0 yield 100 break