Newer
Older
# Installsystems is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Installsystems is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License
# along with Installsystems. If not, see <http://www.gnu.org/licenses/>.
import cStringIO
from installsystems.exception import *
from installsystems.printer import *
from installsystems.tarball import Tarball
from installsystems.tools import PipeFile
from installsystems.image import Image, PackageImage
from installsystems.database import Database
class RepositoryFactory(object):
'''
Repository factory
'''
def __init__(self):
self.repo_class = {
1: Repository_v1,
2: Repository
}
def create(self, config):
db = None
if not config.offline:
try:
db = Database(config.dbpath)
except ISWarning as e:
warn('[%s]: %s' % (config.name, e))
config.offline = True
except ISError:
debug(u"Unable to load database %s" % config.dbpath)
config.offline = True
if config.offline:
debug(u"Repository %s is offline" % config.name)
if db is None:
return Repository(config)
else:
return self.repo_class[int(db.version)](config, db)
@staticmethod
def is_repository_name(name):
return re.match("^[-_\w]+$", name) is not None
@staticmethod
def check_repository_name(name):
'''
Raise exception is repository name is invalid
'''
if not Repository.is_repository_name(name):
raise ISError(u"Invalid repository name %s" % name)
return name
@staticmethod
def split_image_path(path):
'''
Split an image path (repo/image:version)
in a tuple (repo, image, version)
'''
x = re.match(u"^(?:([^/:]+)/)?([^/:]+)?(?::v?([^/:]+)?)?$", path)
if x is None:
raise ISError(u"invalid image path: %s" % path)
return x.group(1, 2, 3)
@staticmethod
def split_repository_list(repolist, filter=None):
'''
Return a list of repository from a comma/spaces separated names of repo
'''
if filter is None:
filter = Repository.is_repository_name
return [r for r in re.split("[ ,\n\t\v]+", repolist) if filter(r)]
arrow(u"Diff between repositories #y#%s#R# and #g#%s#R#" % (repo1.config.name,
repo2.config.name))
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
# Get info from databases
i_dict1 = dict((b[0], b[1:]) for b in repo1.db.ask(
"SELECT md5, name, version FROM image").fetchall())
i_set1 = set(i_dict1.keys())
i_dict2 = dict((b[0], b[1:]) for b in repo2.db.ask(
"SELECT md5, name, version FROM image").fetchall())
i_set2 = set(i_dict2.keys())
p_dict1 = dict((b[0], b[1:]) for b in repo1.db.ask(
"SELECT md5, name FROM payload").fetchall())
p_set1 = set(p_dict1.keys())
p_dict2 = dict((b[0], b[1:]) for b in repo2.db.ask(
"SELECT md5, name FROM payload").fetchall())
p_set2 = set(p_dict2.keys())
# computing diff
i_only1 = i_set1 - i_set2
i_only2 = i_set2 - i_set1
p_only1 = p_set1 - p_set2
p_only2 = p_set2 - p_set1
# printing functions
pimg = lambda r,c,m,d,: out("#%s#Image only in repository %s: %s v%s (%s)#R#" %
(c, r.config.name, d[m][0], d[m][1], m))
ppay = lambda r,c,m,d,: out("#%s#Payload only in repository %s: %s (%s)#R#" %
(c, r.config.name, d[m][0], m))
# printing image diff
for md5 in i_only1: pimg(repo1, "y", md5, i_dict1)
for md5 in p_only1: ppay(repo1, "y", md5, p_dict1)
for md5 in i_only2: pimg(repo2, "g", md5, i_dict2)
for md5 in p_only2: ppay(repo2, "g", md5, p_dict2)
self.local = istools.isfile(self.config.path)
def __getattribute__(self, name):
'''
Raise an error if repository is unavailable
Unavailable can be caused because db is not accessible or
because repository is not initialized
'''
config = object.__getattribute__(self, "config")
# config, init, local and upgrade_db are always accessible
if name in ("init", "config", "local", "upgrade_db"):
return object.__getattribute__(self, name)
# if no db (not init or not accessible) raise error
raise ISError(u"Repository %s is offline" % config.name)
@property
def version(self):
'''
Return repository version
'''
return self.db.version
@property
def uuid(self):
'''
Return repository UUID
'''
return self.db.ask("SELECT uuid from repository").fetchone()[0]
raise ISError(u"Repository creation must be local")
# creating local directory
try:
if os.path.exists(config.path):
arrow(u"%s already exists" % config.path)
istools.mkdir(config.path, config.uid, config.gid, config.dmod)
arrow(u"%s directory created" % config.path)
raise ISError(u"Unable to create directory %s" % config.path, e)
Loading full blame...