1c342db35SBrad Bishop# 2*92b42cb3SPatrick Williams# Copyright BitBake Contributors 3*92b42cb3SPatrick Williams# 4c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 5c342db35SBrad Bishop# 6eb8dc403SDave Cobbley""" 7eb8dc403SDave CobbleyBitbake "Fetch" implementation for osc (Opensuse build service client). 8eb8dc403SDave CobbleyBased on the svn "Fetch" implementation. 9eb8dc403SDave Cobbley 10eb8dc403SDave Cobbley""" 11eb8dc403SDave Cobbley 12eb8dc403SDave Cobbleyimport logging 13c9f7865aSAndrew Geisslerimport os 14d583833aSAndrew Geisslerimport re 15eb8dc403SDave Cobbleyimport bb 16eb8dc403SDave Cobbleyfrom bb.fetch2 import FetchMethod 17eb8dc403SDave Cobbleyfrom bb.fetch2 import FetchError 18eb8dc403SDave Cobbleyfrom bb.fetch2 import MissingParameterError 19eb8dc403SDave Cobbleyfrom bb.fetch2 import runfetchcmd 20eb8dc403SDave Cobbley 21c9f7865aSAndrew Geisslerlogger = logging.getLogger(__name__) 22c9f7865aSAndrew Geissler 23eb8dc403SDave Cobbleyclass Osc(FetchMethod): 24eb8dc403SDave Cobbley """Class to fetch a module or modules from Opensuse build server 25eb8dc403SDave Cobbley repositories.""" 26eb8dc403SDave Cobbley 27eb8dc403SDave Cobbley def supports(self, ud, d): 28eb8dc403SDave Cobbley """ 29eb8dc403SDave Cobbley Check to see if a given url can be fetched with osc. 30eb8dc403SDave Cobbley """ 31eb8dc403SDave Cobbley return ud.type in ['osc'] 32eb8dc403SDave Cobbley 33eb8dc403SDave Cobbley def urldata_init(self, ud, d): 34eb8dc403SDave Cobbley if not "module" in ud.parm: 35eb8dc403SDave Cobbley raise MissingParameterError('module', ud.url) 36eb8dc403SDave Cobbley 37eb8dc403SDave Cobbley ud.module = ud.parm["module"] 38eb8dc403SDave Cobbley 39eb8dc403SDave Cobbley # Create paths to osc checkouts 401a4b7ee2SBrad Bishop oscdir = d.getVar("OSCDIR") or (d.getVar("DL_DIR") + "/osc") 41eb8dc403SDave Cobbley relpath = self._strip_leading_slashes(ud.path) 42d583833aSAndrew Geissler ud.oscdir = oscdir 431a4b7ee2SBrad Bishop ud.pkgdir = os.path.join(oscdir, ud.host) 44eb8dc403SDave Cobbley ud.moddir = os.path.join(ud.pkgdir, relpath, ud.module) 45eb8dc403SDave Cobbley 46eb8dc403SDave Cobbley if 'rev' in ud.parm: 47eb8dc403SDave Cobbley ud.revision = ud.parm['rev'] 48eb8dc403SDave Cobbley else: 49eb8dc403SDave Cobbley pv = d.getVar("PV", False) 5003907ee1SPatrick Williams rev = bb.fetch2.srcrev_internal_helper(ud, d, '') 5182c905dcSAndrew Geissler if rev: 52eb8dc403SDave Cobbley ud.revision = rev 53eb8dc403SDave Cobbley else: 54eb8dc403SDave Cobbley ud.revision = "" 55eb8dc403SDave Cobbley 56d583833aSAndrew Geissler ud.localfile = d.expand('%s_%s_%s.tar.gz' % (ud.module.replace('/', '.'), relpath.replace('/', '.'), ud.revision)) 57eb8dc403SDave Cobbley 58eb8dc403SDave Cobbley def _buildosccommand(self, ud, d, command): 59eb8dc403SDave Cobbley """ 60eb8dc403SDave Cobbley Build up an ocs commandline based on ud 61eb8dc403SDave Cobbley command is "fetch", "update", "info" 62eb8dc403SDave Cobbley """ 63eb8dc403SDave Cobbley 641a4b7ee2SBrad Bishop basecmd = d.getVar("FETCHCMD_osc") or "/usr/bin/env osc" 65eb8dc403SDave Cobbley 66d583833aSAndrew Geissler proto = ud.parm.get('protocol', 'https') 67eb8dc403SDave Cobbley 68eb8dc403SDave Cobbley options = [] 69eb8dc403SDave Cobbley 70eb8dc403SDave Cobbley config = "-c %s" % self.generate_config(ud, d) 71eb8dc403SDave Cobbley 72d583833aSAndrew Geissler if getattr(ud, 'revision', ''): 73eb8dc403SDave Cobbley options.append("-r %s" % ud.revision) 74eb8dc403SDave Cobbley 75eb8dc403SDave Cobbley coroot = self._strip_leading_slashes(ud.path) 76eb8dc403SDave Cobbley 77eb8dc403SDave Cobbley if command == "fetch": 78d583833aSAndrew Geissler osccmd = "%s %s -A %s://%s co %s/%s %s" % (basecmd, config, proto, ud.host, coroot, ud.module, " ".join(options)) 79eb8dc403SDave Cobbley elif command == "update": 80d583833aSAndrew Geissler osccmd = "%s %s -A %s://%s up %s" % (basecmd, config, proto, ud.host, " ".join(options)) 81d583833aSAndrew Geissler elif command == "api_source": 82d583833aSAndrew Geissler osccmd = "%s %s -A %s://%s api source/%s/%s" % (basecmd, config, proto, ud.host, coroot, ud.module) 83eb8dc403SDave Cobbley else: 84eb8dc403SDave Cobbley raise FetchError("Invalid osc command %s" % command, ud.url) 85eb8dc403SDave Cobbley 86eb8dc403SDave Cobbley return osccmd 87eb8dc403SDave Cobbley 88d583833aSAndrew Geissler def _latest_revision(self, ud, d, name): 89d583833aSAndrew Geissler """ 90d583833aSAndrew Geissler Fetch latest revision for the given package 91d583833aSAndrew Geissler """ 92d583833aSAndrew Geissler api_source_cmd = self._buildosccommand(ud, d, "api_source") 93d583833aSAndrew Geissler 94d583833aSAndrew Geissler output = runfetchcmd(api_source_cmd, d) 95d583833aSAndrew Geissler match = re.match(r'<directory ?.* rev="(\d+)".*>', output) 96d583833aSAndrew Geissler if match is None: 97d583833aSAndrew Geissler raise FetchError("Unable to parse osc response", ud.url) 98d583833aSAndrew Geissler return match.groups()[0] 99d583833aSAndrew Geissler 100d583833aSAndrew Geissler def _revision_key(self, ud, d, name): 101d583833aSAndrew Geissler """ 102d583833aSAndrew Geissler Return a unique key for the url 103d583833aSAndrew Geissler """ 104d583833aSAndrew Geissler # Collapse adjacent slashes 105d583833aSAndrew Geissler slash_re = re.compile(r"/+") 106d583833aSAndrew Geissler rev = getattr(ud, 'revision', "latest") 107d583833aSAndrew Geissler return "osc:%s%s.%s.%s" % (ud.host, slash_re.sub(".", ud.path), name, rev) 108d583833aSAndrew Geissler 109eb8dc403SDave Cobbley def download(self, ud, d): 110eb8dc403SDave Cobbley """ 111eb8dc403SDave Cobbley Fetch url 112eb8dc403SDave Cobbley """ 113eb8dc403SDave Cobbley 114d1e89497SAndrew Geissler logger.debug2("Fetch: checking for module directory '" + ud.moddir + "'") 115eb8dc403SDave Cobbley 116d583833aSAndrew Geissler if os.access(ud.moddir, os.R_OK): 117eb8dc403SDave Cobbley oscupdatecmd = self._buildosccommand(ud, d, "update") 118eb8dc403SDave Cobbley logger.info("Update "+ ud.url) 119eb8dc403SDave Cobbley # update sources there 120d1e89497SAndrew Geissler logger.debug("Running %s", oscupdatecmd) 121eb8dc403SDave Cobbley bb.fetch2.check_network_access(d, oscupdatecmd, ud.url) 122eb8dc403SDave Cobbley runfetchcmd(oscupdatecmd, d, workdir=ud.moddir) 123eb8dc403SDave Cobbley else: 124eb8dc403SDave Cobbley oscfetchcmd = self._buildosccommand(ud, d, "fetch") 125eb8dc403SDave Cobbley logger.info("Fetch " + ud.url) 126eb8dc403SDave Cobbley # check out sources there 127eb8dc403SDave Cobbley bb.utils.mkdirhier(ud.pkgdir) 128d1e89497SAndrew Geissler logger.debug("Running %s", oscfetchcmd) 129eb8dc403SDave Cobbley bb.fetch2.check_network_access(d, oscfetchcmd, ud.url) 130eb8dc403SDave Cobbley runfetchcmd(oscfetchcmd, d, workdir=ud.pkgdir) 131eb8dc403SDave Cobbley 132eb8dc403SDave Cobbley # tar them up to a defined filename 133eb8dc403SDave Cobbley runfetchcmd("tar -czf %s %s" % (ud.localpath, ud.module), d, 134eb8dc403SDave Cobbley cleanup=[ud.localpath], workdir=os.path.join(ud.pkgdir + ud.path)) 135eb8dc403SDave Cobbley 136eb8dc403SDave Cobbley def supports_srcrev(self): 137eb8dc403SDave Cobbley return False 138eb8dc403SDave Cobbley 139eb8dc403SDave Cobbley def generate_config(self, ud, d): 140eb8dc403SDave Cobbley """ 141eb8dc403SDave Cobbley Generate a .oscrc to be used for this run. 142eb8dc403SDave Cobbley """ 143eb8dc403SDave Cobbley 144d583833aSAndrew Geissler config_path = os.path.join(ud.oscdir, "oscrc") 145d583833aSAndrew Geissler if not os.path.exists(ud.oscdir): 146d583833aSAndrew Geissler bb.utils.mkdirhier(ud.oscdir) 147d583833aSAndrew Geissler 148eb8dc403SDave Cobbley if (os.path.exists(config_path)): 149eb8dc403SDave Cobbley os.remove(config_path) 150eb8dc403SDave Cobbley 151eb8dc403SDave Cobbley f = open(config_path, 'w') 152d583833aSAndrew Geissler proto = ud.parm.get('protocol', 'https') 153eb8dc403SDave Cobbley f.write("[general]\n") 154d583833aSAndrew Geissler f.write("apiurl = %s://%s\n" % (proto, ud.host)) 155eb8dc403SDave Cobbley f.write("su-wrapper = su -c\n") 156eb8dc403SDave Cobbley f.write("build-root = %s\n" % d.getVar('WORKDIR')) 157eb8dc403SDave Cobbley f.write("urllist = %s\n" % d.getVar("OSCURLLIST")) 158eb8dc403SDave Cobbley f.write("extra-pkgs = gzip\n") 159eb8dc403SDave Cobbley f.write("\n") 160d583833aSAndrew Geissler f.write("[%s://%s]\n" % (proto, ud.host)) 161eb8dc403SDave Cobbley f.write("user = %s\n" % ud.parm["user"]) 162eb8dc403SDave Cobbley f.write("pass = %s\n" % ud.parm["pswd"]) 163eb8dc403SDave Cobbley f.close() 164eb8dc403SDave Cobbley 165eb8dc403SDave Cobbley return config_path 166