Skip to content

Commit ef8f71b

Browse files
author
Vincent Vinet
committed
wip again
Change-Id: Iaa17c3649eeb65b2aa6fe7c47058515f64ddf7ab
1 parent e1f4711 commit ef8f71b

File tree

5 files changed

+176
-194
lines changed

5 files changed

+176
-194
lines changed

tilde/core.py

Lines changed: 60 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
import os
55
import pwd, grp
66

7-
8-
from tilde.ssh import SSHServer, RunCommandProtocol
9-
107
from twisted.internet import defer
118
from twisted.internet.error import ProcessTerminated
129

10+
from tilde import models
11+
from tilde.ssh import SSHServer, RunCommandProtocol
12+
1313

1414
class ServerManager(object):
1515
def __init__(self, reactor, servers):
@@ -62,16 +62,19 @@ def _openConnection(self, name, config):
6262
class ShareUpdater(object):
6363
CMD_STAT = "/usr/bin/stat"
6464
CMD_TEST = "/usr/bin/test"
65-
CMD_MKDIR = "/usr/bin/mkdir"
66-
CMD_CHOWN = "/usr/bin/chown"
67-
CMD_CHMOD = "/usr/bin/chmod"
65+
CMD_MKDIR = "/bin/mkdir"
66+
CMD_CHOWN = "/bin/chown"
67+
CMD_CHMOD = "/bin/chmod"
68+
CMD_RSYNC = "/usr/bin/rsync"
69+
CMD_MOVE = "/bin/mv"
6870

6971
DEF_MODE = 0700
7072
def __init__(self, server, cfg):
7173
self.server = server
7274
self.name = cfg.hostname
7375
self.root = cfg.root
7476
self.archive_root = cfg.archive_root
77+
self.trash_root = cfg.trash_root
7578

7679
def __repr__(self):
7780
return "<ShareUpdater for {0}>".format(self.name)
@@ -84,49 +87,6 @@ def get_real_path(self, homepath, base=None):
8487
realpath = os.path.join(base, shareabs)
8588
return realpath
8689

87-
88-
def uid_to_name(self, uid=None):
89-
if uid is None:
90-
uid = os.getuid()
91-
return pwd.getpwuid(uid).pw_name
92-
93-
def gid_to_name(self, gid=None):
94-
if gid is None:
95-
gid = os.getgid()
96-
return grp.getgrgid(gid).gr_nam
97-
98-
def name_to_uid(self, name):
99-
return pwd.getpwnam(name).pw_uid
100-
101-
def name_to_gid(self, name):
102-
return grp.getgrnam(name).gr_gid
103-
104-
def get_user(self, path):
105-
return self.uid_to_name(os.stat(path).st_uid)
106-
107-
def get_group(self, path):
108-
return self.gid_to_name(os.stat(path).st_gid)
109-
110-
def update(self, home, state):
111-
if home.server_name != state.server_name:
112-
if home.server_name == self.server:
113-
mlog.debug("req create")
114-
self.create(home, state)
115-
elif state.server_name == self.server:
116-
mlog.debug("req remove")
117-
self.remove(home, state)
118-
return
119-
120-
if home.server_name != self.server:
121-
mlog.debug(u"bad server {0} != {1}"
122-
.format(home.server_name, self.server))
123-
return
124-
125-
if home.path != state.path:
126-
self.move(home, state)
127-
128-
self.set_perms(home, state)
129-
13090
def exists(self, path):
13191
d = defer.Deferred()
13292
cmd = self.server.runCommand(
@@ -164,6 +124,13 @@ def _failed(reason):
164124
cmd.finished.chainDeferred(d)
165125
return d
166126

127+
def _make_parent(self, path):
128+
parent = os.path.split(os.path.normpath(path))[0]
129+
return self.server.runCommand(
130+
" ".join([self.CMD_MKDIR, "-p", parent])
131+
).finished
132+
133+
167134
def create_home(self, home):
168135
d = defer.Deferred()
169136
realpath = self.get_real_path(home.path)
@@ -176,16 +143,16 @@ def create_home(self, home):
176143
cmd.extend(["&&",
177144
self.CMD_CHOWN,
178145
"{0}:{1}".format(
179-
home.owner.encode("utf-8"),
180-
(home.group or u'').encode("utf-8")),
146+
home.owner,
147+
(home.group or '')),
181148
realpath])
182149

