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
|
#!/usr/bin/python
# versioned_repos.py:
# Directory of "versioned" repositories, sharing hard-linked files
#
# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
# Copyright (C) 2010 Red Hat, Inc.
# Written by Colin Walters <walters@verbum.org>
import os
import sys
import logging
import glib
import gio
import rpm
import rpmUtils
import rpmUtils.miscutils
from . import subtask
class Repo(object):
def __init__(self, basedir, name, version):
self.name = name
self.version = version
self._dirname = '%d' % (version, )
self._dir = os.path.join(basedir, self._dirname)
self._task_basename = 'repo-%s' % (name, )
if not os.path.isdir(self._dir):
os.makedirs(self._dir)
def get_dir(self):
return self._dir
def add_rpm(self, rpm_path):
basename = os.path.basename(rpm_path)
dest = os.path.join(self._dir, basename)
logging.debug("Linking %r to %r" % (rpm_path, dest))
os.link(rpm_path, dest)
def iter_rpms(self):
for filename in os.listdir(self._dir):
if filename.endswith('.rpm'):
yield os.path.join(self._dir, filename)
def _delete_old_rpms_in_dir(self, dirpath):
output = subtask.spawn_sync_get_output('repomanage-' + self._task_basename,
['repomanage', '-o', '.'], cwd=dirpath)
for line in output.split('\n'):
path = os.path.join(self._dir, line)
if line.endswith('.rpm') and os.path.exists(path):
os.unlink(path)
def update_sync(self):
self._delete_old_rpms_in_dir(self._dir)
subtask.spawn_sync('createrepo' + self._task_basename,
['createrepo', '.'], cwd=self._dir)
class VersionedRepo(object):
def __init__(self, dirpath):
self._dir = dirpath
if not os.path.isdir(self._dir):
os.makedirs(self._dir)
self._name = os.path.basename(dirpath)
self._versions = {}
self._last_version = -1
self._reload()
def get_versions(self):
return self._versions
def _reload(self):
self._versions = {}
for filename in os.listdir(self._dir):
path = os.path.join(self._dir, filename)
if not os.path.isdir(path):
continue
try:
revision = int(filename)
except ValueError, e:
continue
self._versions[revision] = Repo(self._dir, self._name, revision)
if revision > self._last_version:
self._last_version = revision
def get_latest_version(self):
if self._last_version == -1:
return None
return self._versions[self._last_version]
def get_latest_path(self):
latest = self.get_latest_version()
if latest is None:
return None
return latest.get_dir()
def commit_sync(self, new_rpms):
rev = self._last_version + 1
new_repo = Repo(self._dir, self._name, rev)
if rev > 0:
prev_repo = self._versions[self._last_version]
for rpm in prev_repo.iter_rpms():
new_repo.add_rpm(rpm)
for rpm in new_rpms:
new_repo.add_rpm(rpm)
new_repo.update_sync()
self._versions[rev] = new_repo
self._last_version = rev
return rev
|