1# 2# Copyright BitBake Contributors 3# 4# SPDX-License-Identifier: GPL-2.0-only 5# 6""" 7Bitbake "Fetch" implementation for osc (Opensuse build service client). 8Based on the svn "Fetch" implementation. 9 10""" 11 12import logging 13import os 14import bb 15from bb.fetch2 import FetchMethod 16from bb.fetch2 import FetchError 17from bb.fetch2 import MissingParameterError 18from bb.fetch2 import runfetchcmd 19 20logger = logging.getLogger(__name__) 21 22class Osc(FetchMethod): 23 """Class to fetch a module or modules from Opensuse build server 24 repositories.""" 25 26 def supports(self, ud, d): 27 """ 28 Check to see if a given url can be fetched with osc. 29 """ 30 return ud.type in ['osc'] 31 32 def urldata_init(self, ud, d): 33 if not "module" in ud.parm: 34 raise MissingParameterError('module', ud.url) 35 36 ud.module = ud.parm["module"] 37 38 # Create paths to osc checkouts 39 oscdir = d.getVar("OSCDIR") or (d.getVar("DL_DIR") + "/osc") 40 relpath = self._strip_leading_slashes(ud.path) 41 ud.oscdir = oscdir 42 ud.pkgdir = os.path.join(oscdir, ud.host) 43 ud.moddir = os.path.join(ud.pkgdir, relpath, ud.module) 44 45 if 'rev' in ud.parm: 46 ud.revision = ud.parm['rev'] 47 else: 48 pv = d.getVar("PV", False) 49 rev = bb.fetch2.srcrev_internal_helper(ud, d, '') 50 if rev: 51 ud.revision = rev 52 else: 53 ud.revision = "" 54 55 ud.localfile = d.expand('%s_%s_%s.tar.gz' % (ud.module.replace('/', '.'), relpath.replace('/', '.'), ud.revision)) 56 57 def _buildosccommand(self, ud, d, command): 58 """ 59 Build up an ocs commandline based on ud 60 command is "fetch", "update", "info" 61 """ 62 63 basecmd = d.getVar("FETCHCMD_osc") or "/usr/bin/env osc" 64 65 proto = ud.parm.get('protocol', 'ocs') 66 67 options = [] 68 69 config = "-c %s" % self.generate_config(ud, d) 70 71 if ud.revision: 72 options.append("-r %s" % ud.revision) 73 74 coroot = self._strip_leading_slashes(ud.path) 75 76 if command == "fetch": 77 osccmd = "%s %s co %s/%s %s" % (basecmd, config, coroot, ud.module, " ".join(options)) 78 elif command == "update": 79 osccmd = "%s %s up %s" % (basecmd, config, " ".join(options)) 80 else: 81 raise FetchError("Invalid osc command %s" % command, ud.url) 82 83 return osccmd 84 85 def download(self, ud, d): 86 """ 87 Fetch url 88 """ 89 90 logger.debug2("Fetch: checking for module directory '" + ud.moddir + "'") 91 92 if os.access(ud.moddir, os.R_OK): 93 oscupdatecmd = self._buildosccommand(ud, d, "update") 94 logger.info("Update "+ ud.url) 95 # update sources there 96 logger.debug("Running %s", oscupdatecmd) 97 bb.fetch2.check_network_access(d, oscupdatecmd, ud.url) 98 runfetchcmd(oscupdatecmd, d, workdir=ud.moddir) 99 else: 100 oscfetchcmd = self._buildosccommand(ud, d, "fetch") 101 logger.info("Fetch " + ud.url) 102 # check out sources there 103 bb.utils.mkdirhier(ud.pkgdir) 104 logger.debug("Running %s", oscfetchcmd) 105 bb.fetch2.check_network_access(d, oscfetchcmd, ud.url) 106 runfetchcmd(oscfetchcmd, d, workdir=ud.pkgdir) 107 108 # tar them up to a defined filename 109 runfetchcmd("tar -czf %s %s" % (ud.localpath, ud.module), d, 110 cleanup=[ud.localpath], workdir=os.path.join(ud.pkgdir + ud.path)) 111 112 def supports_srcrev(self): 113 return False 114 115 def generate_config(self, ud, d): 116 """ 117 Generate a .oscrc to be used for this run. 118 """ 119 120 config_path = os.path.join(ud.oscdir, "oscrc") 121 if not os.path.exists(ud.oscdir): 122 bb.utils.mkdirhier(ud.oscdir) 123 124 if (os.path.exists(config_path)): 125 os.remove(config_path) 126 127 f = open(config_path, 'w') 128 proto = ud.parm.get('proto', 'https') 129 f.write("[general]\n") 130 f.write("apiurl = %s://%s\n" % (proto, ud.host)) 131 f.write("su-wrapper = su -c\n") 132 f.write("build-root = %s\n" % d.getVar('WORKDIR')) 133 f.write("urllist = %s\n" % d.getVar("OSCURLLIST")) 134 f.write("extra-pkgs = gzip\n") 135 f.write("\n") 136 f.write("[%s://%s]\n" % (proto, ud.host)) 137 f.write("user = %s\n" % ud.parm["user"]) 138 f.write("pass = %s\n" % ud.parm["pswd"]) 139 f.close() 140 141 return config_path 142