183150
cmd.extend(["&&",
184151
self.CMD_CHMOD,
185152
str_mod,
186153
realpath])
187154

188-
cmd = self.server.runCommand(cmd)
155+
cmd = self.server.runCommand(" ".join(cmd))
189156

190157
def _success(reason):
191158
return True
@@ -198,15 +165,47 @@ def _failed(reason):
198165
cmd.finished.chainDeferred(d)
199166
return d
200167

201-
def move(self, home, state):
202-
old = self.get_real_path(state.path)
203-
new = self.get_real_path(home.path)
204-
mlog.info(u"Moving {0} to {1}".format(old, new))
205-
parent = os.path.split(new)[0]
206-
if not os.path.exists(parent):
207-
os.makedirs(parent)
208-
shutil.move(old, new)
209-
state.path = home.path
168+
def sync(self, fromState, to, home, bwlimit=None):
169+
if fromState.status == models.HomeState.ACTIVE:
170+
src_base = self.root
171+
else:
172+
src_base = self.archive_root
173+
174+
sourcepath = self.get_real_path(fromState.path, src_base)
175+
to_path = to.get_real_path(home.path)
176+
177+
cmd = [self.CMD_RSYNC, "-rlptgo"]
178+
if bwlimit:
179+
cmd.append("--bwlimit={0}".format(bwlimit))
180+
181+
dest = ":".join([to.name, to_path])
182+
# Trailing slash on source to prevent copying dir inside itself
183+
cmd.extend([sourcepath + "/", dest])
184+
185+
d = self._make_parent(to_path)
186+
def _then(*r):
187+
return self.server.runCommand(" ".join(cmd)).finished
188+
d.addBoth(_then)
189+
return d
190+
191+
def archive(self, homestate, toPath):
192+
if homestate.status != models.HomeState.ACTIVE:
193+
return defer.fail(Exception("Home must be active to archive"))
194+
195+
src = self.get_real_path(homestate.path, self.root)
196+
dst = self.get_real_path(toPath, self.archive_root)
197+
return self._make_parent(dst).addCallback(lambda *r: self.move(src, dst))
198+
199+
def move(self, source, dest):
200+
args = [self.CMD_MOVE, "-T", "--backup=t", source, dest]
201+
cmd = self.server.runCommand(" ".join(args))
202+
203+
204+
205+
return cmd.finished
206+
207+
208+
210209

211210
def remove(self, home, state):
212211
realpath = self.get_real_path(home.path)
@@ -236,24 +235,3 @@ def remove(self, home, state):
236235

237236
state.path = None
238237

239-
def set_perms(self, home, state):
240-
realpath = self.get_real_path(home.path)
241-
if not os.path.exists(realpath):
242-
self.create(home, state)
243-
244-
if home.owner:
245-
setuid = home.owner
246-
numuid = self.name_to_uid(setuid)
247-
else:
248-
setuid = None
249-
numuid = -1
250-
251-
if home.group:
252-
setgid = home.group
253-
numgid = self.name_to_gid(setgid)
254-
else:
255-
setgid = None
256-
numgid = -1
257-
258-
if setuid or setuid:
259-
os.chown(realpath, numuid, numgid)

tilde/loader.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ def __init__(self,
88
root,
99
user="root",
1010
port=22,
11-
archive_root=None):
11+
archive_root=None,
12+
trash_root=None):
1213
self.hostname = hostname
1314
self.root = root
1415
self.user = user
1516
self.port = port
1617
self.archive_root = archive_root
18+
self.trash_root = trash_root
1719

1820
def __repr__(self):
1921
return repr(self.__dict__)

tilde/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ def update(self, other):
9090
self.ts = other.ts
9191

9292
@classmethod
93-
def fromState(cls, other):
93+
def fromState(cls, other, **kw):
9494
new = cls()
9595
new.update(other)
96+
for k, v in kw.iteritems():
97+
setattr(new, k, v)
9698
return new
9799

98100
@classmethod

0 commit comments

Comments
 (0)