1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
_retry_import_pymscp = False
try:
import pymscp
except ImportError:
_retry_import_pymscp = True
if _retry_import_pymscp:
"""
libmscp.so is not installed on system library paths. So retry to
import libmscp.so installed on the mscp python module directory.
"""
import os
import ctypes
mscp_dir = os.path.dirname(__file__)
ctypes.cdll.LoadLibrary("{}/libmscp.so".format(mscp_dir))
import pymscp
# inherit static values from pymscp
LOCAL2REMOTE = pymscp.LOCAL2REMOTE
REMOTE2LOCAL = pymscp.REMOTE2LOCAL
SEVERITY_NONE = pymscp.SEVERITY_NONE
SEVERITY_ERR = pymscp.SEVERITY_ERR
SEVERITY_WARN = pymscp.SEVERITY_WARN
SEVERITY_NOTICE = pymscp.SEVERITY_NOTICE
SEVERITY_INFO = pymscp.SEVERITY_INFO
SEVERITY_DEBUG = pymscp.SEVERITY_DEBUG
_STATE_INIT = 0
_STATE_CONNECTED = 1
_STATE_PREPARED = 2
_STATE_RUNNING = 3
_STATE_STOPPED = 4
_STATE_JOINED = 5
_STATE_CLEANED = 6
_STATE_RELEASED = 7
_state_str = {
_STATE_INIT: "init",
_STATE_CONNECTED: "connected",
_STATE_PREPARED: "prepared",
_STATE_RUNNING: "running",
_STATE_STOPPED: "stopped",
_STATE_JOINED: "joined",
_STATE_CLEANED: "cleaned",
_STATE_RELEASED: "released",
}
class mscp:
def __init__(self, remote: str, direction: int, **kwargs):
"""
See src/pymscp.c:wrap_mscp_init() to determine keyword arguments.
"""
self.remote = remote
self.direction = direction
kwargs["remote"] = remote
kwargs["direction"] = direction
self.m = pymscp.mscp_init(**kwargs)
self.src_paths = []
self.dst_path = None
self.state = _STATE_INIT
def __str__(self):
return "mscp:{}:{}".format(self.remote, self._state2str())
def __repr__(self):
return "<{}>".format(str(self))
def __del__(self):
if not hasattr(self, "state"):
return # this instance failed on mscp_init
if self.state == _STATE_RUNNING:
self.stop()
if self.state == _STATE_STOPPED:
self.join()
self.cleanup()
self.release()
def _state2str(self):
return _state_str[self.state]
def connect(self):
if not (self.state == _STATE_INIT or state.state == _STATE_CLEANED):
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_connect(m = self.m)
self.state = _STATE_CONNECTED
def add_src_path(self, src_path: str):
self.src_paths.append(src_path)
pymscp.mscp_add_src_path(m = self.m, src_path = src_path)
def set_dst_path(self, dst_path: str):
self.dst_path = dst_path
pymscp.mscp_set_dst_path(m = self.m, dst_path = dst_path);
def prepare(self):
if self.state != _STATE_CONNECTED:
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
if not self.src_paths:
raise RuntimeError("src path list is empty")
if not self.dst_path:
raise RuntimeError("dst path is not set")
pymscp.mscp_prepare(m = self.m)
self.state = _STATE_PREPARED
def start(self):
if self.state != _STATE_PREPARED:
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_start(m = self.m)
self.state = _STATE_RUNNING
def stop(self):
if self.state != _STATE_RUNNING:
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_stop(m = self.m)
self.state = _STATE_STOPPED
def join(self):
if not (self.state == _STATE_RUNNING or self.state == _STATE_STOPPED):
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_join(m = self.m)
self.state = _STATE_JOINED
def stats(self):
return pymscp.mscp_get_stats(m = self.m)
def cleanup(self):
if self.state == _STATE_RUNNING:
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_cleanup(m = self.m)
self.state = _STATE_CLEANED
def release(self):
if self.state != _STATE_CLEANED:
raise RuntimeError("invalid mscp state: {}".format(self._state2str()))
pymscp.mscp_free(m = self.m)
self.state = _STATE_RELEASED
# Simple interface: mscp.copy(src, dst)
def copy(self, src, dst, nonblock = False):
if self.state < _STATE_CONNECTED:
self.connect()
if type(src) == list:
for path in src:
self.add_src_path(path)
elif type(src) == str:
self.add_src_path(src)
else:
raise ValueError("src must be str of list: '{}'".format(src))
self.set_dst_path(dst)
self.prepare()
self.start()
if nonblock:
return
self.join()
self.cleanup()
|