2015-02-17 17:51:27 +01:00
|
|
|
# Copyright (C) 2015 SUSE Linux Products GmbH
|
2013-09-04 15:11:27 +02:00
|
|
|
#
|
2015-02-17 17:51:27 +01:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program 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 General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along
|
|
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2013-09-04 15:11:27 +02:00
|
|
|
|
2014-02-25 14:12:28 +01:00
|
|
|
import os
|
2014-02-12 13:15:49 +01:00
|
|
|
import os.path
|
|
|
|
import sys
|
2015-02-19 10:57:55 +01:00
|
|
|
import warnings
|
2014-02-12 18:34:17 +01:00
|
|
|
|
2015-02-10 17:22:00 +01:00
|
|
|
from osc import cmdln
|
|
|
|
from osc import oscerr
|
2014-02-12 13:15:49 +01:00
|
|
|
|
|
|
|
# Expand sys.path to search modules inside the pluging directory
|
|
|
|
_plugin_dir = os.path.expanduser('~/.osc-plugins')
|
|
|
|
sys.path.append(_plugin_dir)
|
2014-03-04 09:39:14 +01:00
|
|
|
from osclib.accept_command import AcceptCommand
|
2015-08-28 13:30:25 +02:00
|
|
|
from osclib.adi_command import AdiCommand
|
2014-08-07 12:39:41 +02:00
|
|
|
from osclib.check_command import CheckCommand
|
2014-03-04 09:39:14 +01:00
|
|
|
from osclib.cleanup_rings import CleanupRings
|
2015-02-17 17:51:27 +01:00
|
|
|
from osclib.conf import Config
|
2014-03-06 18:50:59 +01:00
|
|
|
from osclib.freeze_command import FreezeCommand
|
2014-08-07 12:39:41 +02:00
|
|
|
from osclib.list_command import ListCommand
|
2015-02-10 17:22:00 +01:00
|
|
|
from osclib.obslock import OBSLock
|
2014-08-07 12:39:41 +02:00
|
|
|
from osclib.select_command import SelectCommand
|
|
|
|
from osclib.stagingapi import StagingAPI
|
|
|
|
from osclib.unselect_command import UnselectCommand
|
2014-03-04 09:39:14 +01:00
|
|
|
|
2014-03-03 17:20:40 +01:00
|
|
|
OSC_STAGING_VERSION = '0.0.1'
|
|
|
|
|
2014-03-11 09:38:27 +01:00
|
|
|
|
2013-09-04 15:11:27 +02:00
|
|
|
def _print_version(self):
|
|
|
|
""" Print version information about this extension. """
|
2014-03-03 17:20:40 +01:00
|
|
|
print(self.OSC_STAGING_VERSION)
|
2013-09-04 15:11:27 +02:00
|
|
|
quit(0)
|
|
|
|
|
2014-03-11 09:38:27 +01:00
|
|
|
|
2015-02-17 17:51:27 +01:00
|
|
|
def _full_project_name(self, project):
|
|
|
|
"""Deduce the full project name."""
|
2015-02-19 10:57:55 +01:00
|
|
|
if project.startswith(('openSUSE', 'SUSE')):
|
2015-02-17 17:51:27 +01:00
|
|
|
return project
|
|
|
|
|
|
|
|
if 'Factory' in project or 'openSUSE' in project:
|
|
|
|
return 'openSUSE:%s' % project
|
|
|
|
|
|
|
|
if 'SLE' in project:
|
|
|
|
return 'SUSE:%s' % project
|
|
|
|
|
|
|
|
# If we can't guess, raise a Warning
|
2015-02-26 15:19:29 +01:00
|
|
|
warnings.warn('%s project not recognized.' % project)
|
2015-02-17 17:51:27 +01:00
|
|
|
return project
|
|
|
|
|
|
|
|
|
2014-03-04 09:39:14 +01:00
|
|
|
@cmdln.option('--move', action='store_true',
|
2014-03-03 17:20:40 +01:00
|
|
|
help='force the selection to become a move')
|
2015-08-27 18:42:39 +08:00
|
|
|
@cmdln.option('--by-develproject', action='store_true',
|
|
|
|
help='sort the packages by devel project')
|
2015-10-01 19:09:15 +08:00
|
|
|
@cmdln.option('--supersede', action='store_true',
|
|
|
|
help='superseding requests. please make sure you have staging permissions')
|
2014-02-25 14:12:28 +01:00
|
|
|
@cmdln.option('-f', '--from', dest='from_', metavar='FROMPROJECT',
|
|
|
|
help='manually specify different source project during request moving')
|
2014-08-07 12:39:41 +02:00
|
|
|
@cmdln.option('-p', '--project', dest='project', metavar='PROJECT', default='Factory',
|
|
|
|
help='select a different project instead of openSUSE:Factory')
|
2014-07-17 13:55:45 +02:00
|
|
|
@cmdln.option('--add', dest='add', metavar='PACKAGE',
|
|
|
|
help='mark additional packages to be checked by repo checker')
|
2015-12-22 14:53:42 +01:00
|
|
|
@cmdln.option('--force', action='store_true',
|
|
|
|
help='Force action, overruling internal checks (CAUTION)')
|
2014-07-08 15:02:12 +02:00
|
|
|
@cmdln.option('-o', '--old', action='store_true',
|
|
|
|
help='use the old check algorithm')
|
2013-09-04 15:11:27 +02:00
|
|
|
@cmdln.option('-v', '--version', action='store_true',
|
|
|
|
help='show version of the plugin')
|
2015-03-24 14:46:36 +01:00
|
|
|
@cmdln.option('--no-freeze', dest='no_freeze', action='store_true',
|
|
|
|
help='force the select command ignoring the time from the last freeze')
|
2013-09-04 15:11:27 +02:00
|
|
|
def do_staging(self, subcmd, opts, *args):
|
|
|
|
"""${cmd_name}: Commands to work with staging projects
|
|
|
|
|
2016-02-01 16:35:36 +01:00
|
|
|
${cmd_option_list}
|
|
|
|
|
2014-03-06 18:50:59 +01:00
|
|
|
"accept" will accept all requests in
|
|
|
|
openSUSE:Factory:Staging:<LETTER> (into Factory)
|
|
|
|
|
2015-12-22 22:39:49 +01:00
|
|
|
"acheck" will check if it's safe to accept new staging projects
|
|
|
|
As openSUSE:Factory is syncing the right package versions between
|
|
|
|
/standard, /totest and /snapshot, it's important that the projects
|
|
|
|
are clean prior to a checkin round.
|
|
|
|
|
2013-09-04 15:11:27 +02:00
|
|
|
"check" will check if all packages are links without changes
|
|
|
|
|
2014-03-06 18:50:59 +01:00
|
|
|
"cleanup_rings" will try to cleanup rings content and print
|
|
|
|
out problems
|
|
|
|
|
2014-03-03 17:20:40 +01:00
|
|
|
"freeze" will freeze the sources of the project's links (not
|
|
|
|
affecting the packages actually in)
|
2014-02-10 10:19:37 +01:00
|
|
|
|
2016-02-03 13:04:30 +01:00
|
|
|
"frozenage" will show when the respective staging project was last frozen
|
|
|
|
|
2014-01-31 10:29:44 +01:00
|
|
|
"list" will pick the requests not in rings
|
|
|
|
|
2014-02-12 13:36:41 +01:00
|
|
|
"select" will add requests to the project
|
2014-03-06 18:50:59 +01:00
|
|
|
|
2014-03-05 09:24:07 +01:00
|
|
|
"unselect" will remove from the project - pushing them back to the backlog
|
2014-02-10 10:20:16 +01:00
|
|
|
|
2013-09-04 15:11:27 +02:00
|
|
|
Usage:
|
2015-12-22 14:53:42 +01:00
|
|
|
osc staging accept [--force] [LETTER...]
|
2014-07-08 15:02:12 +02:00
|
|
|
osc staging check [--old] REPO
|
2014-03-06 18:50:59 +01:00
|
|
|
osc staging cleanup_rings
|
|
|
|
osc staging freeze PROJECT...
|
2016-02-03 13:04:30 +01:00
|
|
|
osc staging frozenage PROJECT...
|
2015-10-05 10:49:44 +02:00
|
|
|
osc staging list [--supersede]
|
2015-03-24 14:46:36 +01:00
|
|
|
osc staging select [--no-freeze] [--move [--from PROJECT]] LETTER REQUEST...
|
2014-03-05 09:24:07 +01:00
|
|
|
osc staging unselect REQUEST...
|
2013-09-04 15:11:27 +02:00
|
|
|
"""
|
|
|
|
if opts.version:
|
|
|
|
self._print_version()
|
|
|
|
|
|
|
|
# verify the argument counts match the commands
|
2014-02-10 19:59:45 +01:00
|
|
|
if len(args) == 0:
|
|
|
|
raise oscerr.WrongArgs('No command given, see "osc help staging"!')
|
2013-09-04 15:11:27 +02:00
|
|
|
cmd = args[0]
|
2016-02-03 13:04:30 +01:00
|
|
|
if cmd in ('freeze', 'frozenage'):
|
2014-06-01 19:51:18 +02:00
|
|
|
min_args, max_args = 1, None
|
2014-03-03 17:20:40 +01:00
|
|
|
elif cmd == 'check':
|
2014-02-17 15:13:27 +01:00
|
|
|
min_args, max_args = 0, 2
|
2014-03-04 16:50:49 +01:00
|
|
|
elif cmd == 'select':
|
2014-07-17 13:55:45 +02:00
|
|
|
min_args, max_args = 1, None
|
|
|
|
if not opts.add:
|
|
|
|
min_args = 2
|
2014-03-04 16:50:49 +01:00
|
|
|
elif cmd == 'unselect':
|
|
|
|
min_args, max_args = 1, None
|
2015-07-19 09:32:32 +02:00
|
|
|
elif cmd == 'adi':
|
|
|
|
min_args, max_args = None, None
|
2015-10-11 08:54:05 +02:00
|
|
|
elif cmd in ('list', 'accept'):
|
2015-10-01 19:09:15 +08:00
|
|
|
min_args, max_args = 0, None
|
2015-12-22 22:39:49 +01:00
|
|
|
elif cmd in ('cleanup_rings', 'acheck'):
|
2014-01-31 10:29:44 +01:00
|
|
|
min_args, max_args = 0, 0
|
2013-09-04 15:11:27 +02:00
|
|
|
else:
|
2014-03-03 17:20:40 +01:00
|
|
|
raise oscerr.WrongArgs('Unknown command: %s' % cmd)
|
2013-09-04 15:11:27 +02:00
|
|
|
if len(args) - 1 < min_args:
|
|
|
|
raise oscerr.WrongArgs('Too few arguments.')
|
2014-03-28 11:46:14 +01:00
|
|
|
if max_args is not None and len(args) - 1 > max_args:
|
2013-09-04 15:11:27 +02:00
|
|
|
raise oscerr.WrongArgs('Too many arguments.')
|
|
|
|
|
2015-02-17 17:51:27 +01:00
|
|
|
# Init the OBS access and configuration
|
|
|
|
opts.project = self._full_project_name(opts.project)
|
2014-01-31 10:29:44 +01:00
|
|
|
opts.apiurl = self.get_api_url()
|
|
|
|
opts.verbose = False
|
2015-02-17 17:51:27 +01:00
|
|
|
Config(opts.project)
|
2015-02-10 17:22:00 +01:00
|
|
|
|
2015-02-17 17:51:27 +01:00
|
|
|
with OBSLock(opts.apiurl, opts.project):
|
2015-02-10 17:22:00 +01:00
|
|
|
api = StagingAPI(opts.apiurl, opts.project)
|
|
|
|
|
|
|
|
# call the respective command and parse args by need
|
|
|
|
if cmd == 'check':
|
|
|
|
prj = args[1] if len(args) > 1 else None
|
|
|
|
CheckCommand(api).perform(prj, opts.old)
|
|
|
|
elif cmd == 'freeze':
|
|
|
|
for prj in args[1:]:
|
|
|
|
FreezeCommand(api).perform(api.prj_from_letter(prj))
|
2016-02-03 13:04:30 +01:00
|
|
|
elif cmd == 'frozenage':
|
|
|
|
for prj in args[1:]:
|
|
|
|
print "%s last frozen %0.1f days ago" % (api.prj_from_letter(prj), api.days_since_last_freeze(api.prj_from_letter(prj)))
|
2015-12-22 22:39:49 +01:00
|
|
|
elif cmd == 'acheck':
|
|
|
|
# Is it safe to accept? Meaning: /totest contains what it should and is not dirty
|
|
|
|
version_totest = api.get_binary_version(api.project, "openSUSE-release.rpm", repository="totest", arch="x86_64")
|
2016-03-25 18:53:12 +08:00
|
|
|
skip_totest = False
|
|
|
|
if not version_totest:
|
|
|
|
# SLE don't have totest repository and openSUSE-release.rpm
|
|
|
|
skip_totest = api.item_exists(api.project, "release-notes-sles")
|
|
|
|
|
|
|
|
if not skip_totest:
|
|
|
|
version_openqa = api.load_file_content("%s:Staging" % api.project, "dashboard", "version_totest")
|
|
|
|
totest_dirty = api.is_repo_dirty(api.project, 'totest')
|
|
|
|
print "version_openqa: %s / version_totest: %s / totest_dirty: %s\n" % (version_openqa, version_totest, totest_dirty)
|
|
|
|
else:
|
|
|
|
print "acheck is unavailable in %s!\n" % (api.project)
|
2015-02-10 17:22:00 +01:00
|
|
|
elif cmd == 'accept':
|
2015-11-26 11:20:36 +01:00
|
|
|
# Is it safe to accept? Meaning: /totest contains what it should and is not dirty
|
|
|
|
version_totest = api.get_binary_version(api.project, "openSUSE-release.rpm", repository="totest", arch="x86_64")
|
2016-03-25 18:53:12 +08:00
|
|
|
skip_totest = False
|
|
|
|
if not version_totest:
|
|
|
|
# SLE don't have totest repository and openSUSE-release.rpm
|
|
|
|
skip_totest = api.item_exists(api.project, "release-notes-sles")
|
|
|
|
|
2016-04-03 23:00:11 +02:00
|
|
|
if skip_totest or opts.force:
|
2016-03-26 02:59:28 +08:00
|
|
|
# Nor version_openqa or totest_dirty
|
|
|
|
cmd = AcceptCommand(api)
|
|
|
|
for prj in args[1:]:
|
|
|
|
if not cmd.perform(api.prj_from_letter(prj)):
|
|
|
|
return
|
|
|
|
cmd.accept_other_new()
|
|
|
|
cmd.update_factory_version()
|
|
|
|
if api.item_exists(api.crebuild):
|
|
|
|
cmd.sync_buildfailures()
|
|
|
|
else:
|
2016-03-25 18:53:12 +08:00
|
|
|
version_openqa = api.load_file_content("%s:Staging" % api.project, "dashboard", "version_totest")
|
|
|
|
totest_dirty = api.is_repo_dirty(api.project, 'totest')
|
2016-03-26 02:59:28 +08:00
|
|
|
if version_openqa == version_totest and not totest_dirty:
|
2016-03-25 18:53:12 +08:00
|
|
|
cmd = AcceptCommand(api)
|
|
|
|
for prj in args[1:]:
|
|
|
|
if not cmd.perform(api.prj_from_letter(prj)):
|
|
|
|
return
|
|
|
|
cmd.accept_other_new()
|
|
|
|
cmd.update_factory_version()
|
|
|
|
if api.item_exists(api.crebuild):
|
|
|
|
cmd.sync_buildfailures()
|
|
|
|
else:
|
|
|
|
print "Not safe to accept: /totest is not yet synced"
|
2015-02-10 17:22:00 +01:00
|
|
|
elif cmd == 'unselect':
|
|
|
|
UnselectCommand(api).perform(args[1:])
|
|
|
|
elif cmd == 'select':
|
|
|
|
tprj = api.prj_from_letter(args[1])
|
|
|
|
if opts.add:
|
|
|
|
api.mark_additional_packages(tprj, [opts.add])
|
|
|
|
else:
|
2015-07-16 15:09:26 +02:00
|
|
|
SelectCommand(api, tprj).perform(args[2:], opts.move,
|
2015-08-28 13:30:25 +02:00
|
|
|
opts.from_, opts.no_freeze)
|
2015-02-10 17:22:00 +01:00
|
|
|
elif cmd == 'cleanup_rings':
|
|
|
|
CleanupRings(api).perform()
|
|
|
|
elif cmd == 'list':
|
2015-10-01 19:09:15 +08:00
|
|
|
ListCommand(api).perform(args[1:], supersede=opts.supersede)
|
2015-07-16 15:09:26 +02:00
|
|
|
elif cmd == 'adi':
|
2015-08-27 18:42:39 +08:00
|
|
|
AdiCommand(api).perform(args[1:], move=opts.move, by_dp=opts.by_develproject)
|