diff options
-rwxr-xr-x | bin/bitbake-worker | 6 | ||||
-rw-r--r-- | contrib/hashserv/Dockerfile | 6 | ||||
-rw-r--r-- | lib/bb/build.py | 14 | ||||
-rw-r--r-- | lib/bb/cooker.py | 34 | ||||
-rw-r--r-- | lib/bb/data_smart.py | 10 | ||||
-rw-r--r-- | lib/bb/fetch2/__init__.py | 14 | ||||
-rw-r--r-- | lib/bb/fetch2/git.py | 4 | ||||
-rw-r--r-- | lib/bb/fetch2/npm.py | 16 | ||||
-rw-r--r-- | lib/bb/fetch2/perforce.py | 2 | ||||
-rw-r--r-- | lib/bb/fetch2/ssh.py | 2 | ||||
-rw-r--r-- | lib/bb/fetch2/wget.py | 2 | ||||
-rw-r--r-- | lib/bb/process.py | 2 | ||||
-rw-r--r-- | lib/bb/runqueue.py | 34 | ||||
-rw-r--r-- | lib/bb/server/process.py | 3 | ||||
-rw-r--r-- | lib/bb/server/xmlrpcserver.py | 1 | ||||
-rw-r--r-- | lib/bb/tests/fetch.py | 52 | ||||
-rw-r--r-- | lib/bb/tests/runqueue.py | 2 | ||||
-rw-r--r-- | lib/bb/ui/knotty.py | 11 | ||||
-rw-r--r-- | lib/bb/utils.py | 15 | ||||
-rw-r--r-- | lib/pyinotify.py | 30 | ||||
-rw-r--r-- | lib/toaster/orm/fixtures/oe-core.xml | 28 | ||||
-rw-r--r-- | lib/toaster/orm/fixtures/poky.xml | 80 | ||||
-rw-r--r-- | lib/toaster/orm/fixtures/settings.xml | 2 | ||||
-rw-r--r-- | lib/toaster/orm/models.py | 2 | ||||
-rw-r--r-- | lib/toaster/toastergui/templates/projectconf.html | 16 |
25 files changed, 244 insertions, 144 deletions
diff --git a/bin/bitbake-worker b/bin/bitbake-worker index 6a12e1fed..7fde68876 100755 --- a/bin/bitbake-worker +++ b/bin/bitbake-worker @@ -417,7 +417,11 @@ class BitbakeWorker(object): if self.queue.startswith(b"<" + item + b">"): index = self.queue.find(b"</" + item + b">") while index != -1: - func(self.queue[(len(item) + 2):index]) + try: + func(self.queue[(len(item) + 2):index]) + except pickle.UnpicklingError: + workerlog_write("Unable to unpickle data: %s\n" % ":".join("{:02x}".format(c) for c in self.queue)) + raise self.queue = self.queue[(index + len(item) + 3):] index = self.queue.find(b"</" + item + b">") diff --git a/contrib/hashserv/Dockerfile b/contrib/hashserv/Dockerfile index d6fc728f3..74b4a3be1 100644 --- a/contrib/hashserv/Dockerfile +++ b/contrib/hashserv/Dockerfile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT # # Copyright (c) 2021 Joshua Watt <JPEWhacker@gmail.com> -# +# # Dockerfile to build a bitbake hash equivalence server container # # From the root of the bitbake repository, run: @@ -15,5 +15,9 @@ RUN apk add --no-cache python3 COPY bin/bitbake-hashserv /opt/bbhashserv/bin/ COPY lib/hashserv /opt/bbhashserv/lib/hashserv/ +COPY lib/bb /opt/bbhashserv/lib/bb/ +COPY lib/codegen.py /opt/bbhashserv/lib/codegen.py +COPY lib/ply /opt/bbhashserv/lib/ply/ +COPY lib/bs4 /opt/bbhashserv/lib/bs4/ ENTRYPOINT ["/opt/bbhashserv/bin/bitbake-hashserv"] diff --git a/lib/bb/build.py b/lib/bb/build.py index 7e4ab9f64..44d1d9d98 100644 --- a/lib/bb/build.py +++ b/lib/bb/build.py @@ -715,19 +715,23 @@ def _exec_task(fn, task, d, quieterr): logger.debug2("Zero size logfn %s, removing", logfn) bb.utils.remove(logfn) bb.utils.remove(loglink) - except bb.BBHandledException: - event.fire(TaskFailed(task, fn, logfn, localdata, True), localdata) - return 1 except (Exception, SystemExit) as exc: + handled = False + if isinstance(exc, bb.BBHandledException): + handled = True + if quieterr: + if not handled: + logger.warning(repr(exc)) event.fire(TaskFailedSilent(task, fn, logfn, localdata), localdata) else: errprinted = errchk.triggered # If the output is already on stdout, we've printed the information in the # logs once already so don't duplicate - if verboseStdoutLogging: + if verboseStdoutLogging or handled: errprinted = True - logger.error(repr(exc)) + if not handled: + logger.error(repr(exc)) event.fire(TaskFailed(task, fn, logfn, localdata, errprinted), localdata) return 1 diff --git a/lib/bb/cooker.py b/lib/bb/cooker.py index af794b4c4..288d73fd9 100644 --- a/lib/bb/cooker.py +++ b/lib/bb/cooker.py @@ -388,12 +388,22 @@ class BBCooker: # Create a new hash server bound to a unix domain socket if not self.hashserv: dbfile = (self.data.getVar("PERSISTENT_DIR") or self.data.getVar("CACHE")) + "/hashserv.db" + upstream = self.data.getVar("BB_HASHSERVE_UPSTREAM") or None + if upstream: + import socket + try: + sock = socket.create_connection(upstream.split(":"), 5) + sock.close() + except socket.error as e: + bb.warn("BB_HASHSERVE_UPSTREAM is not valid, unable to connect hash equivalence server at '%s': %s" + % (upstream, repr(e))) + self.hashservaddr = "unix://%s/hashserve.sock" % self.data.getVar("TOPDIR") self.hashserv = hashserv.create_server( self.hashservaddr, dbfile, sync=False, - upstream=self.data.getVar("BB_HASHSERVE_UPSTREAM") or None, + upstream=upstream, ) self.hashserv.serve_as_process() self.data.setVar("BB_HASHSERVE", self.hashservaddr) @@ -804,7 +814,9 @@ class BBCooker: for dep in rq.rqdata.runtaskentries[tid].depends: (depmc, depfn, _, deptaskfn) = bb.runqueue.split_tid_mcfn(dep) deppn = self.recipecaches[depmc].pkg_fn[deptaskfn] - depend_tree["tdepends"][dotname].append("%s.%s" % (deppn, bb.runqueue.taskname_from_tid(dep))) + if depmc: + depmc = "mc:" + depmc + ":" + depend_tree["tdepends"][dotname].append("%s%s.%s" % (depmc, deppn, bb.runqueue.taskname_from_tid(dep))) if taskfn not in seen_fns: seen_fns.append(taskfn) packages = [] @@ -2155,6 +2167,8 @@ class CookerParser(object): self.total) bb.event.fire(event, self.cfgdata) + else: + bb.error("Parsing halted due to errors") for process in self.processes: self.parser_quit.put(None) @@ -2208,21 +2222,33 @@ class CookerParser(object): yield not cached, mc, infos def parse_generator(self): - while True: + empty = False + while self.processes or not empty: + for process in self.processes.copy(): + if not process.is_alive(): + process.join() + self.processes.remove(process) + if self.parsed >= self.toparse: break try: result = self.result_queue.get(timeout=0.25) except queue.Empty: + empty = True pass else: + empty = False value = result[1] if isinstance(value, BaseException): raise value else: yield result + if not (self.parsed >= self.toparse): + raise bb.parse.ParseError("Not all recipes parsed, parser thread killed/died? Exiting.", None) + + def parse_next(self): result = [] parsed = None @@ -2233,7 +2259,7 @@ class CookerParser(object): return False except bb.BBHandledException as exc: self.error += 1 - logger.error('Failed to parse recipe: %s' % exc.recipe) + logger.debug('Failed to parse recipe: %s' % exc.recipe) self.shutdown(clean=False, force=True) return False except ParsingFailure as exc: diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py index 8d235da12..e96032787 100644 --- a/lib/bb/data_smart.py +++ b/lib/bb/data_smart.py @@ -492,12 +492,12 @@ class DataSmart(MutableMapping): def setVar(self, var, value, **loginfo): #print("var=" + str(var) + " val=" + str(value)) - if "_append" in var or "_prepend" in var or "_remove" in var: + if not var.startswith("__anon_") and ("_append" in var or "_prepend" in var or "_remove" in var): info = "%s" % var - if "filename" in loginfo: - info += " file: %s" % loginfo[filename] - if "lineno" in loginfo: - info += " line: %s" % loginfo[lineno] + if "file" in loginfo: + info += " file: %s" % loginfo["file"] + if "line" in loginfo: + info += " line: %s" % loginfo["line"] bb.fatal("Variable %s contains an operation using the old override syntax. Please convert this layer/metadata before attempting to use with a newer bitbake." % info) self.expand_cache = {} diff --git a/lib/bb/fetch2/__init__.py b/lib/bb/fetch2/__init__.py index 259b2637a..25179bc2e 100644 --- a/lib/bb/fetch2/__init__.py +++ b/lib/bb/fetch2/__init__.py @@ -430,6 +430,7 @@ def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None): uri_replace_decoded = list(decodeurl(uri_replace)) logger.debug2("For url %s comparing %s to %s" % (uri_decoded, uri_find_decoded, uri_replace_decoded)) result_decoded = ['', '', '', '', '', {}] + # 0 - type, 1 - host, 2 - path, 3 - user, 4- pswd, 5 - params for loc, i in enumerate(uri_find_decoded): result_decoded[loc] = uri_decoded[loc] regexp = i @@ -449,6 +450,9 @@ def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None): for l in replacements: uri_replace_decoded[loc][k] = uri_replace_decoded[loc][k].replace(l, replacements[l]) result_decoded[loc][k] = uri_replace_decoded[loc][k] + elif (loc == 3 or loc == 4) and uri_replace_decoded[loc]: + # User/password in the replacement is just a straight replacement + result_decoded[loc] = uri_replace_decoded[loc] elif (re.match(regexp, uri_decoded[loc])): if not uri_replace_decoded[loc]: result_decoded[loc] = "" @@ -466,9 +470,13 @@ def uri_replace(ud, uri_find, uri_replace, replacements, d, mirrortarball=None): # Kill parameters, they make no sense for mirror tarballs uri_decoded[5] = {} elif ud.localpath and ud.method.supports_checksum(ud): - basename = os.path.basename(uri_decoded[loc]) - if basename and not result_decoded[loc].endswith(basename): - result_decoded[loc] = os.path.join(result_decoded[loc], basename) + basename = os.path.basename(ud.localpath) + if basename: + uri_basename = os.path.basename(uri_decoded[loc]) + if uri_basename and basename != uri_basename and result_decoded[loc].endswith(uri_basename): + result_decoded[loc] = result_decoded[loc].replace(uri_basename, basename) + elif not result_decoded[loc].endswith(basename): + result_decoded[loc] = os.path.join(result_decoded[loc], basename) else: return None result = encodeurl(result_decoded) diff --git a/lib/bb/fetch2/git.py b/lib/bb/fetch2/git.py index e8ddf2c76..0a708ac85 100644 --- a/lib/bb/fetch2/git.py +++ b/lib/bb/fetch2/git.py @@ -142,6 +142,10 @@ class Git(FetchMethod): ud.proto = 'file' else: ud.proto = "git" + if ud.host == "github.com" and ud.proto == "git": + # github stopped supporting git protocol + # https://github.blog/2021-09-01-improving-git-protocol-security-github/#no-more-unauthenticated-git + ud.proto = "https" if not ud.proto in ('git', 'file', 'ssh', 'http', 'https', 'rsync'): raise bb.fetch2.ParameterError("Invalid protocol type", ud.url) diff --git a/lib/bb/fetch2/npm.py b/lib/bb/fetch2/npm.py index e497c38dc..b3a3a444e 100644 --- a/lib/bb/fetch2/npm.py +++ b/lib/bb/fetch2/npm.py @@ -72,23 +72,19 @@ def npm_unpack(tarball, destdir, d): cmd += " --delay-directory-restore" cmd += " --strip-components=1" runfetchcmd(cmd, d, workdir=destdir) - runfetchcmd("chmod -R +X %s" % (destdir), d, quiet=True, workdir=destdir) + runfetchcmd("chmod -R +X '%s'" % (destdir), d, quiet=True, workdir=destdir) class NpmEnvironment(object): """ Using a npm config file seems more reliable than using cli arguments. This class allows to create a controlled environment for npm commands. """ - def __init__(self, d, configs=None, npmrc=None): + def __init__(self, d, configs=[], npmrc=None): self.d = d - if configs: - self.user_config = tempfile.NamedTemporaryFile(mode="w", buffering=1) - self.user_config_name = self.user_config.name - for key, value in configs: - self.user_config.write("%s=%s\n" % (key, value)) - else: - self.user_config_name = "/dev/null" + self.user_config = tempfile.NamedTemporaryFile(mode="w", buffering=1) + for key, value in configs: + self.user_config.write("%s=%s\n" % (key, value)) if npmrc: self.global_config_name = npmrc @@ -109,7 +105,7 @@ class NpmEnvironment(object): workdir = tmpdir def _run(cmd): - cmd = "NPM_CONFIG_USERCONFIG=%s " % (self.user_config_name) + cmd + cmd = "NPM_CONFIG_USERCONFIG=%s " % (self.user_config.name) + cmd cmd = "NPM_CONFIG_GLOBALCONFIG=%s " % (self.global_config_name) + cmd return runfetchcmd(cmd, d, workdir=workdir) diff --git a/lib/bb/fetch2/perforce.py b/lib/bb/fetch2/perforce.py index e2a41a4a1..3b6fa4b1e 100644 --- a/lib/bb/fetch2/perforce.py +++ b/lib/bb/fetch2/perforce.py @@ -134,7 +134,7 @@ class Perforce(FetchMethod): ud.setup_revisions(d) - ud.localfile = d.expand('%s_%s_%s_%s.tar.gz' % (cleanedhost, cleanedpath, cleandedmodule, ud.revision)) + ud.localfile = d.expand('%s_%s_%s_%s.tar.gz' % (cleanedhost, cleanedpath, cleanedmodule, ud.revision)) def _buildp4command(self, ud, d, command, depot_filename=None): """ diff --git a/lib/bb/fetch2/ssh.py b/lib/bb/fetch2/ssh.py index 2c8557e1f..a104c9eb1 100644 --- a/lib/bb/fetch2/ssh.py +++ b/lib/bb/fetch2/ssh.py @@ -40,9 +40,9 @@ __pattern__ = re.compile(r''' ( # Optional username/password block (?P<user>\S+) # username (:(?P<pass>\S+))? # colon followed by the password (optional) - )? (?P<cparam>(;[^;]+)*)? # connection parameters block (optional) @ + )? (?P<host>\S+?) # non-greedy match of the host (:(?P<port>[0-9]+))? # colon followed by the port (optional) / diff --git a/lib/bb/fetch2/wget.py b/lib/bb/fetch2/wget.py index 349891e85..fd9b30496 100644 --- a/lib/bb/fetch2/wget.py +++ b/lib/bb/fetch2/wget.py @@ -356,7 +356,7 @@ class Wget(FetchMethod): except (TypeError, ImportError, IOError, netrc.NetrcParseError): pass - with opener.open(r) as response: + with opener.open(r, timeout=30) as response: pass except urllib.error.URLError as e: if try_again: diff --git a/lib/bb/process.py b/lib/bb/process.py index d5a1775fc..af5d804a1 100644 --- a/lib/bb/process.py +++ b/lib/bb/process.py @@ -60,7 +60,7 @@ class Popen(subprocess.Popen): "close_fds": True, "preexec_fn": subprocess_setup, "stdout": subprocess.PIPE, - "stderr": subprocess.STDOUT, + "stderr": subprocess.PIPE, "stdin": subprocess.PIPE, "shell": False, } diff --git a/lib/bb/runqueue.py b/lib/bb/runqueue.py index 10511a09d..cd10da8b3 100644 --- a/lib/bb/runqueue.py +++ b/lib/bb/runqueue.py @@ -926,38 +926,36 @@ class RunQueueData: # # Once all active tasks are marked, prune the ones we don't need. - delcount = {} - for tid in list(self.runtaskentries.keys()): - if tid not in runq_build: - delcount[tid] = self.runtaskentries[tid] - del self.runtaskentries[tid] - # Handle --runall if self.cooker.configuration.runall: # re-run the mark_active and then drop unused tasks from new list + reduced_tasklist = set(self.runtaskentries.keys()) + for tid in list(self.runtaskentries.keys()): + if tid not in runq_build: + reduced_tasklist.remove(tid) runq_build = {} for task in self.cooker.configuration.runall: if not task.startswith("do_"): task = "do_{0}".format(task) runall_tids = set() - for tid in list(self.runtaskentries): + for tid in reduced_tasklist: wanttid = "{0}:{1}".format(fn_from_tid(tid), task) - if wanttid in delcount: - self.runtaskentries[wanttid] = delcount[wanttid] if wanttid in self.runtaskentries: runall_tids.add(wanttid) for tid in list(runall_tids): - mark_active(tid,1) + mark_active(tid, 1) if self.cooker.configuration.force: invalidate_task(tid, False) - for tid in list(self.runtaskentries.keys()): - if tid not in runq_build: - delcount[tid] = self.runtaskentries[tid] - del self.runtaskentries[tid] + delcount = set() + for tid in list(self.runtaskentries.keys()): + if tid not in runq_build: + delcount.add(tid) + del self.runtaskentries[tid] + if self.cooker.configuration.runall: if len(self.runtaskentries) == 0: bb.msg.fatal("RunQueue", "Could not find any tasks with the tasknames %s to run within the recipes of the taskgraphs of the targets %s" % (str(self.cooker.configuration.runall), str(self.targets))) @@ -971,16 +969,16 @@ class RunQueueData: for task in self.cooker.configuration.runonly: if not task.startswith("do_"): task = "do_{0}".format(task) - runonly_tids = { k: v for k, v in self.runtaskentries.items() if taskname_from_tid(k) == task } + runonly_tids = [k for k in self.runtaskentries.keys() if taskname_from_tid(k) == task] - for tid in list(runonly_tids): - mark_active(tid,1) + for tid in runonly_tids: + mark_active(tid, 1) if self.cooker.configuration.force: invalidate_task(tid, False) for tid in list(self.runtaskentries.keys()): if tid not in runq_build: - delcount[tid] = self.runtaskentries[tid] + delcount.add(tid) del self.runtaskentries[tid] if len(self.runtaskentries) == 0: diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py index 8fdcc66dc..91c463752 100644 --- a/lib/bb/server/process.py +++ b/lib/bb/server/process.py @@ -27,6 +27,7 @@ import re import datetime import pickle import traceback +import gc import bb.server.xmlrpcserver from bb import daemonize from multiprocessing import queues @@ -739,8 +740,10 @@ class ConnectionWriter(object): def send(self, obj): obj = multiprocessing.reduction.ForkingPickler.dumps(obj) + gc.disable() with self.wlock: self.writer.send_bytes(obj) + gc.enable() def fileno(self): return self.writer.fileno() diff --git a/lib/bb/server/xmlrpcserver.py b/lib/bb/server/xmlrpcserver.py index 2fa71be66..01f55538a 100644 --- a/lib/bb/server/xmlrpcserver.py +++ b/lib/bb/server/xmlrpcserver.py @@ -11,6 +11,7 @@ import hashlib import time import inspect from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler +import bb.server.xmlrpcclient import bb diff --git a/lib/bb/tests/fetch.py b/lib/bb/tests/fetch.py index c20f746f0..b59743872 100644 --- a/lib/bb/tests/fetch.py +++ b/lib/bb/tests/fetch.py @@ -431,6 +431,11 @@ class MirrorUriTest(FetcherTest): ("git://someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://git.openembedded.org/bitbake;protocol=http") : "git://git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", + ("git://user1@someserver.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master", "git://someserver.org/bitbake;branch=master", "git://user2@git.openembedded.org/bitbake;protocol=http") + : "git://user2@git.openembedded.org/bitbake;tag=1234567890123456789012345678901234567890;branch=master;protocol=http", + + ("gitsm://git.qemu.org/git/seabios.git/;protocol=https;name=roms/seabios;subpath=roms/seabios;bareclone=1;nobranch=1;rev=1234567890123456789012345678901234567890", "gitsm://.*/.*", "http://petalinux.xilinx.com/sswreleases/rel-v${XILINX_VER_MAIN}/downloads") : "http://petalinux.xilinx.com/sswreleases/rel-v%24%7BXILINX_VER_MAIN%7D/downloads/git2_git.qemu.org.git.seabios.git..tar.gz", + #Renaming files doesn't work #("http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere.org/somedir1/somefile_1.2.3.tar.gz", "http://somewhere2.org/somedir3/somefile_2.3.4.tar.gz") : "http://somewhere2.org/somedir3/somefile_2.3.4.tar.gz" #("file://sstate-xyz.tgz", "file://.*/.*", "file:///somewhere/1234/sstate-cache") : "file:///somewhere/1234/sstate-cache/sstate-xyz.tgz", @@ -491,7 +496,7 @@ class GitDownloadDirectoryNamingTest(FetcherTest): super(GitDownloadDirectoryNamingTest, self).setUp() self.recipe_url = "git://git.openembedded.org/bitbake" self.recipe_dir = "git.openembedded.org.bitbake" - self.mirror_url = "git://github.com/openembedded/bitbake.git" + self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https" self.mirror_dir = "github.com.openembedded.bitbake.git" self.d.setVar('SRCREV', '82ea737a0b42a8b53e11c9cde141e9e9c0bd8c40') @@ -539,7 +544,7 @@ class TarballNamingTest(FetcherTest): super(TarballNamingTest, self).setUp() self.recipe_url = "git://git.openembedded.org/bitbake" self.recipe_tarball = "git2_git.openembedded.org.bitbake.tar.gz" - self.mirror_url = "git://github.com/openembedded/bitbake.git" + self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https" self.mirror_tarball = "git2_github.com.openembedded.bitbake.git.tar.gz" self.d.setVar('BB_GENERATE_MIRROR_TARBALLS', '1') @@ -573,7 +578,7 @@ class GitShallowTarballNamingTest(FetcherTest): super(GitShallowTarballNamingTest, self).setUp() self.recipe_url = "git://git.openembedded.org/bitbake" self.recipe_tarball = "gitshallow_git.openembedded.org.bitbake_82ea737-1_master.tar.gz" - self.mirror_url = "git://github.com/openembedded/bitbake.git" + self.mirror_url = "git://github.com/openembedded/bitbake.git;protocol=https" self.mirror_tarball = "gitshallow_github.com.openembedded.bitbake.git_82ea737-1_master.tar.gz" self.d.setVar('BB_GIT_SHALLOW', '1') @@ -875,17 +880,25 @@ class FetcherNetworkTest(FetcherTest): @skipIfNoNetwork() def test_fetch_premirror_specify_downloadfilename_regex_uri(self): self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake/") - fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz;downloadfilename=bitbake-v1.0.0.tar.gz"], self.d) + fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) fetcher.download() - self.assertEqual(os.path.getsize(self.dldir + "/bitbake-v1.0.0.tar.gz"), 57749) + self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) @skipIfNoNetwork() # BZ13039 def test_fetch_premirror_specify_downloadfilename_specific_uri(self): self.d.setVar("PREMIRRORS", "http://invalid.yoctoproject.org/releases/bitbake https://downloads.yoctoproject.org/releases/bitbake") - fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.0.tar.gz;downloadfilename=bitbake-v1.0.0.tar.gz"], self.d) + fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/1.0.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) fetcher.download() - self.assertEqual(os.path.getsize(self.dldir + "/bitbake-v1.0.0.tar.gz"), 57749) + self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) + + @skipIfNoNetwork() + def test_fetch_premirror_use_downloadfilename_to_fetch(self): + # Ensure downloadfilename is used when fetching from premirror. + self.d.setVar("PREMIRRORS", "http://.*/.* https://downloads.yoctoproject.org/releases/bitbake") + fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/releases/bitbake/bitbake-1.1.tar.gz;downloadfilename=bitbake-1.0.tar.gz"], self.d) + fetcher.download() + self.assertEqual(os.path.getsize(self.dldir + "/bitbake-1.0.tar.gz"), 57749) @skipIfNoNetwork() def gitfetcher(self, url1, url2): @@ -996,7 +1009,7 @@ class FetcherNetworkTest(FetcherTest): def test_git_submodule_dbus_broker(self): # The following external repositories have show failures in fetch and unpack operations # We want to avoid regressions! - url = "gitsm://github.com/bus1/dbus-broker;protocol=git;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main" + url = "gitsm://github.com/bus1/dbus-broker;protocol=https;rev=fc874afa0992d0c75ec25acb43d344679f0ee7d2;branch=main" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # Previous cwd has been deleted @@ -1012,7 +1025,7 @@ class FetcherNetworkTest(FetcherTest): @skipIfNoNetwork() def test_git_submodule_CLI11(self): - url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf" + url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf;branch=main" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # Previous cwd has been deleted @@ -1027,12 +1040,12 @@ class FetcherNetworkTest(FetcherTest): @skipIfNoNetwork() def test_git_submodule_update_CLI11(self): """ Prevent regression on update detection not finding missing submodule, or modules without needed commits """ - url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714" + url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714;branch=main" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # CLI11 that pulls in a newer nlohmann-json - url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca" + url = "gitsm://github.com/CLIUtils/CLI11;protocol=https;rev=49ac989a9527ee9bb496de9ded7b4872c2e0e5ca;branch=main" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # Previous cwd has been deleted @@ -1046,7 +1059,7 @@ class FetcherNetworkTest(FetcherTest): @skipIfNoNetwork() def test_git_submodule_aktualizr(self): - url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=git;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44" + url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=https;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # Previous cwd has been deleted @@ -1066,7 +1079,7 @@ class FetcherNetworkTest(FetcherTest): """ Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """ # This repository also has submodules where the module (name), path and url do not align - url = "gitsm://github.com/azure/iotedge.git;protocol=git;rev=d76e0316c6f324345d77c48a83ce836d09392699" + url = "gitsm://github.com/azure/iotedge.git;protocol=https;rev=d76e0316c6f324345d77c48a83ce836d09392699;branch=main" fetcher = bb.fetch.Fetch([url], self.d) fetcher.download() # Previous cwd has been deleted @@ -1124,7 +1137,7 @@ class SVNTest(FetcherTest): bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir) # Github will emulate SVN. Use this to check if we're downloding... - bb.process.run("svn propset svn:externals 'bitbake svn://vcs.pcre.org/pcre2/code' .", + bb.process.run("svn propset svn:externals 'bitbake https://github.com/PhilipHazel/pcre2.git' .", cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) bb.process.run("svn commit --non-interactive -m 'Add external'", cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk')) @@ -1242,7 +1255,7 @@ class FetchLatestVersionTest(FetcherTest): test_git_uris = { # version pattern "X.Y.Z" - ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4", "9b1db6b8060bd00b121a692f942404a24ae2960f", "") + ("mx-1.0", "git://github.com/clutter-project/mx.git;branch=mx-1.4;protocol=https", "9b1db6b8060bd00b121a692f942404a24ae2960f", "") : "1.99.4", # version pattern "vX.Y" # mirror of git.infradead.org since network issues interfered with testing @@ -1269,9 +1282,9 @@ class FetchLatestVersionTest(FetcherTest): : "0.4.3", ("build-appliance-image", "git://git.yoctoproject.org/poky", "b37dd451a52622d5b570183a81583cc34c2ff555", r"(?P<pver>(([0-9][\.|_]?)+[0-9]))") : "11.0.0", - ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot", "cd437ecbd8986c894442f8fce1e0061e20f04dee", r"chkconfig\-(?P<pver>((\d+[\.\-_]*)+))") + ("chkconfig-alternatives-native", "git://github.com/kergoth/chkconfig;branch=sysroot;protocol=https", "cd437ecbd8986c894442f8fce1e0061e20f04dee", r"chkconfig\-(?P<pver>((\d+[\.\-_]*)+))") : "1.3.59", - ("remake", "git://github.com/rocky/remake.git", "f05508e521987c8494c92d9c2871aec46307d51d", r"(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))") + ("remake", "git://github.com/rocky/remake.git;protocol=https", "f05508e521987c8494c92d9c2871aec46307d51d", r"(?P<pver>(\d+\.(\d+\.)*\d*(\+dbg\d+(\.\d+)*)*))") : "3.82+dbg0.9", } @@ -1365,9 +1378,6 @@ class FetchCheckStatusTest(FetcherTest): "https://downloads.yoctoproject.org/releases/opkg/opkg-0.1.7.tar.gz", "https://downloads.yoctoproject.org/releases/opkg/opkg-0.3.0.tar.gz", "ftp://sourceware.org/pub/libffi/libffi-1.20.tar.gz", - "http://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz", - "https://ftp.gnu.org/gnu/chess/gnuchess-5.08.tar.gz", - "https://ftp.gnu.org/gnu/gmp/gmp-4.0.tar.gz", # GitHub releases are hosted on Amazon S3, which doesn't support HEAD "https://github.com/kergoth/tslib/releases/download/1.1/tslib-1.1.tar.xz" ] @@ -2058,7 +2068,7 @@ class GitShallowTest(FetcherTest): @skipIfNoNetwork() def test_bitbake(self): - self.git('remote add --mirror=fetch origin git://github.com/openembedded/bitbake', cwd=self.srcdir) + self.git('remote add --mirror=fetch origin https://github.com/openembedded/bitbake', cwd=self.srcdir) self.git('config core.bare true', cwd=self.srcdir) self.git('fetch', cwd=self.srcdir) diff --git a/lib/bb/tests/runqueue.py b/lib/bb/tests/runqueue.py index 3d51779d6..4f335b8f1 100644 --- a/lib/bb/tests/runqueue.py +++ b/lib/bb/tests/runqueue.py @@ -361,7 +361,7 @@ class RunQueueTests(unittest.TestCase): def shutdown(self, tempdir): # Wait for the hashserve socket to disappear else we'll see races with the tempdir cleanup - while os.path.exists(tempdir + "/hashserve.sock"): + while (os.path.exists(tempdir + "/hashserve.sock") or os.path.exists(tempdir + "cache/hashserv.db-wal")): time.sleep(0.5) diff --git a/lib/bb/ui/knotty.py b/lib/bb/ui/knotty.py index 484545a68..3ba5579ca 100644 --- a/lib/bb/ui/knotty.py +++ b/lib/bb/ui/knotty.py @@ -228,7 +228,9 @@ class TerminalFilter(object): def keepAlive(self, t): if not self.cuu: - print("Bitbake still alive (%ds)" % t) + print("Bitbake still alive (no events for %ds). Active tasks:" % t) + for t in self.helper.running_tasks: + print(t) sys.stdout.flush() def updateFooter(self): @@ -605,7 +607,8 @@ def main(server, eventHandler, params, tf = TerminalFilter): warnings = 0 taskfailures = [] - printinterval = 5000 + printintervaldelta = 10 * 60 # 10 minutes + printinterval = printintervaldelta lastprint = time.time() termfilter = tf(main, helper, console_handlers, params.options.quiet) @@ -615,7 +618,7 @@ def main(server, eventHandler, params, tf = TerminalFilter): try: if (lastprint + printinterval) <= time.time(): termfilter.keepAlive(printinterval) - printinterval += 5000 + printinterval += printintervaldelta event = eventHandler.waitEvent(0) if event is None: if main.shutdown > 1: @@ -646,7 +649,7 @@ def main(server, eventHandler, params, tf = TerminalFilter): if isinstance(event, logging.LogRecord): lastprint = time.time() - printinterval = 5000 + printinterval = printintervaldelta if event.levelno >= bb.msg.BBLogFormatter.ERROR: errors = errors + 1 return_value = 1 diff --git a/lib/bb/utils.py b/lib/bb/utils.py index 70634910f..cd442dcd0 100644 --- a/lib/bb/utils.py +++ b/lib/bb/utils.py @@ -16,7 +16,8 @@ import bb.msg import multiprocessing import fcntl import importlib -from importlib import machinery +import importlib.machinery +import importlib.util import itertools import subprocess import glob @@ -400,7 +401,7 @@ def better_exec(code, context, text = None, realfile = "<code>", pythonexception code = better_compile(code, realfile, realfile) try: exec(code, get_context(), context) - except (bb.BBHandledException, bb.parse.SkipRecipe, bb.data_smart.ExpansionError): + except (bb.BBHandledException, bb.parse.SkipRecipe, bb.data_smart.ExpansionError, bb.process.ExecutionError): # Error already shown so passthrough, no need for traceback raise except Exception as e: @@ -451,6 +452,10 @@ def lockfile(name, shared=False, retry=True, block=False): consider the possibility of sending a signal to the process to break out - at which point you want block=True rather than retry=True. """ + if len(name) > 255: + root, ext = os.path.splitext(name) + name = root[:255 - len(ext)] + ext + dirname = os.path.dirname(name) mkdirhier(dirname) @@ -487,7 +492,7 @@ def lockfile(name, shared=False, retry=True, block=False): return lf lf.close() except OSError as e: - if e.errno == errno.EACCES: + if e.errno == errno.EACCES or e.errno == errno.ENAMETOOLONG: logger.error("Unable to acquire lock '%s', %s", e.strerror, name) sys.exit(1) @@ -1616,7 +1621,9 @@ def load_plugins(logger, plugins, pluginpath): logger.debug('Loading plugin %s' % name) spec = importlib.machinery.PathFinder.find_spec(name, path=[pluginpath] ) if spec: - return spec.loader.load_module() + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod logger.debug('Loading plugins from %s...' % pluginpath) diff --git a/lib/pyinotify.py b/lib/pyinotify.py index 6ae40a2d7..8c94b3e33 100644 --- a/lib/pyinotify.py +++ b/lib/pyinotify.py @@ -52,7 +52,6 @@ from collections import deque from datetime import datetime, timedelta import time import re -import asyncore import glob import locale import subprocess @@ -1475,35 +1474,6 @@ class ThreadedNotifier(threading.Thread, Notifier): self.loop() -class AsyncNotifier(asyncore.file_dispatcher, Notifier): - """ - This notifier inherits from asyncore.file_dispatcher in order to be able to - use pyinotify along with the asyncore framework. - - """ - def __init__(self, watch_manager, default_proc_fun=None, read_freq=0, - threshold=0, timeout=None, channel_map=None): - """ - Initializes the async notifier. The only additional parameter is - 'channel_map' which is the optional asyncore private map. See - Notifier class for the meaning of the others parameters. - - """ - Notifier.__init__(self, watch_manager, default_proc_fun, read_freq, - threshold, timeout) - asyncore.file_dispatcher.__init__(self, self._fd, channel_map) - - def handle_read(self): - """ - When asyncore tells us we can read from the fd, we proceed processing - events. This method can be overridden for handling a notification - differently. - - """ - self.read_events() - self.process_events() - - class TornadoAsyncNotifier(Notifier): """ Tornado ioloop adapter. diff --git a/lib/toaster/orm/fixtures/oe-core.xml b/lib/toaster/orm/fixtures/oe-core.xml index b01a33701..25543f6ec 100644 --- a/lib/toaster/orm/fixtures/oe-core.xml +++ b/lib/toaster/orm/fixtures/oe-core.xml @@ -23,9 +23,14 @@ <field type="CharField" name="branch">master</field> </object> <object model="orm.bitbakeversion" pk="4"> - <field type="CharField" name="name">gatesgarth</field> + <field type="CharField" name="name">hardknott</field> <field type="CharField" name="giturl">git://git.openembedded.org/bitbake</field> - <field type="CharField" name="branch">1.48</field> + <field type="CharField" name="branch">1.50</field> + </object> + <object model="orm.bitbakeversion" pk="5"> + <field type="CharField" name="name">honister</field> + <field type="CharField" name="giturl">git://git.openembedded.org/bitbake</field> + <field type="CharField" name="branch">1.52</field> </object> <!-- Releases available --> @@ -51,11 +56,18 @@ <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href=\"https://cgit.openembedded.org/openembedded-core/log/\">OpenEmbedded master</a> branch.</field> </object> <object model="orm.release" pk="4"> - <field type="CharField" name="name">gatesgarth</field> - <field type="CharField" name="description">Openembedded Gatesgarth</field> + <field type="CharField" name="name">hardknott</field> + <field type="CharField" name="description">Openembedded Hardknott</field> <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">4</field> - <field type="CharField" name="branch_name">gatesgarth</field> - <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href=\"https://cgit.openembedded.org/openembedded-core/log/?h=gatesgarth\">OpenEmbedded Gatesgarth</a> branch.</field> + <field type="CharField" name="branch_name">hardknott</field> + <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href=\"https://cgit.openembedded.org/openembedded-core/log/?h=hardknott\">OpenEmbedded Hardknott</a> branch.</field> + </object> + <object model="orm.release" pk="5"> + <field type="CharField" name="name">honister</field> + <field type="CharField" name="description">Openembedded Honister</field> + <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">5</field> + <field type="CharField" name="branch_name">honister</field> + <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href=\"https://cgit.openembedded.org/openembedded-core/log/?h=honister\">OpenEmbedded Honister</a> branch.</field> </object> <!-- Default layers for each release --> @@ -75,6 +87,10 @@ <field rel="ManyToOneRel" to="orm.release" name="release">4</field> <field type="CharField" name="layer_name">openembedded-core</field> </object> + <object model="orm.releasedefaultlayer" pk="5"> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="layer_name">openembedded-core</field> + </object> <!-- Layer for the Local release --> diff --git a/lib/toaster/orm/fixtures/poky.xml b/lib/toaster/orm/fixtures/poky.xml index 363789d62..5811cfae0 100644 --- a/lib/toaster/orm/fixtures/poky.xml +++ b/lib/toaster/orm/fixtures/poky.xml @@ -26,9 +26,15 @@ <field type="CharField" name="dirpath">bitbake</field> </object> <object model="orm.bitbakeversion" pk="4"> - <field type="CharField" name="name">gatesgarth</field> + <field type="CharField" name="name">hardknott</field> <field type="CharField" name="giturl">git://git.yoctoproject.org/poky</field> - <field type="CharField" name="branch">gatesgarth</field> + <field type="CharField" name="branch">hardknott</field> + <field type="CharField" name="dirpath">bitbake</field> + </object> + <object model="orm.bitbakeversion" pk="5"> + <field type="CharField" name="name">honister</field> + <field type="CharField" name="giturl">git://git.yoctoproject.org/poky</field> + <field type="CharField" name="branch">honister</field> <field type="CharField" name="dirpath">bitbake</field> </object> @@ -56,11 +62,18 @@ <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href="https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/">Yocto Project Master branch</a>.</field> </object> <object model="orm.release" pk="4"> - <field type="CharField" name="name">gatesgarth</field> - <field type="CharField" name="description">Yocto Project 3.2 "Gatesgarth"</field> + <field type="CharField" name="name">hardknott</field> + <field type="CharField" name="description">Yocto Project 3.3 "Hardknott"</field> <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">4</field> - <field type="CharField" name="branch_name">gatesgarth</field> - <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href="https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?h=gatesgarth">Yocto Project Gatesgarth branch</a>.</field> + <field type="CharField" name="branch_name">hardknott</field> + <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href="https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?h=hardknott">Yocto Project Hardknott branch</a>.</field> + </object> + <object model="orm.release" pk="5"> + <field type="CharField" name="name">honister</field> + <field type="CharField" name="description">Yocto Project 3.4 "Honister"</field> + <field rel="ManyToOneRel" to="orm.bitbakeversion" name="bitbake_version">5</field> + <field type="CharField" name="branch_name">honister</field> + <field type="TextField" name="helptext">Toaster will run your builds using the tip of the <a href="https://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?h=honister">Yocto Project Honister branch</a>.</field> </object> <!-- Default project layers for each release --> @@ -112,6 +125,18 @@ <field rel="ManyToOneRel" to="orm.release" name="release">4</field> <field type="CharField" name="layer_name">meta-yocto-bsp</field> </object> + <object model="orm.releasedefaultlayer" pk="13"> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="layer_name">openembedded-core</field> + </object> + <object model="orm.releasedefaultlayer" pk="14"> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="layer_name">meta-poky</field> + </object> + <object model="orm.releasedefaultlayer" pk="15"> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="layer_name">meta-yocto-bsp</field> + </object> <!-- Default layers provided by poky openembedded-core @@ -152,7 +177,14 @@ <field rel="ManyToOneRel" to="orm.layer" name="layer">1</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">4</field> - <field type="CharField" name="branch">gatesgarth</field> + <field type="CharField" name="branch">hardknott</field> + <field type="CharField" name="dirpath">meta</field> + </object> + <object model="orm.layer_version" pk="5"> + <field rel="ManyToOneRel" to="orm.layer" name="layer">1</field> + <field type="IntegerField" name="layer_source">0</field> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="branch">honister</field> <field type="CharField" name="dirpath">meta</field> </object> @@ -164,14 +196,14 @@ <field type="CharField" name="vcs_web_tree_base_url">https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%</field> <field type="CharField" name="vcs_web_file_base_url">https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%</field> </object> - <object model="orm.layer_version" pk="5"> + <object model="orm.layer_version" pk="6"> <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">1</field> <field type="CharField" name="branch">dunfell</field> <field type="CharField" name="dirpath">meta-poky</field> </object> - <object model="orm.layer_version" pk="6"> + <object model="orm.layer_version" pk="7"> <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">2</field> @@ -179,18 +211,25 @@ <field type="CharField" name="commit">HEAD</field> <field type="CharField" name="dirpath">meta-poky</field> </object> - <object model="orm.layer_version" pk="7"> + <object model="orm.layer_version" pk="8"> <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">3</field> <field type="CharField" name="branch">master</field> <field type="CharField" name="dirpath">meta-poky</field> </object> - <object model="orm.layer_version" pk="8"> + <object model="orm.layer_version" pk="9"> <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">4</field> - <field type="CharField" name="branch">gatesgarth</field> + <field type="CharField" name="branch">hardknott</field> + <field type="CharField" name="dirpath">meta-poky</field> + </object> + <object model="orm.layer_version" pk="10"> + <field rel="ManyToOneRel" to="orm.layer" name="layer">2</field> + <field type="IntegerField" name="layer_source">0</field> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="branch">honister</field> <field type="CharField" name="dirpath">meta-poky</field> </object> @@ -202,14 +241,14 @@ <field type="CharField" name="vcs_web_tree_base_url">https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%</field> <field type="CharField" name="vcs_web_file_base_url">https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/%path%?h=%branch%</field> </object> - <object model="orm.layer_version" pk="9"> + <object model="orm.layer_version" pk="11"> <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">1</field> <field type="CharField" name="branch">dunfell</field> <field type="CharField" name="dirpath">meta-yocto-bsp</field> </object> - <object model="orm.layer_version" pk="10"> + <object model="orm.layer_version" pk="12"> <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">2</field> @@ -217,18 +256,25 @@ <field type="CharField" name="commit">HEAD</field> <field type="CharField" name="dirpath">meta-yocto-bsp</field> </object> - <object model="orm.layer_version" pk="11"> + <object model="orm.layer_version" pk="13"> <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">3</field> <field type="CharField" name="branch">master</field> <field type="CharField" name="dirpath">meta-yocto-bsp</field> </object> - <object model="orm.layer_version" pk="12"> + <object model="orm.layer_version" pk="14"> <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field> <field type="IntegerField" name="layer_source">0</field> <field rel="ManyToOneRel" to="orm.release" name="release">4</field> - <field type="CharField" name="branch">gatesgarth</field> + <field type="CharField" name="branch">hardknott</field> + <field type="CharField" name="dirpath">meta-yocto-bsp</field> + </object> + <object model="orm.layer_version" pk="15"> + <field rel="ManyToOneRel" to="orm.layer" name="layer">3</field> + <field type="IntegerField" name="layer_source">0</field> + <field rel="ManyToOneRel" to="orm.release" name="release">5</field> + <field type="CharField" name="branch">honister</field> <field type="CharField" name="dirpath">meta-yocto-bsp</field> </object> </django-objects> diff --git a/lib/toaster/orm/fixtures/settings.xml b/lib/toaster/orm/fixtures/settings.xml index 78c0fdca7..ab3ea021f 100644 --- a/lib/toaster/orm/fixtures/settings.xml +++ b/lib/toaster/orm/fixtures/settings.xml @@ -19,7 +19,7 @@ <field type="CharField" name="value">${TOPDIR}/../sstate-cache</field> </object> <object model="orm.toastersetting" pk="6"> - <field type="CharField" name="name">DEFCONF_IMAGE_INSTALL_append</field> + <field type="CharField" name="name">DEFCONF_IMAGE_INSTALL:append</field> <field type="CharField" name="value"></field> </object> <object model="orm.toastersetting" pk="7"> diff --git a/lib/toaster/orm/models.py b/lib/toaster/orm/models.py index 4c94b407d..6d772367d 100644 --- a/lib/toaster/orm/models.py +++ b/lib/toaster/orm/models.py @@ -1717,7 +1717,7 @@ class CustomImageRecipe(Recipe): def generate_recipe_file_contents(self): """Generate the contents for the recipe file.""" - # If we have no excluded packages we only need to _append + # If we have no excluded packages we only need to :append if self.excludes_set.count() == 0: packages_conf = "IMAGE_INSTALL:append = \" " diff --git a/lib/toaster/toastergui/templates/projectconf.html b/lib/toaster/toastergui/templates/projectconf.html index bd49f1f58..c74adf0a7 100644 --- a/lib/toaster/toastergui/templates/projectconf.html +++ b/lib/toaster/toastergui/templates/projectconf.html @@ -73,7 +73,7 @@ {% if image_install_append_defined %} <dt> - <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL_append</span> + <span class="js-config-var-name js-config-var-managed-name">IMAGE_INSTALL:append</span> <span class="glyphicon glyphicon-question-sign get-help" title="Specifies additional packages to install into an image. If your build creates more than one image, the packages will be installed in all of them"></span> </dt> <dd class="variable-list"> @@ -83,7 +83,7 @@ <form id="change-image_install-form" class="form-inline" style="display:none;"> <div class="row"> <div class="col-md-4"> - <span class="help-block">To set IMAGE_INSTALL_append to more than one package, type the package names separated by a space.</span> + <span class="help-block">To set IMAGE_INSTALL:append to more than one package, type the package names separated by a space.</span> </div> </div> <div class="form-group"> @@ -771,10 +771,10 @@ $(document).ready(function() { {% if image_install_append_defined %} - // init IMAGE_INSTALL_append trash icon + // init IMAGE_INSTALL:append trash icon setDeleteTooltip($('#delete-image_install-icon')); - // change IMAGE_INSTALL_append variable + // change IMAGE_INSTALL:append variable $('#change-image_install-icon').click(function() { // preset the edit value var current_val = $("span#image_install").text().trim(); @@ -814,7 +814,7 @@ $(document).ready(function() { $('#apply-change-image_install').click(function(){ // insure these non-empty values have single space prefix var value = " " + $('#new-image_install').val().trim(); - postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+value}); + postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL:append:'+value}); $('#image_install').text(value); $('#image_install').removeClass('text-muted'); $("#change-image_install-form").slideUp(function () { @@ -826,10 +826,10 @@ $(document).ready(function() { }); }); - // delete IMAGE_INSTALL_append variable value + // delete IMAGE_INSTALL:append variable value $('#delete-image_install-icon').click(function(){ $(this).tooltip('hide'); - postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL_append:'+''}); + postEditAjaxRequest({"configvarChange" : 'IMAGE_INSTALL:append:'+''}); $('#image_install').parent().fadeOut(1000, function(){ $('#image_install').addClass('text-muted'); $('#image_install').text('Not set'); @@ -1011,7 +1011,7 @@ $(document).ready(function() { $(".save").attr("disabled","disabled"); // Reload page if admin-removed core managed value is manually added back in - if (0 <= " DISTRO DL_DIR IMAGE_FSTYPES IMAGE_INSTALL_append PACKAGE_CLASSES SSTATE_DIR ".indexOf( " "+variable+" " )) { + if (0 <= " DISTRO DL_DIR IMAGE_FSTYPES IMAGE_INSTALL:append PACKAGE_CLASSES SSTATE_DIR ".indexOf( " "+variable+" " )) { // delayed reload to avoid race condition with postEditAjaxRequest do_reload=true; } |