xref: /openbmc/openbmc/poky/bitbake/lib/bb/fetch2/osc.py (revision 92b42cb3)
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