% '\n'.join(results))
return 0
- msger.info('checking status of obs project: %s ...' % target_prj)
- if not api.exists(target_prj):
- msger.info('copying settings of %s to %s' % (base_prj, target_prj))
- api.copy_project(base_prj, target_prj)
-
- if api.exists(target_prj, package):
- msger.info('cleaning existing package')
- api.remove_files(target_prj, package)
- else:
- msger.info('creating new package %s/%s' % (target_prj, package))
- api.create_package(target_prj, package)
except OSCError, err:
msger.error(str(err))
except GitRepositoryError, exc:
msger.error('failed to get commit info: %s' % exc)
- msger.info('commit packaging files to build server ...')
+ files = glob.glob("%s/*" % exportdir)
try:
- api.commit_files(target_prj, package,
- glob.glob("%s/*" % exportdir), commit_msg)
- except errors.ObsError, exc:
- msger.error('commit packages fail: %s, please check the permission '\
- 'of target project:%s' % (exc, target_prj))
+ msger.info('checking status of obs project: %s ...' % target_prj)
+ if api.exists(target_prj, package):
+ old, _not_changed, changed, new = api.diff_files(target_prj,
+ package, files)
+ if old:
+ msger.info("removing old files from OBS project")
+ api.remove_files(target_prj, package, old)
+ commit_files = changed + new
+ else:
+ msger.info('copying settings of %s to %s' % (base_prj, target_prj))
+ api.copy_project(base_prj, target_prj)
+ msger.info('creating new package %s/%s' % (target_prj, package))
+ api.create_package(target_prj, package)
+ # new project - submitting all local files
+ commit_files = files
+ except OSCError, err:
+ msger.error(str(err))
+
+ if not commit_files:
+ msger.warning("No local changes found. Triggering rebuild")
+ api.rebuild(target_prj, package, obs_arch)
+ else:
+ msger.info('commit packaging files to build server ...')
+ commit_files = [(fpath, fpath in commit_files) for fpath in files]
+ try:
+ api.commit_files(target_prj, package, commit_files, commit_msg)
+ except errors.ObsError, exc:
+ msger.error('commit packages fail: %s, please check the permission '\
+ 'of target project:%s' % (exc, target_prj))
+ msger.info('local changes submitted to build server successfully')
- msger.info('local changes submitted to build server successfully')
msger.info('follow the link to monitor the build progress:\n'
' %s/package/show?package=%s&project=%s' \
% (apiurl.replace('api', 'build'), package, target_prj))
return True
+ def rebuild(self, prj, pkg, arch):
+ """Rebuild package."""
+ try:
+ return core.rebuild(self.apiurl, prj, pkg, repo=None, arch=arch)
+ except (urllib2.URLError, M2Crypto.m2urllib2.URLError, \
+ M2Crypto.SSL.SSLError), err:
+ raise ObsError("Can't trigger rebuild for %s/%s: %s" % \
+ (prj, pkg, str(err)))
+ except SSLVerificationError:
+ raise ObsError("SSL verification error.")
+
+ def diff_files(self, prj, pkg, paths):
+ """
+ Find difference between local and remote filelists
+ Return 4 lists: (old, not changed, changed, new)
+ where:
+ old - present only remotely
+ changed - present remotely and locally and differ
+ not changed - present remotely and locally and does not not differ
+ new - present only locally
+ old is a list of remote filenames
+ changed, not changed and new are lists of local filepaths
+ """
+
+ # Get list of files from the OBS
+ rfiles = core.meta_get_filelist(self.apiurl, prj, pkg, verbose=True)
+
+ old, not_changed, changed, new = [], [], [], []
+
+ if not rfiles:
+ # no remote files - all local files are new
+ return old, not_changed, changed, paths[:]
+
+ # Helper dictionary helps to avoid looping over remote files
+ rdict = dict((fobj.name, (fobj.size, fobj.md5)) for fobj in rfiles)
+
+ for lpath in paths:
+ lname = os.path.basename(lpath)
+ if lname in rdict:
+ lsize = os.path.getsize(lpath)
+ rsize, rmd5 = rdict[lname]
+ if rsize == lsize and rmd5 == core.dgst(lpath):
+ not_changed.append(lpath)
+ else:
+ changed.append(lpath)
+ # remove processed files from the remote dict
+ # after processing only old files will be letf there
+ rdict.pop(lname)
+ else:
+ new.append(lpath)
+
+ return rdict.keys(), not_changed, changed, new
+
def commit_files(self, prj, pkg, files, message):
"""Commits files to OBS."""
url = core.makeurl(self.apiurl, ['source', prj, pkg], query=query)
xml = "<directory>"
- for fpath in files:
+ for fpath, _ in files:
with open(fpath) as fhandle:
xml += '<entry name="%s" md5="%s"/>' % \
(os.path.basename(fpath), hexdigest(fhandle))
try:
self.core_http(core.http_POST, url, data=xml)
- for fpath in files:
- put_url = core.makeurl(
- self.apiurl, ['source', prj, pkg,
- pathname2url(os.path.basename(fpath))],
- query="rev=repository")
- self.core_http(core.http_PUT, put_url, filep=fpath)
+ for fpath, commit_flag in files:
+ if commit_flag:
+ put_url = core.makeurl(
+ self.apiurl, ['source', prj, pkg,
+ pathname2url(os.path.basename(fpath))],
+ query="rev=repository")
+ self.core_http(core.http_PUT, put_url, filep=fpath)
self.core_http(core.http_POST, url, data=xml)
except OSCError, err:
raise ObsError("can't commit files to %s/%s: %s" % (prj, pkg, err))