[mirrormanager] master: umdl: fix calling nuke_gone_directories() (184b25d)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit 184b25daa7bd6387ea3a4c162a41f4ba3ce297f0
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 14:19:03 2013 -0600
umdl: fix calling nuke_gone_directories()
>---------------------------------------------------------------
server/update-master-directory-list | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/server/update-master-directory-list b/server/update-master-directory-list
index 7c66ee5..f92ee6d 100755
--- a/server/update-master-directory-list
+++ b/server/update-master-directory-list
@@ -267,7 +267,7 @@ def is_excluded(path, excludes):
return False
-def nuke_gone_directories(diskpath, category, excludes):
+def nuke_gone_directories(diskpath, category):
""" deleting a Directory has a ripple effect through the whole
database. Be really sure you're ready do to this. It comes
in handy when say a Test release is dropped."""
@@ -275,7 +275,7 @@ def nuke_gone_directories(diskpath, category, excludes):
topdirName = category.topdir.name
for d in category.directories(orderBy='-name'):
- if is_excluded(d.name, excludes): continue
+ if is_excluded(d.name, category.excludes): continue
relativeDName = remove_category_topdir(topdirName, d.name)
if not os.path.isdir(os.path.join(diskpath, relativeDName)):
if len(d.categories) == 1: # safety, this should always trigger
10 years, 4 months
[mirrormanager] master: model: fix mirroradmins() SQL (aa2edb9)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit aa2edb9cc4e0d29484c43e1396611688e8583fe7
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 12:24:22 2013 -0600
model: fix mirroradmins() SQL
otherwise a traceback occurs because the wrong column names were
being used.
>---------------------------------------------------------------
server/mirrormanager/model.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/server/mirrormanager/model.py b/server/mirrormanager/model.py
index ee36da1..961cf10 100644
--- a/server/mirrormanager/model.py
+++ b/server/mirrormanager/model.py
@@ -887,7 +887,7 @@ def mirror_admins(public_only=True):
sql += 'WHERE host.site_id = site.id '
sql += 'AND site_admin.site_id = site.id '
if public_only:
- sql += 'AND site.public AND host.public '
+ sql += 'AND NOT site.private AND NOT host.private '
sql += 'ORDER BY site_admin.username '
qresult = Directory._connection.queryAll(sql)
result = [x[0] for x in qresult]
10 years, 4 months
[mirrormanager] master: model: use datetime.datetime.utcnow callable for defaults (2df5a89)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit 2df5a89c52ad9f38c3c4e2a7e11f642eebf2f319
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 09:48:05 2013 -0600
model: use datetime.datetime.utcnow callable for defaults
When done as a function (), this is evaluated at program start time,
not during runtime. Instead we want it evaluated at runtime, so pass
in the function name. Also make sure all are utcnow and not just
.now.
>---------------------------------------------------------------
server/mirrormanager/model.py | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/server/mirrormanager/model.py b/server/mirrormanager/model.py
index 2fd9ed6..ee36da1 100644
--- a/server/mirrormanager/model.py
+++ b/server/mirrormanager/model.py
@@ -43,7 +43,7 @@ class Site(SQLObject):
private = BoolCol(default=False)
admin_active = BoolCol(default=True)
user_active = BoolCol(default=True)
- createdAt = DateTimeCol(default=datetime.datetime.utcnow())
+ createdAt = DateTimeCol(default=datetime.datetime.utcnow)
createdBy = UnicodeCol(default=None)
# allow all sites to pull from me
allSitesCanPullFromMe = BoolCol(default=False)
@@ -323,7 +323,7 @@ class Host(SQLObject):
def _set_config(self, config):
# really, we don't store the config anymore
self._config = None
- self.lastCheckedIn = datetime.datetime.utcnow()
+ self.lastCheckedIn = datetime.datetime.utcnow
def checkin(self, config):
message = self._uploaded_config(config)
@@ -605,7 +605,7 @@ class HostStats(SQLObject):
class sqlmeta:
cacheValues = False
host = ForeignKey('Host')
- _timestamp = DateTimeCol(default=datetime.datetime.utcnow())
+ _timestamp = DateTimeCol(default=datetime.datetime.utcnow)
type = UnicodeCol(default=None)
data = PickleCol(default=None)
@@ -988,7 +988,7 @@ class Visit(SQLObject):
visit_key = StringCol(length=40, alternateID=True,
alternateMethodName="by_visit_key")
- created = DateTimeCol(default=datetime.datetime.now)
+ created = DateTimeCol(default=datetime.datetime.utcnow)
expiry = DateTimeCol()
def lookup_visit(cls, visit_key):
@@ -1017,7 +1017,7 @@ class Group(SQLObject):
group_name = UnicodeCol(length=16, alternateID=True,
alternateMethodName="by_group_name")
display_name = UnicodeCol(length=255)
- created = DateTimeCol(default=datetime.datetime.now)
+ created = DateTimeCol(default=datetime.datetime.utcnow)
# collection of all users belonging to this group
users = RelatedJoin("User", intermediateTable="user_group",
@@ -1044,7 +1044,7 @@ class User(SQLObject):
alternateMethodName="by_email_address")
display_name = UnicodeCol(length=255)
password = UnicodeCol(length=40)
- created = DateTimeCol(default=datetime.datetime.now)
+ created = DateTimeCol(default=datetime.datetime.utcnow)
# groups this user belongs to
groups = RelatedJoin("Group", intermediateTable="user_group",
10 years, 4 months
[mirrormanager] master: version 1.4.3 (adfdb94)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit adfdb944ea74905fac2358b8ddb9db880aadb1e7
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 08:34:11 2013 -0600
version 1.4.3
>---------------------------------------------------------------
Makefile | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index ab7e5c4..2fd533b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-RELEASE_DATE := "23-Jul-2013"
+RELEASE_DATE := "18-Dec-2013"
RELEASE_MAJOR := 1
RELEASE_MINOR := 4
-RELEASE_EXTRALEVEL := .2
+RELEASE_EXTRALEVEL := .3
RELEASE_NAME := mirrormanager
RELEASE_VERSION := $(RELEASE_MAJOR).$(RELEASE_MINOR)$(RELEASE_EXTRALEVEL)
RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_VERSION)
10 years, 4 months
[mirrormanager] master: spec: remove selinux policy stuff, upstream selinux is adding it (54802d0)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit 54802d0a813d00a4c6307e5cddf6815733ce8dfc
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 08:32:46 2013 -0600
spec: remove selinux policy stuff, upstream selinux is adding it
Either run in permissive mode, or wait for the new upstream selinux
policy which will add MM-specific labeling as necessary.
>---------------------------------------------------------------
mirrormanager.spec.in | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/mirrormanager.spec.in b/mirrormanager.spec.in
index eb615b7..6c70c11 100644
--- a/mirrormanager.spec.in
+++ b/mirrormanager.spec.in
@@ -14,7 +14,6 @@ BuildRequires: python >= 2.6
Requires: TurboGears, python-IPy, python-GeoIP, wget, yum, psmisc, python-dns, python-fedora >= 0.3.14, python-fedora-turbogears, py-radix, mod_wsgi, python-TurboMail
Requires: supervisor
Requires(pre): shadow-utils
-Requires(pre): policycoreutils-python
%description
MirrorManager tracks all the content provided on a master mirror
@@ -61,8 +60,6 @@ getent group mirrormanager >/dev/null || groupadd -r mirrormanager
getent passwd mirrormanager >/dev/null || \
useradd -r -g mirrormanager -d /var/lib/mirrormanager -s /sbin/nologin \
-c "MirrorManager" mirrormanager
-semanage fcontext -a -t httpd_sys_content_t '/var/lib/mirrormanager/mirrorlists(/.*)?'
-semanage fcontext -a -t httpd_sys_content_t '/var/log/mirrormanager/crawler(/.*)?'
exit 0
%files
10 years, 4 months
[mirrormanager] master: spec: bump version, eliminate stupid warnings (2f8e062)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit 2f8e06238cdf80d9a3f316225ea7a794238e80d9
Author: Matt Domsch <matt(a)domsch.com>
Date: Wed Dec 18 08:24:50 2013 -0600
spec: bump version, eliminate stupid warnings
>---------------------------------------------------------------
mirrormanager.spec.in | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/mirrormanager.spec.in b/mirrormanager.spec.in
index 2e7f3c6..eb615b7 100644
--- a/mirrormanager.spec.in
+++ b/mirrormanager.spec.in
@@ -12,7 +12,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
# for tempfile.SpooledTemporaryFile at least. RHEL6 has python 2.6 anyhow.
BuildRequires: python >= 2.6
Requires: TurboGears, python-IPy, python-GeoIP, wget, yum, psmisc, python-dns, python-fedora >= 0.3.14, python-fedora-turbogears, py-radix, mod_wsgi, python-TurboMail
-Requires: supervisor
+Requires: supervisor
Requires(pre): shadow-utils
Requires(pre): policycoreutils-python
@@ -100,6 +100,10 @@ exit 0
%doc LICENSES LICENSE-GPLv2
%changelog
+* Wed Dec 18 2013 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.4.3-1
+- upstream bugfix release
+- Reduce Fedora-isms to make it more usable for other distributions
+
* Tue Jul 23 2013 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.4.2-1
- upstream bugfix release
@@ -188,12 +192,12 @@ Matt Domsch (8):
* Mon Oct 26 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.3-2
- add patch to fix confirm delete from webui
-* Thu Sep 28 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.3-1
+* Mon Sep 28 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.3-1
- initial setup patches from BJ Dierkes
- simpler mirrormanager.initial, README.rpm_setup, prod.cfg
- add user mirrormanager and group mirrormanager, content permissions
-* Thu Sep 28 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.2-1
+* Mon Sep 28 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.2-1
- add BGP ASN lookups
* Fri Sep 18 2009 Matt Domsch <mdomsch(a)fedoraproject.org> - 1.3.1-1
10 years, 4 months
[mirrormanager] master: crawler: add a --debug option, set default loglevel to INFO (6484452)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit 64844522999dbc171707deba39ad132d16dfee41
Author: Matt Domsch <matt(a)domsch.com>
Date: Tue Dec 17 22:16:02 2013 -0600
crawler: add a --debug option, set default loglevel to INFO
>---------------------------------------------------------------
server/crawler | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/server/crawler b/server/crawler
index 81e472b..e676ca7 100755
--- a/server/crawler
+++ b/server/crawler
@@ -152,7 +152,7 @@ def doit():
master.wait_for_completion()
-def setup_logger():
+def setup_logger(debug):
fmt = "%(asctime)s %(message)s"
formatter = logging.Formatter(fmt=fmt)
formatter.converter = time.gmtime
@@ -160,7 +160,10 @@ def setup_logger():
handler = logging.handlers.WatchedFileHandler(options.logfile, "a+b")
handler.setFormatter(formatter)
logger.addHandler(handler)
- logger.setLevel(logging.DEBUG)
+ if debug:
+ logger.setLevel(logging.DEBUG)
+ else:
+ logger.setLevel(logging.INFO)
return logger
def main():
@@ -204,6 +207,10 @@ def main():
dest="canary", action="store_true", default=False,
help="fast crawl by only scanning for canary files")
+ parser.add_option("--debug", "-d",
+ dest="debug", action="store_true", default=False,
+ help="enable printing of debug-level messages")
+
(options, args) = parser.parse_args()
turbogears.update_config(configfile=options.config,
@@ -214,7 +221,7 @@ def main():
__connection__ = hub
global logger
- logger = setup_logger()
+ logger = setup_logger(options.debug)
doit()
remove_pidfile(pidfile)
10 years, 4 months
[mirrormanager] master: publiclist: add country link & anchor tags (d52dfde)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit d52dfdefbbfdf1974b790618fa2f23760b907259
Author: Matt Domsch <matt(a)domsch.com>
Date: Tue Dec 17 22:07:41 2013 -0600
publiclist: add country link & anchor tags
This lets you see all the country codes above the list, and click one to
jump straight to that country's list of mirrors.
>---------------------------------------------------------------
.../mirrormanager/templates/centos/publiclist.kid | 23 ++++++++++++++++++-
.../mirrormanager/templates/fedora/publiclist.kid | 23 ++++++++++++++++++-
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/server/mirrormanager/templates/centos/publiclist.kid b/server/mirrormanager/templates/centos/publiclist.kid
index d2d1f53..f783c99 100644
--- a/server/mirrormanager/templates/centos/publiclist.kid
+++ b/server/mirrormanager/templates/centos/publiclist.kid
@@ -64,18 +64,37 @@ and development networks globally.
<p py:if="len(hosts) == 0">There are no mirrors matching your your search criteria.</p>
+<?python
+country_codes = set()
+for h in hosts:
+ country_codes.add(h.country)
+country_codes = sorted(list(country_codes))
+previous_country=None
+?>
+
+<P>
+Countries:
+<span py:for="cc in country_codes">
+ <a href="#${cc}"><span py:replace="cc">CC</span></a>
+</span>
+</P>
+
<table border="1" class="altrows">
<tr><th>Country</th><th>Site</th><th>Host</th><th>Content</th><th>Bandwidth (Mbits/sec)</th><th>I2</th><th>Comments</th></tr>
<tr py:for="i,host in enumerate(hosts)"
py:attrs="{'class': i%2 and 'odd' or 'even'}">
-<td><span py:if="host.country is not None" py:replace="host.country.upper()">Country</span></td>
+<td><a py:if="host.country != previous_country" name="${host.country}"/>
+<?python
+previous_country = host.country
+?>
+<span py:if="host.country is not None" py:replace="host.country.upper()">Country</span></td>
<td><a href="${host.site_url}"><span py:replace="host.site_name">Site Name</span></a></td>
<td><span py:replace="host.name">Host Name</span></td>
<td>
<table>
<?python
- categories = sorted(host.categories.keys())
+categories = sorted(host.categories.keys())
?>
<tr py:for="hc in categories">
<td><span py:replace="host.categories[hc].name">Category name</span></td>
diff --git a/server/mirrormanager/templates/fedora/publiclist.kid b/server/mirrormanager/templates/fedora/publiclist.kid
index 8b1279d..ac98b4d 100644
--- a/server/mirrormanager/templates/fedora/publiclist.kid
+++ b/server/mirrormanager/templates/fedora/publiclist.kid
@@ -64,18 +64,37 @@ and development networks globally.
<p py:if="len(hosts) == 0">There are no mirrors matching your your search criteria.</p>
+<?python
+country_codes = set()
+for h in hosts:
+ country_codes.add(h.country)
+country_codes = sorted(list(country_codes))
+previous_country=None
+?>
+
+<P>
+Countries:
+<span py:for="cc in country_codes">
+ <a href="#${cc}"><span py:replace="cc">CC</span></a>
+</span>
+</P>
+
<table border="1" class="altrows">
<tr><th>Country</th><th>Site</th><th>Host</th><th>Content</th><th>Bandwidth (Mbits/sec)</th><th>I2</th><th>Comments</th></tr>
<tr py:for="i,host in enumerate(hosts)"
py:attrs="{'class': i%2 and 'odd' or 'even'}">
-<td><span py:if="host.country is not None" py:replace="host.country.upper()">Country</span></td>
+<td><a py:if="host.country != previous_country" name="${host.country}"/>
+<?python
+previous_country = host.country
+?>
+<span py:if="host.country is not None" py:replace="host.country.upper()">Country</span></td>
<td><a href="${host.site_url}"><span py:replace="host.site_name">Site Name</span></a></td>
<td><span py:replace="host.name">Host Name</span></td>
<td>
<table>
<?python
- categories = sorted(host.categories.keys())
+categories = sorted(host.categories.keys())
?>
<tr py:for="hc in categories">
<td><span py:replace="host.categories[hc].name">Category name</span></td>
10 years, 4 months
[mirrormanager] master: import_centos: more fixes (f9f258b)
by Matt Domsch
Repository : http://git.fedorahosted.org/cgit/
On branch : master
>---------------------------------------------------------------
commit f9f258bfccaaad7fd7bd775522a169c13cad50ef
Author: Matt Domsch <matt(a)domsch.com>
Date: Mon Dec 16 23:52:10 2013 -0600
import_centos: more fixes
>---------------------------------------------------------------
server/import_centos | 77 +++++++++++++++++++++++++++++--------------------
1 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/server/import_centos b/server/import_centos
index 0ab6ea0..1f343db 100755
--- a/server/import_centos
+++ b/server/import_centos
@@ -23,7 +23,8 @@ from mirrormanager.model import *
from mirrormanager.mirrorlist import name_to_ips
from optparse import OptionParser
import csv
-import random, string
+import random
+import string
import urllib
import radix
from IPy import IP
@@ -35,6 +36,7 @@ from turbogears.database import PackageHub
from turbogears import config
hub = __connection__ = None
+centos_category = None
centos_upstream = u'rsync://msync.centos.org/CentOS'
internet2_netblocks_file = '/var/lib/mirrormanager/i2_netblocks.txt'
global_netblocks_file = '/var/lib/mirrormanager/global_netblocks.txt'
@@ -235,19 +237,26 @@ def one_hostname_from_urls(http, ftp, rsync):
else:
return None
-# "Sponsor"," Location Major"," Location Minor"," http-URL"," ftp-URL"," rsync-URL"," Bandwidth (if available)"," state (current mostly)"," Sponsor URL"," cc"," continent"
+# "Sponsor","Location Major","Location Minor","http-URL","ftp-URL","rsync-URL","Bandwidth (if available)","state (current mostly)","Sponsor URL","cc","continent"
def process(row):
+ for key in row.keys():
+ row[key] = row[key].decode('utf-8').strip()
+ if row[key] == u'' and not 'URL' in key: # we'll get those later
+ row[key] = None
+
# Create Site
# avoid duplicate sites
- http_url = row['http-URL'].strip().rstrip('/')
- ftp_url = row['ftp-URL'].strip().rstrip('/')
- rsync_url = row['rsync-URL'].strip().rstrip('/')
+ http_url = row[u'http-URL'].rstrip(u'/')
+ ftp_url = row[u'ftp-URL'].rstrip(u'/')
+ rsync_url = row[u'rsync-URL'].rstrip(u'/')
+ orgUrl = row[u'Sponsor URL']
+ siteName = row[u'Sponsor']
try:
- site = Site(name=row['Sponsor'],
+ site = Site(name=row[u'Sponsor'],
password=generate_password(),
- orgUrl=row.get('Sponsor URL'))
- print "Site %s created" % (site.name)
+ orgUrl=orgUrl)
+ print u"%s created" % (siteName)
except:
return # no duplicates
@@ -264,13 +273,20 @@ def process(row):
print "no hostname for row %s" % row
return
try:
- country = row['cc'].upper() or country_from_urls(http_url, ftp_url, rsync_url)
+ country = row[u'cc']
+ if country is None:
+ country = country_from_urls(http_url, ftp_url, rsync_url)
+ else:
+ country = country.upper()
internet2 = urls_in_internet2(http_url, ftp_url, rsync_url)
asn = asn_from_urls(http_url, ftp_url, rsync_url)
- bandwidth_int = row['Bandwidth (if available)']
- bandwidth_int = bandwidth_int.strip()
- if len(bandwidth_int):
- bandwidth_int = int(bandwidth_int)
+ bandwidth_int = row[u'Bandwidth (if available)']
+ if bandwidth_int is not None and len(bandwidth_int):
+ try:
+ bandwidth_int = int(bandwidth_int)
+ except:
+ bandwidth_int = 100
+
else:
bandwidth_int = 100
host = Host(name = hostname,
@@ -280,49 +296,46 @@ def process(row):
asn = asn,
bandwidth_int = bandwidth_int
)
- print "Host %s created" % host
except:
# duplicate hosts means we've gone this far already somehow before.
# don't bother doing any more
raise
# Create HostCategory
- category = Category.byName("CentOS")
- host_category = HostCategory(host=host,
- category=category)
+ host_category = HostCategory(host=host, category=centos_category)
# Create HostCategoryURLs
if http_url:
- if http_url.startswith('http'):
+ if http_url.startswith(u'http'):
try:
http_url = HostCategoryUrl(host_category=host_category,
url = http_url)
except:
- print "ERROR: HTTP URL for %s is a duplicate" % row
+ print u"ERROR: HTTP URL for %s is a duplicate" % row
else:
- print "ERROR: HTTP URL for %s is invalid" % row
+ print u"ERROR: HTTP URL for %s is invalid" % row
if ftp_url:
- if ftp_url.startswith('ftp'):
+ if ftp_url.startswith(u'ftp'):
try:
- ftp_url = HostCategoryUrl(host_category=host_category,
+ ftp_iurl = HostCategoryUrl(host_category=host_category,
url = ftp_url)
except:
- print "ERROR: HTTP URL for %s is a duplicate" % row
+ print u"ERROR: HTTP URL for %s is a duplicate" % row
else:
- print "ERROR: FTP URL for %s is invalid" % row
+ print u"ERROR: FTP URL for %s is invalid" % row
if rsync_url:
- if rsync_url.startswith('rsync'):
+ if rsync_url.startswith(u'rsync'):
try:
rsync_url = HostCategoryUrl(host_category=host_category,
url = rsync_url)
except:
- print "ERROR: RSYNC URL for %s is a duplicate" % row
+ print u"ERROR: RSYNC URL for %s is a duplicate" % row
else:
- print "ERROR: RSYNC URL for %s is invalid" % row
+ print u"ERROR: RSYNC URL for %s is invalid" % row
def email_user(user):
subject = "Welcome to the CentOS MirrorManager"
@@ -382,14 +395,11 @@ def doit(options, args):
if options.filename == '-':
f = sys.stdin
else:
- f = open(options.filename, 'r')
+ f = open(options.filename, 'rb')
csv_reader = csv.DictReader(f, dialect='excel')
for row in csv_reader:
- print row
-# user, new_user = process(row)
process(row)
-# if new_user:
-# email_user(user)
+
def main():
parser = OptionParser(usage=sys.argv[0] + " [options]")
@@ -415,6 +425,9 @@ def main():
global admin
admin = User.selectBy(user_name=u'admin')[0]
+ global centos_category
+ centos_category = Category.byName(u"CentOS")
+
doit(options, args)
if __name__ == "__main__":
10 years, 4 months