summaryrefslogtreecommitdiffstats
path: root/src/software/lmi/software/yumdb/repository.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/software/lmi/software/yumdb/repository.py')
-rw-r--r--src/software/lmi/software/yumdb/repository.py202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/software/lmi/software/yumdb/repository.py b/src/software/lmi/software/yumdb/repository.py
new file mode 100644
index 0000000..758ae21
--- /dev/null
+++ b/src/software/lmi/software/yumdb/repository.py
@@ -0,0 +1,202 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+#
+# This library 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 2.1 of the License, or (at your option) any later version.
+#
+# This library 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 this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+"""
+Module holding an abstraction for YUM repository.
+"""
+
+from datetime import datetime
+import logging
+import yum
+import yum.Errors
+
+# maps names of Repository properties to their corresponding property
+# names in YumRepository object
+PROPERTY_NAME_MAP = {
+ "repoid" : "id",
+ "base_urls" : "baseurl",
+ "config_file" : "repofile",
+ "cost" : "cost",
+ "enabled" : "enabled",
+ "gpg_check" : "gpgcheck",
+ "last_edit" : "repo_config_age",
+ "mirror_list" : "mirrorlist",
+ "mirror_urls" : "mirrorurls",
+ "name" : "name",
+ "pkg_dir" : "pkgdir",
+ "ready" : "ready",
+ "repo_gpg_check" : "repo_gpgcheck",
+ "timeout" : "timeout"
+}
+
+def get_prop_from_yum_repo(repo, prop_name):
+ """
+ @param prop_name is one Repository properties
+ @return value of property from object of YumRepository
+ """
+ if not isinstance(repo, yum.yumRepo.YumRepository):
+ raise TypeError("repo must be in instance of yum.yumRepo.YumRepository")
+ if prop_name in PROPERTY_NAME_MAP:
+ val = getattr(repo, PROPERTY_NAME_MAP[prop_name])
+ if prop_name == "last_edit":
+ val = datetime.fromtimestamp(val)
+ elif prop_name == "mirror_urls" and not repo.mirrorlist:
+ val = None
+ elif prop_name == "ready":
+ val = val()
+ elif prop_name in {"arch", "basearch", "releasever"}:
+ val = repo.yumvar[prop_name]
+ elif prop_name in {"revision", "last_update"}:
+ if repo.enabled and repo.repoXML:
+ md = repo.repoXML
+ if prop_name == "last_update":
+ val = datetime.fromtimestamp(md.timestamp)
+ elif prop_name == "revision":
+ val = long(md.revision)
+ else:
+ val = getattr(repo.repoXML, prop_name)
+ else:
+ val = None
+ elif prop_name == "pkg_count":
+ # this needs populated sack: ydb.repos.populateSack(repo.id)
+ val = len(repo.sack)
+ else:
+ raise ValueError('Unknown repository property: "%s"' % prop_name)
+ return val
+
+class Repository(object):
+ """
+ Container for repository metadata. It represents yum repository.
+ It's supposed to be passed from YumWorker to YumDB client and
+ vice-versa.
+ """
+ __slots__ = (
+ "objid", # [int] id of python object on server process
+ "repoid", # [string] repository id name
+ # (name of config file)
+
+ "arch", # [string] architecture of packages
+ "basearch", # [string] base system architecture
+ "base_urls", # [list] base urls as strings
+ #"cache",
+ #"cache_dir",
+ "name", # [string] repository descriptive name
+ "config_file", # [string] file path to corresponding
+ # config file
+ "cost", # [int] cost of repository
+ "enabled", # [boolean] whether repo is enabled
+ "gpg_check", # [boolean] whether to check gpg signature
+ #"metadata_expire", # how long are metadata considered valid
+ "last_edit", # datetime of last config modification
+ "last_update", # datetime of last change of repository
+ # on server
+ "mirror_list", # url of mirrorlist, or None
+ "mirror_urls", # list of urls obtained from mirrorlist or None
+ #"persist_dir", #
+ #"pkg_count", # number of packages in directory
+ "pkg_dir", # directory with packages
+ #"proxy", # boolean saying whether this is a proxy
+ "ready", # boolean saying, whether it's ready for use
+ "releasever", # version of targeted distribution
+ "repo_gpg_check", # [boolean] whether to check gpg
+ # signarues of data
+ "revision",
+ "timeout", # timeout for requests
+ )
+
+ def __init__(self, objid, repoid, arch, basearch, base_urls,
+ config_file, cost, enabled, gpg_check, last_edit, last_update,
+ name, pkg_dir, ready, releasever, repo_gpg_check, revision,
+ timeout, mirror_list=None, mirror_urls=None):
+ for arg in ('last_edit', 'last_update'):
+ if ( locals()[arg] is not None
+ and not isinstance(locals()[arg], datetime)):
+ raise TypeError("%s must be an instance of datetime" % arg)
+ if not isinstance(timeout, float):
+ raise TypeError("timeout must be a float")
+ for arg in ('cost', 'revision'):
+ if ( locals()[arg] is not None
+ and not isinstance(locals()[arg], (int, long))):
+ raise TypeError("%s must be an integer" % arg)
+ self.objid = objid
+ self.repoid = repoid
+ self.arch = arch
+ self.basearch = basearch
+ self.base_urls = list(base_urls)
+ self.config_file = config_file
+ self.cost = cost
+ self.enabled = bool(enabled)
+ self.gpg_check = bool(gpg_check)
+ self.last_edit = last_edit
+ self.last_update = last_update
+ self.mirror_list = "" if not mirror_list else mirror_list
+ self.mirror_urls = [] if not mirror_urls else list(mirror_urls)
+ self.name = name
+ #self.pkg_count = pkg_count
+ self.pkg_dir = pkg_dir
+ self.ready = bool(ready)
+ self.releasever = releasever
+ self.repo_gpg_check = bool(repo_gpg_check)
+ self.revision = revision
+ self.timeout = timeout
+
+ def __str__(self):
+ return self.repoid
+
+ def __getstate__(self):
+ """
+ Used for serialization with pickle.
+ @return container content that will be serialized
+ """
+ return dict((k, getattr(self, k)) for k in self.__slots__)
+
+ def __setstate__(self, state):
+ """
+ Used for deserialization with pickle.
+ Restores the object from serialized form.
+ @param state is an object created by __setstate__() method
+ """
+ for k, value in state.items():
+ setattr(self, k, value)
+
+def make_repository_from_db(repo):
+ """
+ Create instance of Repository from instance of yum.yumRepo.YumRepository
+ @return instance of Repository
+ """
+ if not isinstance(repo, yum.yumRepo.YumRepository):
+ raise TypeError("repo must be in instance of yum.yumRepo.YumRepository")
+ metadata = {}
+ for prop_name in Repository.__slots__[1:]:
+ try:
+ metadata[prop_name] = get_prop_from_yum_repo(repo, prop_name)
+ except yum.Errors.RepoError as exc:
+ # some properties can cause error (like requesting ready)
+ logging.getLogger(__name__).warn(
+ 'failed to get property "%s" of repo "%s": %s' % (
+ prop_name, repo.name, exc))
+ if prop_name == "ready":
+ metadata[prop_name] = False
+ continue
+
+ res = Repository(id(repo), **metadata)
+ return res
+