Compare commits

..

562 Commits
sumo ... fido

Author SHA1 Message Date
Daniel Lublin
8763191981 bitbake: lib/bs4: Fix imports from html5lib >= 0.9999999/1.0b8
As of html5lib 0.9999999/1.0b8 (released on July 14, 2016), some modules
have moved from _base to base. Handle this, while staying compatible
with earlier versions.

(Bitbake rev: edd90cd858da5da564e9849ebc0849a8a8173d4f)

Signed-off-by: Daniel Lublin <daniel@lublin.se>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2018-03-28 12:56:38 +01:00
Scott Rifenbark
ea6d21066a bitbake: bitbake-user-manual: Fixed porno hack for hello world example
Someone hacked the http://hambedded site or it was moved and some
links to that site in the BB manual had been hijacked to point to
an entry portal for a pornography site.  Replaced the link with an
archived version that restores the integrity of the links.

(Bitbake rev: e42c645955e972e75f979a33f26cc33ddd61315a)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2018-01-17 22:32:46 +00:00
Roy Li
c53ddb2006 systemd: re-enable mount propagation for udevd
With MountFlags=slave, those mounts then become private to the systemd-udevd
namespace and are no longer accessible from outside the namespace, which is
not expected

[YOCTO #8613]

(From OE-Core rev: 73f43d857fe0102033f25491007b6dbe3d5fa8ee)

(From OE-Core rev: f9c35dfc6601901664dbef2cba3a9b96bef96e64)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit f2092e67ea)
Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-12-05 17:21:36 +00:00
Richard Purdie
c9f0a99050 build-appliance-image: Update to fido head revision
(From OE-Core rev: 511ea0fcc9c238ad8e3b3089ec2bcf82bb1ecc77)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-12 13:14:51 +01:00
Joshua Lock
e6b06016bc openssl: prevent ABI break from earlier fido releases
The backported upgrade to 1.0.2h included an updated GNU LD
version-script which results in an ABI change. In order to try and
respect ABI for existing binaries built against fido this commit
partially reverts the version-script to maintain the existing ABI
and instead only add the new symbols required by 1.0.2h.

Suggested-by: Martin Jansa <martin.jansa@gmail.com>
(From OE-Core rev: 480db6be99f9a53d8657b31b846f0079ee1a124f)

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-12 13:14:42 +01:00
Ross Burton
740a2d817a conf/local.conf.sample: comment out ASSUME_PROVIDED=libsdl-native
Ubuntu 15.10 and Debian testing can't build qemu-native against the host libsdl.
Now that libsdl-native is buildable, comment out the ASSUME_PROVIDED which meant
it wouldn't be used.

[ YOCTO #8553 ]

(From meta-yocto master rev: 759accbfca46de058ce402938713189dab22a70c)

(From meta-yocto rev: aa4ad74c23b283f545a0f9f1ee57635fbe1a1dc6)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-12 10:59:11 +01:00
Richard Purdie
5aed3ebfc1 build-appliance-image: Update to fido head revision
(From OE-Core rev: e7c46ce3e59cb4fd770e76ae006c0166d0dd5265)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-11 18:00:19 +01:00
Robert Yang
3cea047b6c openssl: 1.0.2d -> 1.0.2h (mainly for CVEs)
* CVEs:
  - CVE-2016-0705
  - CVE-2016-0798
  - CVE-2016-0797
  - CVE-2016-0799
  - CVE-2016-0702
  - CVE-2016-0703
  - CVE-2016-0704
  - CVE-2016-2105
  - CVE-2016-2106
  - CVE-2016-2109
  - CVE-2016-2176

* The LICENSE's checksum is changed because of date changes (2011 ->
  2016), the contents are the same.

* Remove backport patches
  - 0001-Add-test-for-CVE-2015-3194.patch
  - CVE-2015-3193-bn-asm-x86_64-mont5.pl-fix-carry-propagating-bug-CVE.patch
  - CVE-2015-3194-1-Add-PSS-parameter-check.patch
  - CVE-2015-3195-Fix-leak-with-ASN.1-combine.patch
  - CVE-2015-3197.patch
  - CVE-2016-0701_1.patch
  - CVE-2016-0701_2.patch
  - CVE-2016-0800.patch
  - CVE-2016-0800_2.patch
  - CVE-2016-0800_3.patch

* Update crypto_use_bigint_in_x86-64_perl.patch

* Add version-script.patch and update block_diginotar.patch (From master branch)

* Update openssl-avoid-NULL-pointer-dereference-in-EVP_DigestInit_ex.patch
  (From Armin)

(From OE-Core master rev: bca156013af0a98cb18d8156626b9acc8f9883e3)

(From OE-Core rev: 6ed7c8a9f82bc173ae0cc8b494af5a2c838f08fc)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-11 18:00:11 +01:00
Paul Eggleton
8463c06290 bitbake: tests/fetch: ensure fetch tests preserve current dir
The fetcher calls os.chdir() in a number of places, which can affect
other tests (since the directory it changes into gets deleted) - let's
just put the current directory back to where it was when we're done.

(This fixes bb.tests.Path.test_unsafe_delete_path failing if it was run
as part of a full bitbake-selftest run, where the fetcher tests get to
run before it.)

(Bitbake rev: fdb6c123593fd2255b9b09e6bdf7306d64a82892)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 11:10:58 +01:00
Richard Purdie
4d03d1880f bitbake: bb/tests/fetch: Update cups url
Update the upstream url used for testing cups versions after upstream website
changes.

(Bitbake rev: 27ae1b39c400cf7edbd6902ff050a39147d64217)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 11:10:58 +01:00
Joshua Lock
9b9b8285be gtk+_2.24.25: backport a fix for building with newer host perl
This backports a patch from gtk+ upstream to prevent an issue when
building on Fedora 23 hosts.

(From OE-Core rev: fd27f8620ae4d95dfe07b27eee4256b0a128348a)

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
3a4d269d39 tzdata: update to 2016d
Changes affecting future time stamps

America/Caracas switches from -0430 to -04 on 2016-05-01 at 02:30.
(Thanks to Alexander Krivenyshev for the heads-up.)

Asia/Magadan switches from +10 to +11 on 2016-04-24 at 02:00.
(Thanks to Alexander Krivenyshev and Matt Johnson.)

New zone Asia/Tomsk, split off from Asia/Novosibirsk. It covers
Tomsk Oblast, Russia, which switches from +06 to +07 on 2016-05-29
at 02:00.  (Thanks to Stepan Golosunov.)

Changes affecting past time stamps

New zone Europe/Kirov, split off from Europe/Volgograd.  It covers
Kirov Oblast, Russia, which switched from +04/+05 to +03/+04 on
1989-03-26 at 02:00, roughly a year after Europe/Volgograd made
the same change.  (Thanks to Stepan Golosunov.)

Russia and nearby locations had daylight-saving transitions on
1992-03-29 at 02:00 and 1992-09-27 at 03:00, instead of on
1992-03-28 at 23:00 and 1992-09-26 at 23:00.  (Thanks to Stepan
Golosunov.)

Many corrections to historical time in Kazakhstan from 1991
through 2005.  (Thanks to Stepan Golosunov.)  Replace Kazakhstan's
invented time zone abbreviations with numeric abbreviations.

(From OE-Core rev: 80936e6c259923e19331678ca2f8aa40b79da5c2)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>

(From OE-Core master rev: 10194ca3d8c2f4d8648a685c5c239a33d944b6fe)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
e09c0fae90 tzcode: update to 2016d
they keep the versions in-sync. changes are all in data.

Changes affecting future time stamps

America/Caracas switches from -0430 to -04 on 2016-05-01 at 02:30.
(Thanks to Alexander Krivenyshev for the heads-up.)

Asia/Magadan switches from +10 to +11 on 2016-04-24 at 02:00.
(Thanks to Alexander Krivenyshev and Matt Johnson.)

New zone Asia/Tomsk, split off from Asia/Novosibirsk. It covers
Tomsk Oblast, Russia, which switches from +06 to +07 on 2016-05-29
at 02:00.  (Thanks to Stepan Golosunov.)

Changes affecting past time stamps

New zone Europe/Kirov, split off from Europe/Volgograd.  It covers
Kirov Oblast, Russia, which switched from +04/+05 to +03/+04 on
1989-03-26 at 02:00, roughly a year after Europe/Volgograd made
the same change.  (Thanks to Stepan Golosunov.)

Russia and nearby locations had daylight-saving transitions on
1992-03-29 at 02:00 and 1992-09-27 at 03:00, instead of on
1992-03-28 at 23:00 and 1992-09-26 at 23:00.  (Thanks to Stepan
Golosunov.)

Many corrections to historical time in Kazakhstan from 1991
through 2005.  (Thanks to Stepan Golosunov.)  Replace Kazakhstan's
invented time zone abbreviations with numeric abbreviations.

(From OE-Core rev: a17a81991a10d6c61def5eb81687f57fc7ad87b0)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>

(From OE-Core master rev: db8223e4dd2e513a656aedfae217d94e053c2366)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
3167b4de2a tzcode: update to 2016c
(From OE-Core rev: 2dd4085180b5fca144b0e0b5ef149e291e796bf0)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: 41adb87c2f1aa20e51f1af3542d65c920eb94be6)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
dc77e99b27 tzdata: update to 2016c
The 2016c release of the tz code and data is available. Its most urgent change is for Asia/Baku, where the update takes effect this weekend.

This release reflects the following changes, which were either circulated on the tz mailing list or are relatively minor technical or administrative changes:

Changes affecting future time stamps

Azerbaijan no longer observes DST.  (Thanks to Steffen Thorsen.)

Chile reverts from permanent to seasonal DST.  (Thanks to Juan
Correa for the heads-up, and to Tim Parenti for corrections.)
Guess that future transitions are August's and May's second
Saturdays at 24:00 mainland time.  Also, call the period from
2014-09-07 through 2016-05-14 daylight saving time instead of
standard time, as that seems more appropriate now.

Changes affecting past time stamps

Europe/Kaliningrad and Europe/Vilnius changed from +03/+04 to
+02/+03 on 1989-03-26, not 1991-03-31.  Europe/Volgograd changed
from +04/+05 to +03/+04 on 1988-03-27, not 1989-03-26.
(Thanks to Stepan Golosunov.)

Changes to commentary
Several updates and URLs for historical and proposed Russian changes.
(Thanks to Stepan Golosunov, Matt Johnson, and Alexander Krivenyshev.)

(From OE-Core rev: 770f1769df2930fdc57a3a7427b18e9b6ebe9dda)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: 66031bcf8cec2e8e7a6803f2c6cfc2c2ba071ffe)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
45e2a649ee tzcode: update to 2016b
change SRC_URI http seems more reliable

Changes to code

     tzselect's diagnostics and checking, and checktab.awk's checking,
     have been improved.  (Thanks to J William Piggott.)

     tzcode now builds under MinGW.  (Thanks to Ian Abbott and Esben Haabendal.)

     tzselect now tests Julian-date TZ settings more accurately.
     (Thanks to J William Piggott.)

Changes to commentary

     Comments in zone tables have been improved.  (Thanks to J William Piggott.)

     tzselect again limits its menu comments so that menus fit on a
     24x80 alphanumeric display.

     A new web page tz-how-to.html.  (Thanks to Bill Seymour.)

     In the Theory file, the description of possible time zone abbreviations in
     tzdata has been cleaned up, as the old description was unclear and
     inconsistent.  (Thanks to Alain Mouette for reporting the problem.)

(From OE-Core rev: 8598455b372931e88d4936f0ec0313540ec602a0)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: 0c4816c1f723951179988a274f236f28fe4db20f)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Armin Kuster
459a661ff5 tzdata: update to 2016b
updated SRC_URI to http as it seems more stable.

Changes affecting future time stamps

     New zones Europe/Astrakhan and Europe/Ulyanovsk for Astrakhan and
     Ulyanovsk Oblasts, Russia, both of which will switch from +03 to +04 on
     2016-03-27 at 02:00 local time.  They need distinct zones since their
     post-1970 histories disagree.  New zone Asia/Barnaul for Altai Krai and
     Altai Republic, Russia, which will switch from +06 to +07 on the same date
     and local time.  Also, Asia/Sakhalin moves from +10 to +11 on 2016-03-27
     at 02:00.  (Thanks to Alexander Krivenyshev for the heads-up, and to
     Matt Johnson and Stepan Golosunov for followup.)

     As a trial of a new system that needs less information to be made up,
     the new zones use numeric time zone abbreviations like "+04"
     instead of invented abbreviations like "ASTT".

     Haiti will not observe DST in 2016.  (Thanks to Jean Antoine via
     Steffen Thorsen.)

     Palestine's spring-forward transition on 2016-03-26 is at 01:00, not 00:00.
     (Thanks to Hannah Kreitem.) Guess future transitions will be March's last
     Saturday at 01:00, not March's last Friday at 24:00.

Changes affecting past time stamps

     Europe/Chisinau observed DST during 1990, and switched from +04 to
     +03 at 1990-05-06 02:00, instead of switching from +03 to +02.
     (Thanks to Stepan Golosunov.)

     1991 abbreviations in Europe/Samara should be SAMT/SAMST, not
     KUYT/KUYST.  (Thanks to Stepan Golosunov.)

(From OE-Core rev: 55eb60c513ac0125e7fdb697d171e4c6ab8883f8)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: d3ab7005f0c899da9f9f132b22861bd5d4f952ba)

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Sona Sarmadi
a8ff4c8f42 bind: CVE-2016-1285 CVE-2016-1286
CVE-2016-1285 bind: malformed packet sent to rndc can trigger assertion failure
CVE-2016-1286 bind: malformed signature records for DNAME records can
trigger assertion failure

[YOCTO #9400]

External References:
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-1285
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-1286
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1285
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1286

References to the Upstream commits and Security Advisories:

CVE-2016-1285: https://kb.isc.org/article/AA-01352
https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=patch;
h=31e4657cf246e41d4c5c890315cb6cf89a0db25a

CVE-2016-1286_1: https://kb.isc.org/article/AA-01353
https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=patch;
h=76c3c9fe9f3f1353b47214b8f98b3d7f53e10bc7

CVE-2016-1286_2: https://kb.isc.org/article/AA-01353
https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=patch;
h=ce3cd91caee698cb144e1350c6c78292c6be6339

(From OE-Core rev: e289df4daa4b90fb95ae3602c244cba9d56a8c2f)

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Brad Mouring
0c49cef4a6 busybox_git: Fix SRCREV
The SRCREV in the busybox git recipe did not point to a commit ID
on the master branch. Point the variable to something reachable from
the master branch (which fixes this recipe's fetch()).

Suggested-by: Khem Raj <raj.khem@gmail.com>
(From OE-Core rev: b0720e996dde537d04a9129e7ffdc883836c3cf8)

Signed-off-by: Brad Mouring <brad.mouring@ni.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:34 +01:00
Brad Mouring
f5a7dd40ff busybox: Backport patch to fix zcip false-conflict
Busybox upstream fixed the issue where an incorrect comparison of
addresses led to bogus renegotiation of a new ll ip in 1.24. Backport
this change to 1.23.1.

(From OE-Core rev: 37f074eed40ec0e100066eeef16ff8af555e3301)

Signed-off-by: Brad Mouring <brad.mouring@ni.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Richard Purdie
1992a76b89 populate_sdk_base: Ensure PKGDATA_DIR exists
The code assumes that PKG_DATADIR exists and will fail if an image has not been
generated which creates it. This occurs when something like buildtools-tarball
is built which doesn't have target packages, only nativesdk ones.

Since this shouldn't be fatal, workaround this by creating the missing
directory.

(From OE-Core master rev: 319c5d55bb0c7e429766f46dd42a15e16a43c4dd)

(From OE-Core rev: d9ea863ff844ee1b84d4699b0d3af7245f3703c5)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Richard Purdie
5d677d7dba scripts/oe-pkgdata-util: Fix variable name in error handling
Fix:
    logger.error('Unable to find pkgdata directory %s' % pkgdata_dir)
NameError: global name 'pkgdata_dir' is not defined

(From OE-Core master rev: a1202ed17e11400f08064c9065fdfa996554d4ad)

(From OE-Core rev: af95fa33067542fe6f253d57b6dda575ceea5527)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Ross Burton
dd90a73c51 xorg-lib: allow native building without x11 DISTRO_FEATURES
The Xorg libraries use REQUIRED_DISTRO_FEATURES to stop building on
distributions without the x11 feature but this stops people building native
tooling that uses libX11, such as libsdl-native.

(From OE-Core master rev: 161bb3409edee21827cf594cc011fe88185f1496)

(From OE-Core rev: 16b2e5a5af9fadbfe85a9f66be2896d1c7c3b72d)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

libxcb change removed as it's not valid in fido
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Ross Burton
4a9e57795e base: check for existing prefix when expanding names in PACKAGECONFIG
When the DEPENDS are added as part of the PACKAGECONFIG logic the list of
packages are expanded so that any required nativesdk-/-native/multilib prefixes
and suffixes are added.

However the special handling of virtual/foo names doesn't check that the prefix
already exists, which breaks under nativesdk as in that situation there's an
explicit nativesdk- prefix *and* MLPREFIX is set to nativesdk-.  This results in
the same prefix being applied twice, and virtual packages such as virtual/libx11
ending up as virtual/nativesdk-nativesdk-libx11.

(From OE-Core master rev: 9e7d207e207bf0319b09d403d87d37f24e3dfbee)

(From OE-Core rev: af32a5d84e9aa300095ffb7d4626708e2f85e7a2)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Ross Burton
ad7ea213b2 libsdl: expand PACKAGECONFIG and enable native builds
Use PACKAGECONFIG instead of using logic in DEPENDS and EXTRA_OECONF, adding new
options for PulseAudio, tslib, DirectFB, OpenGL and X11.  Pass
--disable-x11-shared so that it links to the X libraries instead of using
dlopen().

Disable tslib by default as the kernel event input subsystem is generally used.

SDL's OpenGL support requires X11 so check for both x11 and opengl, and merge
the dependencies.

Finally enable native builds, with a minimal PACKAGECONFIG that will build from
oe-core for native and nativesdk.

(From OE-Core master rev: 3d6c31c3a4ff34376e17005a981bb55fc6f7a38f)

(From OE-Core rev: c1b39f145b9e9f65875ec7b46030327741267031)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Robert Yang
2851c970ca libsdl: depends on libglu when both x11 and opengl
The libglu requires both opengl (depends on virtual/libgl) and x11
(needs libGL.so which is provided by mesa when x11 in DISTRO_FEATURES),
so let libsdl depends on libglu when both x11 and opengl in
DISTRO_FEATURES.

(From OE-Core master rev: b33e927096292f22f1bd9b2b0f633a6d645fc1eb)

(From OE-Core rev: 45a6ae4cf6b2684ee7e58b8a85f44eb0031fa2b4)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Richard Purdie
fd394338ed testimage: Handle ipk/deb packaging format tests correctly
The default test list only works for rpm packaging. This fixes it for
deb and ipk too.

(From OE-Core master rev: 210c8926405fcf695ec00f5768f29ba198320d6a)

(From OE-Core rev: 961a9de0e918526bc8c880ea1d35db16b55f500a)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Mariano Lopez
dad3b97a9a dhcp: CVE-2015-8605
ISC DHCP allows remote attackers to cause a denial of
service (application crash) via an invalid length field
in a UDP IPv4 packet.

(From OE-Core rev: 43f2cfdf63fb70e3c2da0224221dae63b05477df)

Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-05-09 08:11:33 +01:00
Richard Purdie
900d7d6b59 build-appliance-image: Update to fido head revision
(From OE-Core rev: 1ebf604cae8d9bd3d2c10d06cd126e79e13732ee)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-13 10:52:43 +00:00
Richard Purdie
3d61b942f7 poky.conf: Bump version for 1.8.2 fido release
(From meta-yocto rev: 16d067de9a9682e93b30726b74078a1c4366a015)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-13 10:52:11 +00:00
Richard Purdie
a4f91cb18b build-appliance-image: Update to fido head revision
(From OE-Core rev: aba91bb6e2b748f05051bf824531e4f283eb5f09)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-12 15:15:52 +00:00
Scott Rifenbark
bf9e5d6ef6 documentation: Final bits for the 1.8.2 manual set
Changes include:

 * Updating all the Manual revision history tables for 1.8.2
 * Updating the poky.ent file with new variable values for 1.8.2
 * Updating the mega-manual.sed file so good links are generated
   for the mega-manual

(From yocto-docs rev: d77321f4bef95c48d1df8b671418ebb4fa68bd66)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-11 23:05:50 +00:00
ngutzmann
be0c978fa1 nettle: The variable named p in the patch file was incorrectly named.
The variable in question should have been called ecc->p. The patch has been
updated so that the compilation of the nettle recipe would complete
successfully. The backport originated from this commit

c71d2c9d20

(From OE-Core rev: 7f4d3b90840a14d660a56d23e1fe79f4fb633d59)

Signed-off-by: ngutzmann <nathangutzmann@gmail.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-11 10:56:02 +00:00
Armin Kuster
dbb46510cc openssl: Security fix CVE-2016-0800
CVE-2016-0800 SSL/TLS: Cross-protocol attack on TLS using SSLv2 (DROWN)

https://www.openssl.org/news/secadv/20160301.txt

(From OE-Core rev: 6c06c42594539bec4c360c8cc28ebee8a338e6b4)

Signed-off-by: Armin Kuster <akuster@mvista.com>

Not required for master, an update to 1.0.2g has been submitted.
Backport from jethro.
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Hongxu Jia
7d663e9c47 wpa-supplicant: Fix CVE-2015-8041
Backport patch from http://w1.fi/security/2015-5/
and rebase for wpa-supplicant 2.4

(From OE-Core rev: 12520d7f729fe3d07c2f94b813994718edb2d987)

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>

Not needed in master since the upgrade to 2.5
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
f98b8b767d git: Security fixes CVE-2015-7545
CVE-2015-7545 git: arbitrary code execution via crafted URLs

(From OE-Core rev: 0c4bdd61acbc1fa1b9bfb167d8eaf90c8bccc25c)

Signed-off-by: Armin Kuster <akuster@mvista.com>

Already in Jethro, not needed in master due to shipping a version of git
which is already fixes (> 2.6.1)
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
3aa8ba185b nettle: Security fix CVE-2015-8804
(From OE-Core master rev: 7474c7dbf98c1a068bfd9b14627b604da5d79b67)

minor tweak to get x86_64/ecc-384-modp.asm to apply

(From OE-Core rev: d1903e264ab62d34daeb652c89c6fb67e7c9b42d)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
2250d4025b nettle: Security fix CVE-2015-8803 and CVE-2015-8805
(From OE-Core master rev: f62eb452244c3124cc88ef01c14116dac43f377a)

hand applied changes for ecc-256.c

(From OE-Core rev: cb03397ac97bfa99df6b72c80e1e03214e059e6e)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
12cdd6d2b3 bind: Security fix CVE-2015-8461
CVE-2015-8461 bind: race condition when handling socket errors can lead to an assertion failure in resolver.c\

(From OE-Core master rev: 1656eaa722952861ec73362776bd0c4826aec3da)

Hand applied Changelog changes.

(From OE-Core rev: 104d050d420ee4aa14b772850742699b15d127d6)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Li Zhou
d4b6c1657b rpcbind: Security Advisory - rpcbind - CVE-2015-7236
rpcbind: Fix memory corruption in PMAP_CALLIT code

Use-after-free vulnerability in xprt_set_caller in rpcb_svc_com.c in
rpcbind 0.2.1 and earlier allows remote attackers to cause a denial of
service (daemon crash) via crafted packets, involving a PMAP_CALLIT
code.

The patch comes from
<http://www.openwall.com/lists/oss-security/2015/09/18/7>, and it hasn't
been in rpcbind upstream yet.

(From OE-Core master rev: cc4f62f3627f3804907e8ff9c68d9321979df32b)

(From OE-Core rev: 224bcc2ead676600bcd9e290ed23d9b2ed2f481e)

(From OE-Core rev: 16cf2f5386bc438dc20c4ae40de267618e9dc500)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
854c2e724d curl: Secuirty fix CVE-2016-0755
CVE-2016-0755 curl: NTLM credentials not-checked for proxy connection re-use

(From OE-Core master rev: 8322814c7f657f572d5c986652e708d6bd774378)

hand applied changed to url.c

(From OE-Core rev: e479ec9e6cbd34f3a7a56a170aaabcc4229f1959)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
8ca73f8fa4 curl: Security fix CVE-2016-0754
CVE-2016-0754 curl: remote file name path traversal in curl tool for Windows

(From OE-Core master rev: b2c9b48dea2fd968c307a809ff95f2e686435222)

minor tweak to tool_operate.c to get it to apply

(From OE-Core rev: b8df558ece47e51653e1fc0fb0637ec2cdf2907b)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
d25973e203 libgcrypt: Security fix CVE-2015-7511
CVE-2015-7511 libgcrypt: side-channel attack on ECDH with Weierstrass curves

affects libgcrypt < 1.6.5

adjust SRC_URI + for this version.

Patch 1 is a dependancy patch. simple macro name change.
Patch 2 is the cve fix.

(From OE-Core master rev: c691ce99bd2d249d6fdc4ad58300719488fea12c)

(From OE-Core rev: 88ba5ea3f3a421ac91d670e450f4b0645a53d733)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
e1a2fb6e85 libpng: Security fix CVE-2015-8472
libpng: Buffer overflow vulnerabilities in png_get_PLTE/png_set_PLTE functions

this patch fixes an incomplete patch in CVE-2015-8126

adjusted dir to match this version.

(From OE-Core master rev: f4a805702df691cbd2b80aa5f75d6adfb0f145eb)

(From OE-Core rev: bed289a9ac39fb9b613e3075d5a062b24c59c956)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:40 +00:00
Armin Kuster
fbe015523f libpng: Security fix CVE-2015-8126
libpng: Buffer overflow vulnerabilities in png_get_PLTE/png_set_PLTE functions

Adjusted dir location to match the version.

(From OE-Core master rev: d0a8313a03711ff881ad89b6cfc545f66a0bc018)

(From OE-Core rev: 20a1f80f554c2dc9da414c5846fb5bafd73e2cac)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
2f9a715583 gdk-pixbuf: Security fix CVE-2015-7674
CVE-2015-7674 Heap overflow with a gif file in gdk-pixbuf < 2.32.1

(From OE-Core master rev: f2b16d0f9c3ad67fdf63e9e41f42a6d54f1043e4)

(From OE-Core rev: 50602eebe1150819c320b6b611dcd792573eb55a)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
d192c62891 librsvg: Security fix CVE-2015-7558
CVE-2015-7558 librsvg2: Stack exhaustion causing DoS

including two supporting patches.

(From OE-Core master rev: 4945643bab1ee6b844115cc747e5c67d874d5fe6)

(From OE-Core rev: 4e21caee47a0ca3e66e84a15d104d3b532731263)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
34c865c7ba tiff: Security fix CVE-2015-8784
CVE-2015-8784 libtiff: out-of-bound write in NeXTDecode()

(From OE-Core master rev: 3e89477c8ad980fabd13694fa72a0be2e354bbe2)
minor tweak to get tif_next.c changes to apply.

(From OE-Core rev: 645255274769bfaeb737f66a6222a9a929823160)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
d9a3e4a5cf tiff: Security fix CVE-2015-8781
CVE-2015-8781 libtiff: out-of-bounds writes for invalid images

(From OE-Core master rev: 29c80024bdb67477dae47d8fb903feda2efe75d4)

minor tweek to get Changelog changes to apply

(From OE-Core rev: fa7fac56be40fdb519d426e9465436415e3f5527)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
83af960b7d foomatic-filters: Security fixes CVE-2015-8327
CVE-2015-8327 cups-filters: foomatic-rip did not consider the back tick as an illegal shell escape character

this time with the recipe changes.

(From OE-Core master rev: 62d6876033476592a8ca35f4e563c996120a687b)

(From OE-Core rev: 9ca5534b1d8ce71eb150964e11ce79ba79ced7e4)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
9a6a7150d9 foomatic-filters: Security fix CVE-2015-8560
CVE-2015-8560 cups-filters: foomatic-rip did not consider semicolon as illegal shell escape character

(From OE-Core master rev: 307056ce062bf4063f6effeb4c891c82c949c053)

(From OE-Core rev: 4f92365ebfb382509d152dfe6220e225193645f1)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
37905e7663 qemu: Security fix CVE-2016-2198
CVE-2016-2198 Qemu: usb: ehci null pointer dereference in ehci_caps_write

(From OE-Core master rev: 646a8cfa5398a22062541ba9c98539180ba85d58)

(From OE-Core rev: 082031bdd4b5c5d4acea816c95d94a731b7855c2)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-03-03 11:11:39 +00:00
Armin Kuster
06d9c89463 libbsd: Security fix CVE-2016-2090
CVE-2016-2090 Heap buffer overflow in fgetwln function of libbsd

affects libbsd <= 0.8.1 (and therefore not needed in master)

(From OE-Core rev: ab29efb8e85020a3621079c7fde217c1bfaa5289)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-18 11:03:10 +00:00
Joshua Lock
d7be819eed glibc: Security fix CVE-2015-7547
CVE-2015-7547: getaddrinfo() stack-based buffer overflow

(Based on OE-Core rev: cf754c5c806307d6eb522d4272b3cd7485f82420)

(From OE-Core rev: ed6299ab0970d836d6719795531458078ba4cbf6)

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-18 11:03:10 +00:00
Markus Lehtonen
e6fca31dc0 kernel.bbclass: do not mv/link sources when externalsrc enabled
If externalsrc is enabled the 'do_unpack' task is run if the recipe has
some local source files. In the case of kernel recipe this caused the
(externalsrc) source tree to be moved/symlinked. This patch prevents the
behaviour, making sure the source tree is not moved around when
externalsrc is enabled. Instead of moving the source tree,
STAGING_KERNEL_DIR will be a symlink to it.

[YOCTO #6658]

(From OE-Core master rev: 8f6c564661a3801012eb2d9a98cdc99c91712367)

(From OE-Core rev: ca55a01908126c45120fc18e68e78f8f49ecf0ce)

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-16 15:16:55 +00:00
Armin Kuster
b213ada9a7 libpcre: Security fixes and package update.
this is related to [Yocto # 9008]

8.38:
The following security fixes are included:
CVE-2015-3210 pcre: heap buffer overflow in pcre_compile2()  compile_regex()
CVE-2015-3217 pcre: stack overflow in match()
CVE-2015-5073 CVE-2015-8388 pcre: Buffer overflow caused by certain patterns with an unmatched closing parenthesis
CVE-2015-8380 pcre: Heap-based buffer overflow in pcre_exec
CVE-2015-8381 pcre: Heap Overflow in compile_regex()
CVE-2015-8383 pcre: Buffer overflow caused by repeated conditional group
CVE-2015-8384 pcre: Buffer overflow caused by recursive back reference by name within certain group
CVE-2015-8385 pcre: Buffer overflow caused by forward reference by name to certain group
CVE-2015-8386 pcre: Buffer overflow caused by lookbehind assertion
CVE-2015-8387 pcre: Integer overflow in subroutine calls
CVE-2015-8389 pcre: Infinite recursion in JIT compiler when processing certain patterns
CVE-2015-8390 pcre: Reading from uninitialized memory when processing certain patterns
CVE-2015-8392 pcre: Buffer overflow caused by certain patterns with duplicated named groups
CVE-2015-8393 pcre: Information leak when running pcgrep -q on crafted binary
CVE-2015-8394 pcre: Integer overflow caused by missing check for certain conditions
CVE-2015-8395 pcre: Buffer overflow caused by certain references
CVE-2016-1283 pcre: Heap buffer overflow in pcre_compile2 causes DoS

8.37:
The following security fixes are included:
CVE-2014-8964 pcre: incorrect handling of zero-repeat assertion conditions
CVE-2015-2325 pcre: heap buffer overflow in compile_branch()
CVE-2015-2326 pcre: heap buffer overflow in pcre_compile2()

LICENSE file changed do to Copyright date updates.

(From OE-Core rev: 3bbd53035fb62793f1e44b24b18eb275bd860ed1)

Signed-off-by: Armin Kuster <akuster@mvista.com>

Jethro and master don't require this patch as they have newer libpcre which
contains these fixes.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-16 15:16:55 +00:00
Martin Jansa
2f1fc8c899 tzdata: remove 2015d version
* this is left-over from upgrade to 2016a

* it's safer to remove so that .bbappends in other layers really apply to version
  used in build (currently we have bbappend for 2015d and build will use 2016a
  without any warning

* the same problem was reported with 2015f upgrade:
  http://lists.openembedded.org/pipermail/openembedded-core/2015-August/109708.html

(From OE-Core rev: 6b0f0ed6b9ffc3e81b04cf442645130bb41b7ee9)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>

Not required by other branches as this is removing a leftover file in Fido
only.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-16 15:16:54 +00:00
Mariano Lopez
c94eb07d53 rpmresolve.c: Fix unfreed pointers that keep DB opened
There are some unfreed rpmmi pointers in printDepList()
function; this happens when the package have null as
the requirement.

This patch fixes these unfreed pointers and add small
changes to keep consistency with some variables.

[YOCTO #8028]

(From OE-Core master rev: da7aa183f94adc1d0fff5bb81e827c584f9938ec)

(From OE-Core rev: 8821b0443b4b39b3bd4f41800a6fc809197fda82)

Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-16 15:16:54 +00:00
Armin Kuster
528bdf528d dpkg: Security fix CVE-2015-0860
CVE-2015-0860 dpkg: stack overflows and out of bounds read

(From OE-Core rev: 5aaec01acc9e5a19374a566307a425d43c887f4b)

(From OE-Core rev: 4dea3e7b9a0041e7359981e68c561e7de8ad3ae5)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:06 +00:00
Armin Kuster
db99f58eea bind: Security fix CVE-2015-8704
CVE-2015-8704 bind: specific APL data could trigger an INSIST in apl_42.c

(From OE-Core rev: 600c1d2beb64e23123e478051537b917f5d4a8a7)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:06 +00:00
Armin Kuster
092903a2ef libxml2: Security fix CVE-2015-8710
CVE-2015-8710 libxml2: out-of-bounds memory access when parsing an unclosed HTML comment

(From OE-Core rev: 03d481070ebc6f9af799aec5d038871f9c73901c)

(From OE-Core rev: d5db25213613cb862255047c0e995fd5489d9765)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:06 +00:00
Armin Kuster
c2f4fe8d0c libxml2: Security fix CVE-2015-8241
CVE-2015-8241 libxml2: Buffer overread with XML parser in xmlNextChar

(From OE-Core rev: f3c19a39cdec435f26a7f46a3432231ba4daa19c)

(From OE-Core rev: 428878a67fd723908af74c4881e933969f2928a7)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Paul Eggleton
ce70f38442 tzdata: reinstate changes reverted in 2014c upgrade
OE-Core commit 57af3fb9662106f0a65a1b4edf83e2398be0a8f1 upgraded tzdata
but also reverted a couple of changes to SUMMARY and LIC_FILES_CHKSUM.
Reinstate these (with an update to the README md5 value since that has
changed slightly, without any change to the licensing statements
within).

(From OE-Core rev: cea4f6b86129f84a99700207777929bf7e811ed6)

(From OE-Core rev: 37069c7511603f9fe33bcc48e38ac58ab89138f9)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
f359ebd78d tzdata: update to 2016a
Changed LIC_CHKSUM_FILES to a new LICENSE  file.
Add BSD-3-clause to licenses

Changes affecting future time stamps

America/Cayman will not observe daylight saving this year after all.
Revert our guess that it would.  (Thanks to Matt Johnson.)

Asia/Chita switches from +0800 to +0900 on 2016-03-27 at 02:00.
(Thanks to Alexander Krivenyshev.)

Asia/Tehran now has DST predictions for the year 2038 and later,
to be March 21 00:00 to September 21 00:00.  This is likely better
than predicting no DST, albeit off by a day every now and then.

Changes affecting past and future time stamps

America/Metlakatla switched from PST all year to AKST/AKDT on
2015-11-01 at 02:00.  (Thanks to Steffen Thorsen.)

America/Santa_Isabel has been removed, and replaced with a
backward compatibility link to America/Tijuana.  Its contents were
apparently based on a misreading of Mexican legislation.

Changes affecting past time stamps
Asia/Karachi's two transition times in 2002 were off by a minute.
(Thanks to Matt Johnson.)

(From OE-Core rev: 790315dbd2dcb5b2024948ef412f32d2788cb6b5)

(From OE-Core rev: 6ebd2689f72b725c1ca493eae77d5a41386ee901)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
(cherry picked from commit 39e231cfabda8d75906c935d2a01f37df6121b84)
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
5ddc177fdf tzcode: update to 2016a
Change LIC_CHKSUM_FILES to License. Some files are BSD clause 3

Changes affecting build procedure

An installer can now combine leap seconds with use of the backzone file,
e.g., with 'make PACKRATDATA=backzone REDO=posix_right zones'.
The old 'make posix_packrat' rule is now marked as obsolescent.
(Thanks to Ian Abbott for an initial implementation.)

Changes affecting documentation and commentary

A new file LICENSE makes it easier to see that the code and data
are mostly public-domain.  (Thanks to James Knight.) The three
non-public-domain files now use the current (3-clause) BSD license
instead of older versions of that license.

tz-link.htm mentions the BDE library (thanks to Andrew Paprocki),
CCTZ (thanks to Tim Parenti), TimeJones.com, and has a new section
on editing tz source files (with a mention of Sublime zoneinfo,
thanks to Gilmore Davidson).

The Theory and asia files now mention the 2015 book "The Global
Transformation of Time, 1870-1950", and cite a couple of reviews.

The America/Chicago entry now documents the informal use of US
central time in Fort Pierre, South Dakota.  (Thanks to Rick
McDermid, Matt Johnson, and Steve Jones.)

(From OE-Core rev: 1ee9072e16d96f95d07ec5a1f63888ce4730d60e)

(From OE-Core rev: 7d8a32361c45ab99c88bc65612327aa49cf3bd39)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
(cherry picked from commit b7f292b84eea202fb13730c11452ac1957e41cf0)
Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
3c686ae014 qemu: Security fix CVE-2015-7295
CVE-2015-7295 Qemu: net: virtio-net possible remote DoS

(From OE-Core rev: 74771f8c41aaede0ddfb86983c6841bd1f1c1f0f)

(From OE-Core rev: 3a7c84952d40f95b0f34bc35eef4490ecc8da07e)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
27aeaab726 qemu: Security fix CVE-2016-1568
CVE-2016-1568 Qemu: ide: ahci use-after-free vulnerability in aio port commands

(From OE-Core rev: 166c19df8be28da255cc68032e2d11afc59d4197)

(From OE-Core rev: c2361dd9bb663b00dd194cb7fdb0e07d7e1ab5e1)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
94c26caff1 qemu: Security fix CVE-2015-8345
CVE-2015-8345 Qemu: net: eepro100: infinite loop in processing command block list

(From OE-Core rev: 99ffcd66895e4ba064542a1797057e45ec4d3220)

(From OE-Core rev: e51fc319b859f44be61822d93e0b72647a02f7c6)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
05f4812d15 qemu: Security fix CVE-2015-7512
CVE-2015-7512 Qemu: net: pcnet: buffer overflow in non-loopback mod

(From OE-Core rev: e6e9be51f77c9531f49cebe0ca6b495c23cf022d)

(From OE-Core rev: 90d2a8eb0853f506a457e9935f4354c71d2fc9c9)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:05 +00:00
Armin Kuster
caa104fd2a qemu: Security fix CVE-2015-7504
CVE-2015-7504 Qemu: net: pcnet: heap overflow vulnerability in loopback mode

(From OE-Core rev: b01b569d7d7e651a35fa38750462f13aeb64a2f3)

(From OE-Core rev: 10752d6beb5520ec0fc83a7d0173e10144b11685)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
73941fbc6a qemu: Security fix CVE-2015-8504
CVE-2015-8504 Qemu: ui: vnc: avoid floating point exception

(From OE-Core rev: c622bdd7133d31d7fbefe87fb38187f0aea4b592)

(From OE-Core rev: 38f102a9271896a49aa32aacf2c2be3a14f51493)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Wenzong Fan
4d3ce52194 subversion: fix CVE-2015-3187
The svn_repos_trace_node_locations function in Apache Subversion before
1.7.21 and 1.8.x before 1.8.14, when path-based authorization is used,
allows remote authenticated users to obtain sensitive path information
by reading the history of a node that has been moved from a hidden path.

Patch is from:
http://subversion.apache.org/security/CVE-2015-3187-advisory.txt

(From OE-Core master rev: 6da25614edcad30fdb4bea8ff47b81ff81cdaed2)

(From OE-Core rev: e1e277bf51c6f00268358f6bf8623261b1b9bc22)

(From OE-Core rev: b45dcbadc1a51188ac6dead855e14a181a7bccd9)

Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Wenzong Fan
f0ecaf46bb subversion: fix CVE-2015-3184
mod_authz_svn in Apache Subversion 1.7.x before 1.7.21 and 1.8.x before
1.8.14, when using Apache httpd 2.4.x, does not properly restrict
anonymous access, which allows remote anonymous users to read hidden
files via the path name.

Patch is from:
http://subversion.apache.org/security/CVE-2015-3184-advisory.txt

(From OE-Core master rev: 29eb921ed074d86fa8d5b205a313eb3177473a63)

(From OE-Core rev: 7af7a3e692a6cd0d92768024efe32bfa7d83bc8f)

(From OE-Core rev: e4a1caecc5ae6b8488ec8ed7d303296af99146c0)

Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
165fa6ce62 openssl: Security fix CVE-2016-0701
CVE-2016-0701 OpenSSL: DH small subgroups

(From OE-Core rev: c5868a7cd0a28c5800dfa4be1c9d98d3de08cd12)

(From OE-Core rev: 5e73d0e88c28ca1e948f5c463b9d9d1001251a42)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
1098a7bc0c openssl: Security fix CVE-2015-3197
CVE-2015-3197 OpenSSL: SSLv2 doesn't block disabled ciphers

(From OE-Core rev: b387d9b8dff8e2c572ca14f9628ab8298347fd4f)

(From OE-Core rev: c037cbdac6a0e871a60077703432c08be6d29677)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
e6d734904d glibc: CVE-2015-8776
it was found that out-of-range time values passed to the strftime function may
cause it to crash, leading to a denial of service, or potentially disclosure
information.

(From OE-Core rev: b9bc001ee834e4f8f756a2eaf2671aac3324b0ee)

(From OE-Core rev: 3527ba3be7cfdfd813f5ca495bc74db559a648cd)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
b03994fe3b glibc: CVE-2015-9761
A stack overflow vulnerability was found in nan* functions that could cause
applications which process long strings with the nan function to crash or,
potentially, execute arbitrary code.

(From OE-Core rev: fd3da8178c8c06b549dbc19ecec40e98ab934d49)

(From OE-Core rev: 6cb0465247195ec25ef1073e79997001380aa807)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:04 +00:00
Armin Kuster
ec05eebf8d glibc: CVE-2015-8779
A stack overflow vulnerability in the catopen function was found, causing
applications which pass long strings to the catopen function to crash or,
potentially execute arbitrary code.

(From OE-Core rev: af20e323932caba8883c91dac610e1ba2b3d4ab5)

(From OE-Core rev: 2e1c8cab3bc7b70e2a05dca20cb5bcec4335f04d)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:03 +00:00
Armin Kuster
7ff74d177c glibc: CVE-2015-8777
The process_envvars function in elf/rtld.c in the GNU C Library (aka glibc or
libc6) before 2.23 allows local users to bypass a pointer-guarding protection
mechanism via a zero value of the LD_POINTER_GUARD environment variable.

(From OE-Core rev: 22570ba08d7c6157aec58764c73b1134405b0252)

(From OE-Core rev: 9cc998978bd67bc5569cc1478f4ddee40020b929)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-07 17:23:03 +00:00
Armin Kuster
9845a542a7 openssh: CVE-2016-077x
this address two CVE's.
CVE-2016-0777 and CVE-2016-0778

(From OE-Core rev: 1c05115a906499989d2159683195ed6d2cda75ba)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:30 +00:00
Hongxu Jia
368da33ee7 logrotate: do not move binary logrotate to /usr/bin
In oe-core commit a46d3646a3e1781be4423b508ea63996b3cfca8a
...
Author: Fahad Usman <fahad_usman@mentor.com>
Date:   Tue Aug 26 13:16:48 2014 +0500

    logrotate: obey our flags

    Needed to quiet GNU_HASH warnings, and some minor fixes.
...
it explicitly move logrotate to /usr/bin without any reason,
which is against the original Linux location /usr/sbin.

So partly revert the above commit which let logrotate be
kept in the original place /usr/sbin.

(From OE-Core rev: 88015d6d0a887969ae82b0888bf32659a6d225d3)

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:30 +00:00
Armin Kuster
48d9e00913 libxml2: security fix CVE-2015-5312
(From OE-Core rev: 15d05f186fbe78774c933cf93f116af1a2a8e51a)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:30 +00:00
Armin Kuster
436e204445 libxml2: security fix CVE-2015-8242
(From OE-Core rev: acbd71fe7d0571b78bbecb7464d99823411a7b22)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
389549c0bb libxml2: security fix CVE-2015-7500
includes a depend fix security issue CVE-2015-7500

(From OE-Core rev: 7d54f2f85dfcc3a56239abafd5eaefb9d7d25081)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
88e28c86c5 libxml2: security fix CVE-2015-7499
includes:
CVE-2015-7499-1
CVE-2015-7499-2

(From OE-Core rev: 3048fe24e4c5f83ad0971062a88592bcb6bf52bc)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
6abe713244 libxml2: security fix CVE-2015-7497
(From OE-Core rev: 5b72983d1a6d5ad5e9a21d2673d57d1da2333ac6)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
66740c3314 libxml2: security fix CVE-2015-7498
(From OE-Core rev: b3d6a714180199a5e0099e3d40b37c9bfa106eb1)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
2390475894 libxml2: security fix CVE-2015-8035
(From OE-Core rev: 495eaf5039596ac0fab7684cfc867569710eb0f4)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
663943a802 libxml2: security fix CVE-2015-7942
includes:
CVE-2015-7942
CVE-2015-7942-2

(From OE-Core rev: 4ca806d70cf65a66daab85898bcf5d682bef43d3)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
7aaf773d32 libxml2: security fix CVE-2015-8317
(From OE-Core rev: 34379b38919d535cd787bde4493fff61bd17f37a)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:29 +00:00
Armin Kuster
9d44210c74 libxml2: security fix CVE-2015-7941
includes:
CVE-2015-7941-1
CVE-2015-7941-2

(From OE-Core rev: e06312c71209b2e1d19c7df1434e409ad96b58be)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Joshua Lock
d3ad918a71 libxml2: remove files for easier maintenance
Drop a couple of CVE fixes for easy cherry-picking from jethro.
The same fixes will be pack-ported from jethro in a following
patch.

(From OE-Core rev: 02fb45bada58f03c5571baf700934154e9fc57c2)

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Armin Kuster
f9e5cc9e16 openssl: fix for CVE-2015-3195
(From OE-Core rev: 55d09d4e2dad9d1f80e50348d44177e47e6e33e1)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Armin Kuster
0ed23c1a0a openssl: fix for CVE-2015-3194
(From OE-Core rev: edff5fc629c8f70191bd33c731084e8217780a38)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Armin Kuster
5c12661f8c openssl: fix for CVE-2015-3193
(From OE-Core rev: ee47f6ca78d15ec56556d5c078bf20315af457b8)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Martin Jansa
c7e2c072c2 texinfo: don't create dependency on INHERIT variable
* we don't want the do_package signature depending on INHERIT variable
* e.g. just adding the own-mirrors causes texinfo to rebuild:
  # bitbake-diffsigs BUILD/sstate-diff/*/*/texinfo/*do_package.sig*
  basehash changed from 015df2fd8e396cc1e15622dbac843301 to 9f1d06c4f238c70a99ccb6d8da348b6a
  Variable INHERIT value changed from
  ' rm_work blacklist blacklist report-error ${PACKAGE_CLASSES} ${USER_CLASSES} ${INHERIT_DISTRO} ${INHERIT_BLACKLIST} sanity'
  to
  ' rm_work own-mirrors blacklist blacklist report-error ${PACKAGE_CLASSES} ${USER_CLASSES} ${INHERIT_DISTRO} ${INHERIT_BLACKLIST} sanity'

(From OE-Core rev: e6cae8ace890fc4322830731cb95bcc2680f4cfc)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-20 17:08:28 +00:00
Belal, Awais
c1162207c9 grub2: Fix CVE-2015-8370
http://git.savannah.gnu.org/cgit/grub.git/commit/?id=451d80e52d851432e109771bb8febafca7a5f1f2

(From OE-Core rev: 3f2701c102e4e5b95fc79a8d967f9c48f8232fc6)

Signed-off-by: Awais Belal <awais_belal@mentor.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:35 +00:00
Thomas PERROT
a690c381ab openssl: fix SRC_URI
Corrects the URI of the openssl's recipe from fido. The sources were moved
to a new subdirectory.

(From OE-Core rev: 685e861f085736a4b0bae09bab86c3d456ec84ae)

Signed-off-by: Thomas Perrot <thomas.perrot@tupi.fr>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:35 +00:00
Sona Sarmadi
58f6a400d1 bind: CVE-2015-8000
Fixes a denial of service in BIND.

An error in the parsing of incoming responses allows some
records with an incorrect class to be accepted by BIND
instead of being rejected as malformed. This can trigger
a REQUIRE assertion failure when those records are subsequently
cached.

[YOCTO #8838]

References:
http://www.openwall.com/lists/oss-security/2015/12/15/14
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8000
https://bugzilla.redhat.com/attachment.cgi?id=1105581

(From OE-Core rev: 5e1c3942a02564904ee2b2e24004b9679d649b4e)

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Stefan Müller-Klieser
152e4c11e6 gcc-4.9: backport from gcc trunk r212178
When compiling meta-toolchain-qt5 on cortexa8, the compiler throws an
internal compiler error:

...
qttools-opensource-src-5.3.2/src/linguist/shared/po.cpp:
In function 'bool loadPO(Translator&, QIODevice&, ConversionData&)':
qttools-opensource-src-5.3.2/src/linguist/shared/po.cpp:717:1:
internal compiler error: in add_stores, at var-tracking.c:6000
...

Tracking this down led to https://bugs.linaro.org/show_bug.cgi?id=534
It seems the bug is well know and fixed upstream. So backporting from
trunk seems to be the right solution. This fixes the compiler problem
on cortexa8 and does not seem to be very invasive. The original commit
can be found at:

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212178 138bc75d-0d04-0410-961f-82ee72b054a4

(From OE-Core master rev: 6751ef78694783fb86e55c77afefae750ab1b610)

(From OE-Core rev: 91a001fc74dd13ea9e5249aa624ad360ce807349)

Signed-off-by: Stefan Müller-Klieser <s.mueller-klieser@phytec.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Martin Jansa
2924348da7 feature-arm-thumb.inc: Fix ARMPKGSFX_THUMB value
* my previous thumb related commit:
  commit 3e760031f91fb87c3e2f62b77a117eb41164f259
  Author: Martin Jansa <martin.jansa@gmail.com>
  Date:   Wed Feb 18 15:40:35 2015 +0100

    feature-arm-thumb.inc: respect ARM_INSTRUCTION_SET when adding thumb
    suffix

  unfortunately removed conditional on "thumb" in TUNE_FEATURES, when
  setting ARMPKGSFX_THUMB

* in case we have MACHINE without "thumb" in TUNE_FEATURES and distro
  setting ARM_INSTRUCTION_SET to "thumb" we end with:
  ARM_INSTRUCTION_SET="thumb"
  ARM_THUMB_OPT="thumb"
  ARM_M_OPT="thumb"

  # TUNE_CCARGS correctly not adding -mthumb
  TUNE_CCARGS=" -march=armv7-a  -mthumb-interwork -mfloat-abi=softfp -mfpu=neon"

  # but ARMPKGSFX_THUMB and TUNE_PKGARCH including "t2":
  ARMPKGSFX_THUMB="t2"
  TUNE_PKGARCH="armv7at2-vfp-neon"

  # causing following error:
  Error, the PACKAGE_ARCHS variable does not contain TUNE_PKGARCH (armv7at2-vfp-neon).

(From OE-Core master rev: 951200673af27538beaef647a33308b4f15d1fb0)

(From OE-Core rev: 17b3112a3d6fc4c777429f8b5965206889c55cc3)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Mike Crowe
36ea7bd65f allarch: Force TARGET_*FLAGS variable values
TARGET_CPPFLAGS, TARGET_CFLAGS, TARGET_CPPFLAGS and TARGET_LDFLAGS may
differ between MACHINEs. Since they are exported they affect task hashes
even if unused which leads to multiple variants of allarch packages
existing in sstate and bouncing in the sysroot when switching between
MACHINEs.

allarch packages shouldn't be using these variables anyway, so let's
ensure they have a fixed value in order to avoid this problem.

(Compare with 05a70ac30b37cab0952f1b9df501993a9dec70da and
14f4d016fef9d660da1e7e91aec4a0e807de59ab.)

(From OE-Core master rev: d08fda21bfb7d264c238af0232a22cdd751f5150)

(From OE-Core rev: 017b1992c7b9055f3a16e9c2e14535fe81dde6c8)

Signed-off-by: Mike Crowe <mac@mcrowe.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Richard Purdie
619b1c6b7d layer.conf: Add missing dependency for allarch package initramfs-framework
Similiarly to the other previous changes, add a missing allarch package dependency
for initramfs-framework on udev.

(From OE-Core master rev: 00524d0c4449eb358dcf6c5a049a8f5371ddadee)

(From OE-Core rev: c195dfac6fd248f65f00b9d5419ab132dbc1e6c9)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Richard Purdie
61f5562730 layer.conf: Add several allarch dependency exclusions
These are dependencies that our allarch packages have in OE-Core that cause
those allarch packages to rebuild every time MACHINE changes.

With these changes, OE-Core allarch packages all have a common sstate
signatures and no longer rebuild.

(From OE-Core rev: 63bff90fa4fb4a95e8c79f9f8e5dd90ae1dfc69d)

(From OE-Core master rev: 0b5e868d160faca041cda42b670066facd4db531)

(From OE-Core rev: 4e69cfb612520f3413be3e2a075d943a9e7c8df1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Martin Jansa
7cbff59de8 linux-dtb.inc: drop unused DTB_NAME variable from do_install
* this is causing do_install to depend on KERNEL_IMAGE_BASE_NAME which
  in some cases contains something like BUILD_NUMBER from CI, that
  caused do_install to be reexecuted every single time, which is very
  sad to be caused by unused variable.
* jethro and newer don't need this change, because it's also fixed in
  commit 86b3f29f93e3f87903668ea317c6bd97be4cdf62
  Author: Marek Vasut <marex@denx.de>
  Date:   Thu May 14 14:31:11 2015 +0200
  Subject: kernel: Build DTBs early

(From OE-Core rev: d17abc45f1e1ba0a08c6e7411eda52a5140faea7)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Bhuvanchandra DV
cfd74b00e5 linux-firmware: rtl8192cx: Add latest available firmware
Add latest available firmware binaries for RTL8192CX chipsets.
These new firmwares have been released in 2012, have been used
by the mainline kernel as preferred firmware since 3.13 and
even backported to stable branches.

(From OE-Core master rev: 2dc67b53d1b7c056bbbff2f90ad16ed214b57609)

(From OE-Core rev: 89c6d043aa76c0e1eac694b92cdd95c6b02c9762)

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Armin Kuster
01b93fb33d libxml2: fix CVE-2015-7942 and CVE-2015-8035
CVE-2015-7942 libxml2: heap-based buffer overflow in xmlParseConditionalSections()
CVE-2015-8035 libxml2: DoS when parsing specially crafted XML document if XZ support is enabled

[YOCTO #8641]

(From OE-Core master rev: 27de51f4ad21d9b896e7d48041e7cdf20c564a38)

(From OE-Core rev: fdaf0f8f8b034f19639f66e1d30088bb9abfc68d)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-01-15 13:14:34 +00:00
Elliot Smith
6e3eefb997 bitbake: toaster: Rework mimetype guessing to fix artifact downloads
Artifact download links were broken because the function to
get the mimetype for the artifact was incorrectly using the
underlying mimetype library. The function was also attached
to the build environment controller, which was unnecessary, as
we only support local controllers anyway.

Remove the mimetype getter on the build environment and
use the one in the view code instead. This prevents the download error
from occurring.

(Backport of dd957fe0f2 and
dd957fe0f2 from master to Yocto 1.8)

[YOCTO #8472]

(Bitbake rev: b09966906ef054834f0b465f0c5a2a937b4c4a4c)

Signed-off-by: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-18 13:52:00 +00:00
brian avery
aff2257e0b toasterconf: remove master as a branch option from fido release
Toaster isn't designed to be forward compatible. As such,
    a release cannot build releases newer then it.

    Particularly, "fido" cannot build "master", so we remove
    "master" from the list of supported releases in "fido"

    [YOCTO #8154]

(From meta-yocto rev: e12c4cf27ccdf3f93035a8450b5ff62fe4fe9838)

Signed-off-by: brian avery <avery.brian@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:28:14 +00:00
Aníbal Limón
118acdcf67 bash: Disable custom memory allocator
Bash is failing trying to allocate memory [1] using the custom
memory allocator if we disable it the issue is fixed.

The major distributions also disabled by default [2], so we
don't have a good reason to use it.

The underlying issue is due to bash’s malloc using brk() calls
to allocate memory, which fail when address randomization is
enabled in kernel. sbrk() based custom allocators are obsolete.
There may be some performance impact of this however correctness
is more important.

[YOCTO #8452]

[1] https://bugzilla.yoctoproject.org/show_bug.cgi?id=8452#c0
[2] https://bugzilla.yoctoproject.org/show_bug.cgi?id=8452#c5

(From OE-Core master rev: e42d8eff9eed7d1454b4f331d96dcee6dea232df)

(From OE-Core rev: 9f339f516ab03d598fae0e536b3a420ea4d8ee1a)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:40 +00:00
Paul Eggleton
72a8138908 tzdata: reinstate changes reverted in 2014c upgrade
OE-Core commit 57af3fb9662106f0a65a1b4edf83e2398be0a8f1 upgraded tzdata
but also reverted a couple of changes to SUMMARY and LIC_FILES_CHKSUM.
Reinstate these (with an update to the README md5 value since that has
changed slightly, without any change to the licensing statements
within).

(From OE-Core master rev: cea4f6b86129f84a99700207777929bf7e811ed6)

(From OE-Core rev: ea1169efac715140cebf20fae67eae58b5f1caf2)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:38 +00:00
Armin Kuster
e3d6475b07 tzdata: update to 2015g
Resend: typo in version in subject.

Changes affecting future time stamps

Turkey's 2015 fall-back transition is scheduled for Nov. 8, not Oct. 25.
(Thanks to Fatih.)

Norfolk moves from +1130 to +1100 on 2015-10-04 at 02:00 local time.
(Thanks to Alexander Krivenyshev.)

Fiji's 2016 fall-back transition is scheduled for January 17, not 24.
(Thanks to Ken Rylander.)

Fort Nelson, British Columbia will not fall back on 2015-11-01. It has
effectively been on MST (-0700) since it advanced its clocks on 2015-03-08.
New zone America/Fort_Nelson.  (Thanks to Matt Johnson.)

(From OE-Core master rev: fce47d3bd51ede32a392b53b046a4583ef1847c8)

(From OE-Core rev: a987c482584c3500c42d733f1d78b7662d46a3c1)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:37 +00:00
Armin Kuster
dd2b5c9653 tzcode: update to 2015g
Changes affecting code

localtime no longer mishandles America/Anchorage after 2037.
(Thanks to Bradley White for reporting the bug.)

On hosts with signed 32-bit time_t, localtime no longer mishandles
Pacific/Fiji after 2038-01-16 14:00 UTC.

The localtime module allows the variables 'timezone', 'daylight',
and 'altzone' to be in common storage shared with other modules,
and declares them in case the system <time.h> does not.
(Problems reported by Kees Dekker.)

On platforms with tm_zone, strftime.c now assumes it is not NULL.
This simplifies the code and is consistent with zdump.c.
(Problem reported by Christos Zoulas.)

Changes affecting documentation
The tzfile man page now documents that transition times denote the
starts (not the ends) of the corresponding time periods.
(Ambiguity reported by Bill Seymour.)

(From OE-Core master rev: 7c9082ab1ae6f7810c7cffe137d7d232b03852f8)

(From OE-Core rev: 6c32103a8491fb0a0fa5dec905720a40877c6563)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:36 +00:00
Adrian Calianu
31aa514524 glibc: fix the big endian loader name on AArch64
Apply a patch backported from glibc 2.22 (master) to fix
the loader name on AArch64.

(From OE-Core rev: 513e52670ea52e8143f46777accf441bb5c299fa)

Signed-off-by: Adrian Calianu <adrian.calianu@enea.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:35 +00:00
Martin Jansa
446295e866 fontcache: allow to pass extra parameters and environment to fc-cache
* this can be useful for passing extra parameters, pass
  -v by default to see what's going on in do_rootfs
* we need to use this for extra parameter we implemented
  in fontconfig:
  --ignore-mtime always use cache file regardless of font directory mtime
  because the checksum of fontcache generated in do_rootfs
  doesn't match with /usr/share/fonts directory as seen on
  target device causing fontconfig to re-create the cache
  when fontconfig is used for first time or worse create
  new cache in every user's home directory when /usr/
  filesystem is read only and cache cannot be updated.

  Running FC_DEBUG=16 fc-cache -v on such device shows:
  FcCacheTimeValid dir "/usr/share/fonts" cache checksum 1441207803 dir checksum 1441206149
* my guess is that the checksum is different, because pseudo
  (which is unloaded when running qemuwrapper) or because some
  influence of running the rootfs under qemu.

(From OE-Core rev: 22bb7e11f9c75943efa07997a98304aa01d14699)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:34 +00:00
Ross Burton
2761a2bd8b readline: actually apply readline63-003 (aka CVE-2014-2524)
This file wasn't named as a patch, nor told to apply explicity, so it was just
unpacked to the work directory and not applied.  Rename the file so the patch is
applied correctly.

(thanks to Petter Mabäcker <petter@technux.se> for spotting this)

(From OE-Core master rev: 02be728762c77962f9c3034cd7995ad51afaee95)

(From OE-Core rev: 7f2e2d57c7496547b7970377547482ead2e152cf)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:34 +00:00
Andre McCurdy
ddb058ca08 gettext_0.16.1: add -lrt and -lpthread to LDFLAGS for uclibc builds
Fix linker errors due to posix_spawnp etc being in librt for uclibc.

 | sh4-rdk-linux-uclibc-libtool: link: sh4-rdk-linux-uclibc-gcc -ml -m4 --sysroot=/build-foo/tmp/sysroots/foo -O2 -pipe -g -feliminate-unused-debug-types -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -o .libs/test-names test-names.o  libuniname.a ../gnulib-lib/.libs/libgettextlib.so /build-foo/tmp/work/sh4-rdk-linux-uclibc/gettext/0.16.1-r6/build/gettext-tools/intl/.libs/libintl.so -lc /build-foo/tmp/sysroots/foo/usr/lib/libiconv.so
 | ../gnulib-lib/.libs/libgettextlib.so: undefined reference to `posix_spawnp'
 | ../gnulib-lib/.libs/libgettextlib.so: undefined reference to `posix_spawn_file_actions_adddup2'
 | ../gnulib-lib/.libs/libgettextlib.so: undefined reference to `posix_spawn_file_actions_addopen'
 | ../gnulib-lib/.libs/libgettextlib.so: undefined reference to `posix_spawn_file_actions_addclose'
 | collect2: error: ld returned 1 exit status

(From OE-Core rev: 28f4d6d6e926be2f5efc098eb599200301f1ab2c)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: d46333d)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:33 +00:00
Andre McCurdy
dfe39ea187 gettext_0.16.1: remove obsolete uclibc specific patch
gettext-error_print_progname.patch was originally created for gettext
v0.14.6 and does not apply cleanly to gettext v0.16.1.

Since the original issue addressed by the patch isn't documented and
because gettext v0.16.1 seems to be build OK for uclibc without the
patch, assume the patch is obsolete and no longer required.

(From OE-Core rev: 66e229474271a4ae6df8b5377bb2f9fe8175fb64)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: d95d92a)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:32 +00:00
Andre McCurdy
4525e29979 libiconv_1.11.1: fix LICENSE declaration, LGPL -> LGPLv2.0
(From OE-Core rev: dde08a4ba4a12a81b780b69c6ec395508b0a030f)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: 7d2da0e)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:31 +00:00
Andre McCurdy
dbf6599fbe libiconv_1.11.1: merge build and packaging fixes from libiconv_1.14
054151c libiconv: Fix B != S with uclibc builds
  273c437 libiconv: Remove RPATH from binaries
  fcb8d6f libiconv_1.14.bb: Fix build failure [partial-merge]

(From OE-Core rev: 3f5b2da748bbb0417a63c69393cdd024623074a2)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: 898e9d7)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:30 +00:00
Andre McCurdy
442518efac uclibc: backport upstream fix for SH4
Backport upstream fix for building uclibc for SH4 with recent gcc:

  http://git.uclibc.org/uClibc/commit/?id=2c8a7766681b704e710f51c0817534e3f9a952d1

(From OE-Core rev: 6077f09f76b05b002f21e14c62c7c986db5427a9)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

(From OE-Core master rev: aa20c3d)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:30 +00:00
Haris Okanovic
afff53db2a openssh: Backport CVE-2015-5600 fix
only query each keyboard-interactive device once per
authentication request regardless of how many times it is listed

Source:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/auth2-chall.c?f=h#rev1.43
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/auth2-chall.c.diff?r2=1.43&r1=1.42&f=u

Bug report:
https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-5600
https://bugzilla.redhat.com/show_bug.cgi?id=1245969

Testing:
Built in Fido and installed to x86_64 test system.
Verified both 'keyboard-interactive' and 'publickey' logon works with
root and a regular user from an openssh 7.1p1-1 client on Arch.

(From OE-Core rev: 433f66ba6c79cf49e29251af0985baf5c4b79e23)

Signed-off-by: Haris Okanovic <haris.okanovic@ni.com>
Reviewed-by: Rich Tollerton <rich.tollerton@ni.com>
Reviewed-by: Ken Sharp <ken.sharp@ni.com>
Natinst-ReviewBoard-ID: 115602
Natinst-CAR-ID: 541263
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:29 +00:00
Tudor Florea
b8eb509ca5 unzip: CVE-2015-7696, CVE-2015-7697
CVE-2015-7696: Fixes a heap overflow triggered by unzipping a file with password
CVE-2015-7697: Fixes a denial of service with a file that never finishes unzipping

References:
http://www.openwall.com/lists/oss-security/2015/10/11/5
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7696
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7697

(From OE-Core rev: 458d877590bcd39c7f05d31cc6e7600ca59de332)

Signed-off-by: Tudor Florea <tudor.florea@enea.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:28 +00:00
Armin Kuster
7e9516cb0e libxslt: CVE-2015-7995
This is a is being give a High rating so please consider it for
all 1.1.28 versions.

A type confusion error within the libxslt "xsltStylePreCompute()"
function in preproc.c can lead to a DoS. Confirmed in version 1.1.28,
other versions may also be affected.

(From OE-Core rev: 2ad0b4dd7262c251f991bbf7826580d89bd6e73a)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:27 +00:00
Ting Liu
dc6630b44b oprofile: update --with-kernel option to find perf_event.h
Update --with-kernel=${STAGING_DIR_HOST}/${prefix} to find kernel
headers (linux/*.h) to fix the error:
| checking kernel supports perf_events... unknown -- perf_event.h not found
| ERROR: You requested to build oprofile with '--with-kernel=/buildarea/lyang1/test_f2/tmp/work-shared/qemux86/kernel-source',
| but headers were not accessible at the given location.
| Be sure you have run the following command from within your kernel source tree:
|      make headers_install INSTALL_HDR_PATH=<kernel-hdrs-install-dir>
| Then pass <kernel-hdrs-install-dir> to oprofile's '--with-kernel' configure option.
| configure: error: Unable to build oprofile. Exiting.

This is part of the commit b5b3085d9d which
already applied in poky master branch.

(From OE-Core rev: 91ca81244e683c4f24752c59ec3342cd4fb1315d)

Signed-off-by: Ting Liu <ting.liu@freescale.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:26 +00:00
Leonardo Sandoval
e0b0824470 init-install-efi.sh: Avoid /mnt/mtab creation if already present
The base-files recipe installs /mnt/mtab (it is a softlink of /proc/mounts),
so if an image includes the latter, there is no new to created it again inside
the install-efi.sh script, otherwise an error may occur as indicated on the
bug's site.

[YOCTO #7971]

(From OE-Core master rev: 6c6c6528954952e1e323f5a26afd93b99913e6f2)

(From OE-Core rev: 92da534cefb5937c69553dbe599b664dc73292f3)

Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:12 +00:00
Stefan Christ
f251052c88 systemd: fix networking setup when ipv6 modules are missing
If the ipv6 kernel modules are missing, e.g. /lib/modules/<version>
doesn't match the runnig kernel, networkd doesn't bring up the
interfaces correctly. Backport fix from systemd version v220.

(From OE-Core rev: 3db960ef645606226784cbfd994d476892db07fe)

Signed-off-by: Stefan Christ <s.christ@phytec.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:12 +00:00
Jonathan Liu
7d2e451823 systemd: add PACKAGECONFIG for qrencode
(From OE-Core master rev: 5c0dc3e8f49621827e20f79fb6bc945c3f17315e)

(From OE-Core rev: 2b8579f18f6e0477ac46bca870c1caf2c2469128)

Signed-off-by: Jonathan Liu <net147@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:12 +00:00
Reinette Chatre
05108aa9c2 systemd: fix tmpfiles location when multilib in use
Systemd's configuration files for creation, deletion and cleaning
of volatile and temporary files are installed in /usr/lib even when
multilib is in use (when /usr/lib64 is available). In this check the
systemd.conf file will not be found if libdir is /usr/lib64 so we fix the
path to match this file's installation path to look for it in
${exec_prefix}/lib

(From OE-Core master rev: c1ef36c2b3e3876cc166a9a5e153fc6f23b42b92)

(From OE-Core rev: 771ee44f3b6f15cc07eb4e3990a05130d3cd6bf1)

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-12-08 13:27:12 +00:00
Scott Rifenbark
51246bfae3 documentation: Updates to support a 1.8.1 YP manual release.
Involves setting poky.ent variables, updating the manual
revision tables, and editing the mega-manual.sed file to
have the 1.8.1 string in there.

(From yocto-docs rev: 5f06e00c9bd657059433cd3487e86eccd31e5cd6)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-11-18 16:44:02 +00:00
Scott Rifenbark
e3425d4b0d toaster-manual: Updated to remove 'master' as the default branch
Made several changes as Toaster will not support using the

'master' branch now.

(From yocto-docs rev: cc7e1273944d72388ba4202cbf7146a909d1cdac)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-11-18 16:44:02 +00:00
Scott Rifenbark
5752ef3892 ref-manual: Corrected example to modify extrauser root password example
Fixes [YOCTO #7925]

Changed the final example from "useradd" to "usermod".

(From yocto-docs rev: 4360a2ab5734d456648efd72df6b1de4a3980ded)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-11-18 16:44:01 +00:00
Paul Barker
fa55b8e505 bitbake: toaster: buildinfohelper Skip packages we have no build info about
If there are more packages listed as installed than we know about from
bitbake, and therefore have insufficient information to be able to
create a Toaster Package object then skip it. Also handle the case where
a dependency references such a package.

Also clarify the error logging.

(Bitbake rev: a9e23e0066ea4dc16806ed3d269587ad1c895353)

Signed-off-by: Paul Barker <paul.barker@commagility.com>
Cc: Michael Wood <michael.g.wood@intel.com>
Cc: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-24 12:01:07 +01:00
Scott Rifenbark
6b421cd7fe ref-manual: Fixed typo in 1.6 migration section for BitBake
In Section 5.5.3.2 bb.fetch.encodeurl: Use bb.fetch.encodeurl

changed to

bb.encodeurl: Use bb.fetch.encodeurl

Reported-by: Olivier Dugas <dugaso@sonatest.com>
(From yocto-docs rev: bb8e0c173d4c1945ab538a33c7c868f0f72fd362)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:39 +01:00
Scott Rifenbark
7b586ea6ff poky.ent: Added "findutils" and "which" packages to Fedora essentials.
(From yocto-docs rev: 3ba75c36f420acda63c12dcff6a2686dd2702466)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:39 +01:00
Scott Rifenbark
cbec5e933e ref-manual: Fix to QA error message.
Fixed wording in section 7.78 to use "nativesdk-myrecipe.bb".

Fixed message to say "non-dev/-dbg/nativesdk- package contains symlink..."

Reported-by: Rene Fichter <rene@fichter.se>
(From yocto-docs rev: 429fd10005c4e63c611eb8192a71f063310f8933)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:39 +01:00
Scott Rifenbark
ecec6c56b5 ref-manual: Fixed grammar issue in the oelint.bbclass section.
(From yocto-docs rev: 346b865c0c2f8696f32ee26f383a078367b74119)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
1aec522aad ref-manual: Updated UNKNOW_CONFIGURE_WHITELIST variable
Fixes [YOCTO #7755]

Applied some review edits to the wording from Ross Burton.

(From yocto-docs rev: da0642350520975416d1c91ac98b57a6bde26439)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
8124686aa2 kernel-dev: Added kernel-devsrc information for building on target
I added a clarifying paragraph at the start of the section that talks
about building on the target hardware.  Included kernel-devsrc and
rationale for why a user would even do this (it is not normal).

(From yocto-docs rev: 95ae213b80cb45b5e9b7b161b2968dca6315e1da)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
8a19731e4d poky.ent: Updated the YOCTO_RELEASE_NOTES variable
Once again... having to try and match what is done by the release
team.  I think going forward we will use this form for
YOCTO_RELEASE_NOTES

(From yocto-docs rev: 7745eb618d7ab6e01e98d2158599047486649e4a)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
6c97739acb ref-manual: Updated the UNKNOWN_CONFIGURE_WHITELIST variable.
Added information to note when it is used (insane.bbclass) and only
if the recipe inherits the autotools.bbclass.

Fixes [YOCTO #7755]

(From yocto-docs rev: 1a30a52c90a77990e9fd178837102b7f1978d7e8)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
0120391b04 kernel-dev: Added new requirement for working with yocto-linux-custom.bb
Fixes [YOCTO #6611]

Added a new step to the "Working With Your Own Sources" section
so that the user is aware of needing to provide a defconfig file
or configuration fragments to the SRC_URI variable when working
with the yocto-linux-custom.bb recipe.

(From yocto-docs rev: 7a24ea3ce2f732baebbdb4fb42d458901ff056d1)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
21469e0ef6 ref-manual: Updated ARCHIVER_MODE and archiver.bbclass
Added information in about the various varflags the user can
use to define the type of archive.

(From yocto-docs rev: b3dbe2410e67c3b9988d11c8f9e105c4d01ce22e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
a142b2265a ref-manual: Fixed "TBD" section cross-reference in KBUILD_DEFCONFIG
Fixes [YOCTO #7474]

There was a TBD section here that needed filling out.

(From yocto-docs rev: f82a5ea99f8b3d6dfc7fc38148b5e6e5e4721b05)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:38 +01:00
Scott Rifenbark
bbd4bfc061 kernel-dev: Added new "in-tree" defconfig file section.
I added the new section "Using an "In-Tree" defconfig File"
section.  This section addresses the ability to not use the
default location for defconfig files, which is usually in the
metadata layer.  The section describes how to use the
KBUILD_DEFCONFIG variable.

Fixes [YOCTO #7474]

(From yocto-docs rev: f514c8b96ef991f5893c73ae06392eb306c12a5e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
7cf64ab594 dev-manual: Added new section on "defconfig" files.
The "Configuring the Kernel" section did not address "defconfig"
files.  In my opinion, this is a hole in the docs for this section.
I added a new section titled "Creating a defconfig File" that is a
sub-section of the "Configuring the Kernel" section.

Additionally, I added a brief sentence in the introductory paragraph
to include the fact that this new information exists.

Finally, I included the bitbake command that ensures that the
proper configuration steps are minimally run before a user attempts
to use bitbake to get into menuconfig.

Fixes [#YOCTO 7474]

(From yocto-docs rev: 3e982a4f19402a941583a9a8708eeb6dbaf8fad5)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
e00d07ce45 kernel-dev: Added detail to start of generating config file
Fixes [YOCTO #7474]

The "Generating Configuration Files" section has a procedure that
starts with a step to complete a build at least through the
kernel configuration task.  This is needed but we could use a
bit of explanation here.  I added some rationale behind why you
should do this.

(From yocto-docs rev: dc6579de0740703796e7e6473ad86f70d0ca5aa2)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
7388b9c8d8 documentation: Updated customization layers to point to XSL mirrors
The customization layers were pointing to Sourceforge site for the
XSl files needed to build the manuals.  Throuhgout time, this site
has failed me enough to warrent trying to get these XSL files from
some other source.  Rather than ship the XSL files with the YP release,
we decided to create some mirrors and point the customization files
there.

(From yocto-docs rev: 280bcafb4ce3471c364612aa85f7280f700f855d)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
10228eed0f ref-manual: Removed PRINC entry from the glossary
This variable has been deprecated a while and Paul Eggleton suggested
we finally remove it from the glossary.  I removed it and also
took away the two links from where the variable was referenced
in a couple spots in the migration section.

(From yocto-docs rev: 141b873f6c3111c791fdc71f937b667171f82d2e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
56b13544d7 toaster-manual: Added detail for the URL to access Web Interface
(From yocto-docs rev: cf7899959a18ac04c732ae80aee2ecd7c3fea851)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
ebec9603e7 ref-manual: Added new variable description UNKNOWN_CONFIGURE_WHITELIST
Fixes [YOCTO #7755]

Added a new description for this variable.  Based it on information
given to me by Paul Eggleton.

(From yocto-docs rev: 112b86020942939a00a742d5aa421a23f2651a97)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
ddefb0a380 ref-manual: Updated EXTRA_IMAGE_FEATURES variable
Added better wording to show that you use spaces to separate
multiple features.

(From yocto-docs rev: 5bbfda659be29b0014d25391680c1f9e4f3866d1)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:37 +01:00
Scott Rifenbark
f23f27d47e dev-manual: Updates to kernel configuration in the "Kernel Modification Workflow" section
This section needed some more information.  It referenced the yocto-kernel
script and menuconfig.  I added references to the appropriate areas of
YP documentation for these.  I also changed wordings to that it is
apparent that .config is created by menuconfig when changes are saved.

(From yocto-docs rev: aa01fd8d5917fac6c14f69aaa0a26200b3e67968)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
45c4f14dcb dev-manual: Added a link to reference defconfig files.
(From yocto-docs rev: d6240dda3f056cdacd039f2867a4da48c0ad0f02)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
329be1e06d dev-manual: Minor edits to "Configuring the Kernel" section.
(From yocto-docs rev: f840fa86b8fd970be20a11e362b7399635e78a93)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
68460ed58c ref-manual: Added new glossary description for KBUILD_DEFCONFIG.
(From yocto-docs rev: 6039b3a5b1ff68104760fa8780507a5d5d3e2d8f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
8ab8646e28 adt-manual: Updated the "Getting the Images" section for eclipse-debug
The way to include tcf-agent now in an image that you are going to
remotely deploy and debug using the Eclipse IDE is to simply include
the eclipse-debug image feature as part of the image.  I updated the
section around getting images to reflect this simple method.

Reported-by: Adam Lee <adam@gumstix.com>
(From yocto-docs rev: 2da55c34972f4e6a57c37a9011c2c4769a0e3814)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
be0ea1022d ref-manual: Added and updated variables to support calling functions
Fixed [YOCTO #7632]

Looked for, updated, and added (if necessary) the following
variables:

 * ROOTFS_PREPROCESS_COMMAND
 * ROOTFS_POSTPROCESS_COMMAND
 * SDK_POSTPROCESS_COMMAND
 * POPULATE_SDK_POST_TARGET_COMMAND
 * POPULATE_SDK_POST_HOST_COMMAND,
 * IMAGE_POSTPROCESS_COMMAND
 * IMAGE_PREPROCESS_COMMAND
 * ROOTFS_POSTUNINSTALL_COMMAND
 * ROOTFS_POSTINSTALL_COMMAND

Each of these variables no longer accepts arbitrary shell commands but
rather functions.  The wordings now support that behavior.

Also, updated the migration section for going to 1.6 release to note
this change.

(From yocto-docs rev: d52256cbf08a4d8968d68423138546fb33abbad6)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
fa9b57e6f5 ref-manual: Added 'ptest' to the list of Distro Features
Reported-by: Paul Eggleton <paul.eggleton@intel.com>
(From yocto-docs rev: e63773beac002bf39b2b371c50d3329de01e8586)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
e91684be80 ref-manual: Updates to the "Speeding Up the Build" section
I applied a little more information to this section to help
round out the variable explanations.  Part of the change involved
adding PARALLEL_MAKEINST to the list of scaled variables.
I had left that variable off.  Also added a new trade-off.

(From yocto-docs rev: 2b6377030677b1318cb9d6e038885d7874f0e609)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:36 +01:00
Scott Rifenbark
d5236b6535 ref-manual, dev-manual: Added info about make race work-around
I updated both the PARALLEL_MAKE and PARALLEL_MAKEINST variables
by expanding the note to indicate how to prohibit parallel make
threads.  Also, added a cross-referencing link to the
"Debugging Parallel Make Races" section.

I added a short note to the start of the "Debugging Parallel Make
Races" section noting that if they can't properly fix the condition,
they can always do a work-around to set the PARALLEL_MAKE or
PARALLEL_MAKEINST variables to null.

Reported-by: Robert P. J. Day <rpjday@crashcourse.ca>
(From yocto-docs rev: 8c0dc2540e97a4e3a42c1d541ea20e65518fffef)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
1025e7fa16 ref-manual: Formatting fixes and tag fix.
(From yocto-docs rev: 60999b4f7c38e0d659730dbe3defe95fa9684619)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
fdba15a1e7 ref-manual: Updates to BB_NUMBER_THREADS and PARALLEL_MAKE
I added some more detail to these two variables.  The system sets
them according to the perceived number of cores.  These default
setting are cool for single socket systems.  However, if you
have some big system with a lot of physical CPUs, you might want
to cap off the values at 20.  This is according to Darren Hart.

I also put in some cross-references to the "Speeding Up the Build"
section.

(From yocto-docs rev: 69b931f019f7bec687a642d7fccd1172a9be1746)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
e934ab58f4 ref-manual: Added descriptions for four new variables
Fixes [YOCTO #7665]

Added descriptions in the glossary for the following variables:

 * SDK_HOST_MANIFEST
 * SDK_TARGET_MANIFEST
 * SDK_VERSION
 * TOOLCHAIN_OUTPUTNAME

(From yocto-docs rev: 709421023ff6545da30fcb3486027ff984d4241e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
2220cca84e adt-manual: Emphasis on populate_sdk as bitbake method for building toolchain
I updated the "Optionally Building a Toolchain Installer" section
to emphasize using 'bitbake <image> -c populate_sdk' as the method
for building outa toolchain.  Before the change, equal emphasis was
put on for this preferred method and the 'bitbake meta-toolchain'
method.

(From yocto-docs rev: 46156957c38edf33cf3c98957733f6eb4323fa0b)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
76d164d5ad dev-manual: Updated requirements for writing a new test.
Fixes [YOCTO #7524]

The "Writing New Tests" section needed more clarification in the first
paragraph.  One requirement is that minimally, an empty __iniit_.py
file must exist in the runtime directory.

(From yocto-docs rev: 8f003a9fe7c31bad7ed705a003a44761ba8b3c4f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:35 +01:00
Scott Rifenbark
4d9919646a ref-manual: Added new variable description for ARCHIVER_MODE
Also, added a cross-reference link from the archiver.bbclass section
to the new description.

(From yocto-docs rev: 1a7c86064f2dbb7453026bf8b8166566b33b3287)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-10-21 23:11:34 +01:00
Richard Purdie
b74ea963ce build-appliance-image: Update to fido head revision
(From OE-Core rev: f0873b83d693af4a103999160d67fcf25c7eedc1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-29 14:59:45 +01:00
Richard Purdie
963a0c2f76 poky.conf: Bump version for 1.8.1 fido release
(From meta-yocto rev: debe2f66bad75f052bc74681d27951345418310f)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-29 14:59:24 +01:00
Ross Burton
f963541dc0 sstate: run recipe-provided hooks outside of ${B}
To avoid races between the sstate tasks/hooks using ${B} as the cwd, and other
tasks such as cmake_do_configure which deletes and re-creates ${B}, ensure that
all sstate hooks are run in the right directory, and run the prefunc/postfunc in WORKDIR.

(From OE-Core rev: 07a7e1a0bee5b8757951e67c9353c786a6ac8500)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-29 14:42:25 +01:00
Robert Yang
57eb677f0e autotools.bbclass: mkdir ${B} -> mkdir -p ${B}
${B} is the default cwd of tasks, so there might be race issues such as:
| mkdir: cannot create directory `${B}': File exists
[snip]
NOTE: recipe perf-1.0-r9: task do_configure: Failed

(From OE-Core rev: 4c02a30f084408d0a6a5149937ef74520f8346dc)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-19 11:11:12 +01:00
Robert Yang
5fecc456e5 perf: mkdir ${B} -> mkdir -p ${B}
${B} is the default cwd of tasks, so there might be race issues such as:
| mkdir: cannot create directory `/path/to/work/qemux86-poky-linux/perf/1.0-r9/perf-1.0/': File exists
[snip]
NOTE: recipe perf-1.0-r9: task do_configure: Failed

(From OE-Core rev: eb3d1dac724144637a86e8124b7b6b91bbeab822)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-19 11:11:11 +01:00
Li Zhou
4ce2a556ca libunwind: Security Advisory - libunwind - CVE-2015-3239
libunwind: Invalid dwarf opcodes can cause references beyond the end of
the array

Off-by-one error in the dwarf_to_unw_regnum function in include/dwarf_i.h
 in libunwind 1.1 allows local users to have unspecified impact via
invalid dwarf opcodes.

(From OE-Core master rev: 9c4e7f5c009b076b0bc638a02fcf3d96c362e7eb)

(From OE-Core rev: 38de3cd2fcc5e2c79dcf1c864c84f8e712111e5d)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:27 +01:00
Martin Jansa
174b15c2c0 rootfs.py: show intercept script output in log.do_rootfs
* without this the output wasn't shown anywhere even when the bb.warn
  says:
  "See log for details!"

(From OE-Core master rev: a3c322b42c7a14584a80e04519c34689ec813210)

(From OE-Core rev: 33b9dc43afbf9d201863d4327cd8689582b19070)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:26 +01:00
Martin Jansa
bb931159ea postinst_intercept: allow to pass variables with spaces
* trying to pass foo="a b" through postinst_intercept ends
  with the actual script header to containing:
  b
  foo=a
  which fails because "b" command doesn't exist.

(From OE-Core master rev: c66d7d85b7225be8c838449324d506565dd0081d)

(From OE-Core rev: e1cb77476934ea0f80993df049c3708bfa33dba3)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:26 +01:00
Martin Jansa
346188f176 rootfs.py: Allow to override postinst-intercepts location
* useful when we need to overlay/extend intercept scripts from oe-core

(From OE-Core master rev: 7d08d2d5c0ae686e3bb8732ea82f30fd189b1cd8)

(From OE-Core rev: 0f528bda0bac76e190b03764c603f199a6079fc6)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:26 +01:00
Sona Sarmadi
3b9a1144a5 libtasn1: CVE-2015-3622
_asn1_extract_der_octet: prevent past of boundary access

References:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3622
http://git.savannah.gnu.org/gitweb/?p=libtasn1.git;a=patch;
h=f979435823a02f842c41d49cd41cc81f25b5d677

(From OE-Core rev: 553bc30b96cd9ef9c5bc621debcf7c23c66d7e42)

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:25 +01:00
George McCollister
687327d494 wic: fix path parsing, use last occurrence
If the path contains 'scripts' more than once the first occurrence will be
incorrectly used. Use rfind instead of find to find the last occurrence.

(From OE-Core rev: 35ecb0b8557aae85f377c9d99f1a72cbb76fb6d8)

Signed-off-by: George McCollister <george.mccollister@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:25 +01:00
Armin Kuster
c18dff0871 openssh: CVE-2015-6563 CVE-2015-6564 CVE-2015-6565
three security fixes.

CVE-2015-6563 (Low) openssh: Privilege separation weakness related to PAM support
CVE-2015-6564 (medium)  openssh: Use-after-free bug related to PAM support
CVE-2015-6565 (High)  openssh: Incorrectly set TTYs to be world-writable

(From OE-Core rev: 259df232b513367a0a18b17e3e377260a770288f)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:24 +01:00
Armin Kuster
ab7f4c1a6d bind: CVE-2015-1349 CVE-2015-4620 CVE-2015-5722
three security fixes.

(From OE-Core rev: 16e80afe187c173e00b734c757a05157855ed504)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:24 +01:00
Richard Purdie
78b2eaa516 runqemu: Handle device names like tapX@NONE
ip list can return devices in the form tapX@NONE. If it does so,
ensure we handle that case correctly. Newer distros appear to do
this in some cases.

[YOCTO #8129]

(From OE-Core master rev: 6459dde380febce24d2c355d441d9cb3b14409b9)

(From OE-Core rev: a6709ac54bb9ac79692c3c6faadaace11b8f33f4)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:24 +01:00
Saul Wold
1245acce18 oprofileui: Use inherit gettext
oprofileui uses gettext during the configuration task so should be inherit
gettext. This issue appears when an older version of gettext is used do to
pinning to the older non-gplv3 version.

[YOCTO #7795]

(From OE-Core rev: 7a161f8685c551892218a9a7877c10bdcd170c0e)

Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:23 +01:00
Sona Sarmadi
6516ecd075 gnutls: CVE-2015-3308
Fixes use-after-free flaw in CRL distribution points parsing

Reference:
d6972be332
053ae65403

http://www.openwall.com/lists/oss-security/2015/04/15/6

(From OE-Core rev: 4db630c0cd7988c923eb3f48153a6cedafd6a139)

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:23 +01:00
Alejandro Hernandez
d6dcddbb3d qemurunner: Improves checking for server and target IPs on qemus parameters
Fixes OS hanging infinitely waiting for qemus process to release bitbake.lock

(From OE-Core master rev: d168bf34c553dbe5de7511e158cd83869d7a88bc)

(From OE-Core rev: b19f599fe8d06d9381ae774f3289fa8c054ad1cc)

Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:22 +01:00
Paul Eggleton
1c65b4bdd8 oeqa/utils/qemurunner: fix logging
OE-Core commit 519e381278d40bdac79add340e4c0460a9f97e17 unfortunately
broke logging in two different ways:

1) it prevented logging to the task log from working within bitbake
   -c testimage. This is due to the logger object being set up too early
   which interferes with BitBake's own logging. If we prefix the name
   with "BitBake." everything works (and we don't need to set the
   logging level).

2) Additionally because it called the log functions on the logging
   module and not the logger object it set up, this caused the
   oe-selftest logging to start printing everything from that point
   forward.

Fix these two issues and return us to the desired behaviour for
do_testimage.

(From OE-Core master rev: 429b1971be06d5146bb1c14f4697966cddab3b33)

(From OE-Core rev: 095b6ccbf86b1830da2dcf5af09a4ebbcdfca921)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:22 +01:00
Ross Burton
e4f0b095e8 oeqa/QemuRunner: don't use bb for logging
Instead of using bb.note() etc for logging use logging.Logger directly, allowing
the use of QemuRunner outside of bitbake.

Also clean up the logging/errors by moving create_socket() out of
__init__()/restart() and into start().

(From OE-Core master rev: 519e381278d40bdac79add340e4c0460a9f97e17)

(From OE-Core rev: 97478640e1449e861b880dd3bedc6af1b0bbacdc)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-18 19:22:22 +01:00
Armin Kuster
b50596d8f6 tzdata: update to 2015d
Changes affecting future time stamps

Egypt will not observe DST in 2015 and will consider canceling it
permanently.  For now, assume no DST indefinitely.
(Thanks to Ahmed Nazmy and Tim Parenti.)

Changes affecting past time stamps
America/Whitehorse switched from UTC-9 to UTC-8 on 1967-05-28, not
1966-07-01.  Also, Yukon's time zone history is documented better.
(Thanks to Brian Inglis and Dennis Ferguson.)

Change affecting past and future time zone abbreviations
The abbreviations for Hawaii-Aleutian standard and daylight times
have been changed from HAST/HADT to HST/HDT, as per US Government
Printing Office style.  This affects only America/Adak since 1983,
as America/Honolulu was already using the new style.

(From OE-Core rev: b9f366ab4e0a9cad69b631f402b9afa02d40f667)

(From OE-Core rev: 5a1839ecc9a2191252019ddd5c253098006f5bc3)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:41:34 +01:00
Armin Kuster
814bdc8a55 tzcode: update to 2015d
Changes affecting code

    zic has some minor performance improvements.

(From OE-Core rev: 3ab7e247b0662a1791169f16424abec426885f80)

(From OE-Core rev: cdc4fa9e3301cb478d89cf0c1d690e17313b7096)

Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:41:34 +01:00
Richard Purdie
fa87963b35 bitbake: bitbake: cooker: properly fix bitbake.lock handling
If the PR server or indeed any other child process takes some time to
exit (which it sometimes does when saving its database), it can end up
holding bitbake.lock after the UI exits, which led to errors if you ran
bitbake commands successively - we saw this when running the PR server
oe-selftest tests in OE-Core. The recent attempt to fix this wasn't
quite right and ended up breaking memory resident bitbake. This time we
close the lock file when cooker shuts down (inside the UI process)
instead of unlocking it, and this is done in the cooker code rather than
the actual UI code so it doesn't matter which UI is in use. Additionally
we report that we're waiting for the lock to be released, using lsof or
fuser if available to list the processes with the lock open.

The 'magic' in the locking is due to all spawned subprocesses of bitbake
holding an open file descriptor to the bitbake.lock. It is automatically
unlocked when all those fds close the file (as all the processes terminate).
We close the UI copy of the lock explicitly, then close the server process
copy, any remaining open copy is therefore some proess exiting.

(The reproducer for the problem is to set PRSERV_HOST = "localhost:0"
and add a call to time.sleep(20) after self.server_close() in
lib/prserv/serv.py, then run "bitbake -p; bitbake -p" ).

Cleanup work done by Paul Eggleton <paul.eggleton@linux.intel.com>.

This reverts bitbake commit 69ecd15aece54753154950c55d7af42f85ad8606 and
e97a9f1528d77503b5c93e48e3de9933fbb9f3cd.

(Bitbake rev: a29780bd43f74b7326fe788dbd65177b86806fcf)

(Bitbake rev: ed30f4ee1cef8db9ea422c5e54b2375c4f3b1d6f)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

Conflicts:
	bitbake/lib/bb/tinfoil.py
2015-09-01 21:37:20 +01:00
Richard Purdie
d7cad22f48 bitbake: runqueue: Add message to explain the problem if diffsigs multiple tasks don't exist
(Bitbake rev: 8292c64e6edae1bf6f554140e8f603cedbd01047)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:37:19 +01:00
Ross Burton
7ccc4e25a3 gnome: move introspection options to gnomebase
The gnome class is really a convenience class to include other classes, so move
the introspection arguments into gnomebase.bbclass.

(From OE-Core rev: b43a1b244a5ceab52713759dc53b00b162d9d43f)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:47 +01:00
Khem Raj
b64fcadb20 systemd: Remove exporting special CPP
This is no more needed.
it was done long ago while systemd lived in meta-openembedded
http://lists.openembedded.org/pipermail/openembedded-commits/2012-August/141061.html
The accompanying patch has been applied to systemd already so we were
not needing to set CPP for sometime now.

as a nice side effect it helps compiling systemd with clang

(From OE-Core rev: b816e3f520bf71c9b681ccea30c8eefd62fb20a2)

(From OE-Core master rev: e95365400ae1ffb6b650723cfb2c6a67913c740c)

(From OE-Core rev: 981d99d1307b7c36e964ba9b9929b7329169d72b)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:47 +01:00
Sona Sarmadi
7e8bd02a57 icu: CVE-2014-8146-CVE-2014-8147
CVE-2014-8146 icu: heap overflow via incorrect isolateCount
CVE-2014-8147 icu: integer truncation in the resolveImplicitLevels function

References:
[1] https://github.com/pedrib/PoC/raw/master/generic/i-c-u-fail.7z
[2] https://www.kb.cert.org/vuls/id/602540
[3] http://bugs.icu-project.org/trac/changeset/37080
[4] http://bugs.icu-project.org/trac/changeset/37162

(From OE-Core rev: a461a1a9141fb6a3f79bf9773a837daace2e9996)

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:46 +01:00
Alexandru DAMIAN
bdba0dd12d toasterconf: remove master as a branch option from fido release
Toaster isn't designed to be forward compatible. As such,
a release cannot build releases newer then it.

Particularly, "fido" cannot build "master", so we remove
"master" from the list of supported releases in "fido"

[YOCTO #8154]

(From OE-Core rev: bda086118abfb168183dc285357ecbb6dccff5e3)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: brian avery <avery.brian@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:46 +01:00
Khem Raj
4fc8836379 glibc: Consider adding -Wno-error in cases when not using -O2
glibc has recently turned on Werror globally which is good but then not
all option combos are well tested so there still remains cleanup needed
when not using -O2, so lets just disable Werror in such cases, until
fixed upstream

Change-Id: I2d491c360a15b0752c97ff77ee0faaeede6e8d2a
(From OE-Core master rev: 52a90e8e592ddd228939e15d7fd0d69f3c1e816f)

(From OE-Core rev: 6f358676c33854cd6b02f41232875cf779cde1b8)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:45 +01:00
Li Zhou
0b1ea952ad gdk-pixbuf: Security Advisory - gdk-pixbuf - CVE-2015-4491
pixops: Be more careful about integer overflow

Integer overflow in the make_filter_table function in pixops/pixops.c
in gdk-pixbuf before 2.31.5, as used in Mozilla Firefox before 40.0 and
Firefox ESR 38.x before 38.2 on Linux, Google Chrome on Linux, and other
products, allows remote attackers to execute arbitrary code or cause a
denial of service (heap-based buffer overflow and application crash) via
crafted bitmap dimensions that are mishandled during scaling.

(From OE-Core master rev: e27f367d08becce9486f2890cb7382f3c8448246)

(From OE-Core rev: 8e6da2d34ed6e3352e235c1723d6b4f425bd5932)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:45 +01:00
Ross Burton
541876e3e5 systemd: update SRC_URI
Upstream has moved git hosts, so update the SRC_URI appropriately.

[ YOCTO #8181 ]

(From OE-Core master rev: c6166b7ff7ebcab424af975b1e5378813c684560)

(From OE-Core rev: b459e8831dfcb8f4317e115b534567c656efee04)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:44 +01:00
Ross Burton
f08e550a89 systemd-compat-units: set S correctly
This recipe doesn't unpack any source, so set S to ${WORKDIR}.

(From OE-Core master rev: 188a08884d0c1b57d5c8c23f93463399526b19a2)

(From OE-Core rev: 5908df2668c46495f3d9626a7d0e6ce8bb1a2f1f)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:44 +01:00
Umut Tezduyar Lindskog
be837d96fa systemd: update the status of configurable root patch
(From OE-Core master rev: a79afafd422a9b8e74c0eaac6296e6d1802bb994)

(From OE-Core rev: 7cfaac7e7f49303a00247d4ac221b6fe13eed7b9)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:44 +01:00
Chen Qi
cde69ef352 systemd: add PACKAGECONFIG for valgrind
Execute `bitbake valgrind && bitbake systemd -c cleansstate && bitbake
systemd -c configure && bitbake valgrind -c cleansstate && bitbake systemd
-c compile', and we would get the following error.

   src/libsystemd/sd-bus/bus-control.c: fatal error: valgrind/memcheck.h: No such file or directory.

Add PACKAGECONFIG option to sovle this problem.

(From OE-Core master rev: e35ee4e016fbd659c88444ab7ee8e86008984f2c)

(From OE-Core rev: 5a9cf55789f030ce940b8d1c78a75147b4a2b486)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:43 +01:00
Ross Burton
29495d0e8d systemd: recommend the vconsole setup units
systemd's early boot wants to run the vconsole setup units.  They were split out
so that systems without visible consoles don't need the overhead of packaging
kbd etc, but we should pull them in by default.

(From OE-Core master rev: a2e7a94f8d777d1cd9a07e1543b88a0cf1f9cd67)

(From OE-Core rev: dc0a58e396213e3f1131e0f9be4f81bf29f135b2)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:43 +01:00
Kai Kang
704b4bf52c systemd: add PACKAGECONFIG selinux
Add PACKAGECONFIG 'selinux' for systemd. debug-shell.service starts
different shell according whether selinux is enabled.

(From OE-Core master rev: 3d1aa27191fe4c21428eaf4ae036acb1496b7df7)

(From OE-Core rev: a7afb11176a997b65e532c5b4fa2e706a3a27a58)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:42 +01:00
Joshua Lock
38fd01f417 bind: backport patch for CVE-2015-5477
(From OE-Core rev: ba84c727b9c8c743e7ac87e6c84456f679118af8)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:42 +01:00
Beth Flanagan
1f404c9bd8 base.bbclass: Note when including pn with INCOMPATIBLE_LICENSES
We need to be able to tell people if we WHITELIST a recipe
that contains an incompatible licese.

Example: If we set WHITELIST_GPL-3.0 ?= "foo", foo will end
up on an image even if GPL-3.0 is incompatible. This is the
correct behaviour but there is nothing telling people that it
is even happening.

(From OE-Core master rev: c9da529943b2f563b7b0aeb43576c13dd3b6f932)

(From OE-Core rev: 1b449dd0ee88274d01f2ec1f2a22955b824ff8ef)

Signed-off-by: Beth Flanagan <elizabeth.flanagan@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:42 +01:00
Kai Kang
e232ad758a qemu: fix CVE-2015-3209
Backport patch to fix CVE-2015-3209.

http://git.qemu.org/?p=qemu.git;a=commit;h=9f7c594

(From OE-Core master rev: ea85f36ad438353f5a8e64292dd27f457f1f665c)

(From OE-Core rev: d8d68c4a630dc9d802e159f0ffe768e52bea5401)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:41 +01:00
Kai Kang
328d35b53d qemu: backport patches to fix CVE issues
Backport patches to fix CVE-2015-4103, CVE-2015-4104, CVE-2015-4105 and
CVE-2015-4106. These patches are from debian, but they are originally
from:

http://git.qemu.org/?p=qemu.git;a=shortlog;h=c25bbf1

(From OE-Core master rev: 496b3ffba6755bb76709c88cf81399c9d23f830a)

(From OE-Core rev: 29746e78ca000f4464c8e0a1da55c77e02c651e4)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

Refresh the following patches to apply cleanly to our qemu-2.2.0:
07-xen-pt-split-out-calculation-of-throughable-mask-CVE-2015-4106.patch
10-xen-pt-add-a-few-PCI-config-space-field-descriptions-CVE-2015-4106.patch

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:41 +01:00
Joshua Lock
2adb210c8c wpa-supplicant: backport a patch to fix CVE-2015-1863
This fix was included in the master branch with the upgrade
to 2.4, backport it to fido as the vulnerability was already
present in 2.3.

(From OE-Core rev: 12fc04731d26597bfb9d9f1713c96b11c8186c43)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:40 +01:00
Fan Xin
982baf1130 wpa-supplicant: Fix CVE-2015-4141, CVE-2015-4143, CVE-2015-4144, CVE-2015-4145, CVE-2015-4146
wpa-supplicant: backport patch to fix CVE-2015-4141,
 CVE-2015-4143, CVE-2015-4144, CVE-2015-4145, CVE-2015-4146

Backport patch to fix CVE-2015-4141, CVE-2015-4143, CVE-2015-4144, CVE-2015-4145, CVE-2015-4146.
This patch is originally from:

For CVE-2015-4141:
http://w1.fi/security/2015-2/0001-WPS-Fix-HTTP-chunked-transfer-encoding-parser.patch

For CVE-2015-4143:
http://w1.fi/security/2015-4/0001-EAP-pwd-peer-Fix-payload-length-validation-for-Commi.patch
http://w1.fi/security/2015-4/0002-EAP-pwd-server-Fix-payload-length-validation-for-Com.patch

For CVE-2015-4144 and CVE-2015-4145:
http://w1.fi/security/2015-4/0003-EAP-pwd-peer-Fix-Total-Length-parsing-for-fragment-r.patch
http://w1.fi/security/2015-4/0004-EAP-pwd-server-Fix-Total-Length-parsing-for-fragment.patch

For CVE-2015-4146:
http://w1.fi/security/2015-4/0005-EAP-pwd-peer-Fix-asymmetric-fragmentation-behavior.patch

(From OE-Core master rev: ce16e95de05db24e4e4132660d793cc7b1d890b9)

(From OE-Core rev: b236c0882d62d8aa722117a54c1ff9edec7f5a6d)

Signed-off-by: Fan Xin <fan.xin at jp.fujitsu.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:40 +01:00
Yuqing Zhu
38f48913ad gstreamer1.0-plugins-base: Need more buffers in output queue for better performance
(From OE-Core master rev: 4b35871f0883ded624c6d5dd9bbf3365934c0e93)

(From OE-Core rev: 9b3ae2e90f405d3c157d5c3d645b2be6b6216042)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:39 +01:00
Yuqing Zhu
aecebf120b gstreamer1.0-plugins-base: Set need_segment after sink pad receive GST_EVENT_SEGMENT
Subparse works in push mode, chain funciton will be called once
up stream element finished the seeking and flushing.

If set need_segment flag in src pad event handler, the segment
event will be pushed earlier, result in the subtitle text will
be send out to down stream from the beginning.

(From OE-Core master rev: 48742378cd91297db439ee83576f3663befaa8f9)

(From OE-Core rev: 0ecbbc39353d92a66d32ea13075aaec76b590fa0)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:38 +01:00
Yuqing Zhu
dd86cb34e6 gstreamer1.0-plugins-base: Enhance SSA text lines parsing
Some parser will pass in the original ssa text line which starts with "Dialog:"
and there's are maybe multiple Dialog lines in one input buffer.

(From OE-Core master rev: f47e6185a2e88081f98704357e873a04d2e39c40)

(From OE-Core rev: c2e8974e6c9e3e1eb386375a3839b81c23626d43)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:37 +01:00
Yuqing Zhu
36978ade7f gstreamer1.0-plugins-base: Don't set async of custom text-sink to false
Setting async to false will lead A/V sync problem when seeking.
The preroll need to use GAP event instead of setting async to false.

(From OE-Core master rev: c3ed0c2162dcdbb1aced57aed33e2791b81db558)

(From OE-Core rev: 10c4993d4da66ed2eb857b396c24a3771a0bd0d6)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:37 +01:00
Yuqing Zhu
407975a71e gstreamer1.0-plugins-base: Make memory copy when video buffer's memory is read only
Detect the memory flag and use gst_buffer_copy_region with GST_BUFFER_COPY_DEEP
parameter to perform deep memory copy.

(From OE-Core master rev: 817e542096cf2d415b1725ee98a4d3bbf0ed9415)

(From OE-Core rev: 5202a84a67be69259c42bfb109aec1e957783945)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:37 +01:00
Yuqing Zhu
86625d2a59 gstreamer1.0-plugins-base: Do not change EOS event to GAP event
-Sending EOS event instead of GAP event as GAP event has error if A/V have the different duration.

-Stop sending second track EOS event when returing failure after sending the first track EOS.
 Fixed by ignoring the return error.

(From OE-Core master rev: 36dfa24b2a4318b7abe6ab54b64e6c011b8e1e0f)

(From OE-Core rev: 6a8d2055421cb6c82203654eabd67e87ae99fee6)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:36 +01:00
Yuqing Zhu
0c925855f7 gstreamer1.0-plugins-base: Keep sticky events around when doing a soft reset
The current code will first discard all frames, and then tries to copy
all sticky events from the (now discarded) frames. So change the order.

(From OE-Core master rev: 32e88fd0632619c5d3eb95a58a0cceb6f5f6d0d0)

(From OE-Core rev: 17be09863be3804ba58006c8cf622cd0653fed1e)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:36 +01:00
Yuqing Zhu
bdf4d19dc3 gstreamer1.0-plugins-base: Fix output buffer can't writable after frame_map() issue
-Add GST_VIDEO_FRAME_MAP_FLAG_NO_REF
 This makes sure that the buffer is not reffed another time when
 storing it in the GstVideoFrame, keeping it writable if it was writable.

-Use new GST_VIDEO_FRAME_MAP_FLAG_NO_REF to replace the old one because it's kind of ugly.

-Don't ref buffers twice when mapping

(From OE-Core master rev: a618f60675dbcc6568d6b9bdee015456cef78a77)

(From OE-Core rev: b75f09af7c4bfa023299c4f82bd6c3f781b93354)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:35 +01:00
Yuqing Zhu
29ef78c85a gstreamer1.0-plugins-base: Update video alignment after video alignment
Video buffer pool will update video alignment to respect stride alignment
requirement. But haven't update it to video alignment in configure.
Which will cause user get wrong video alignment.

(From OE-Core master rev: d0b5780125926eb33cc82f17c679e16e64312478)

(From OE-Core rev: e2eeca08011abedcba0be8c72dd68557066d4776)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:35 +01:00
Yuqing Zhu
78fa7de4f2 gstreamer1.0-plugins-base: Handle audio/video decoder error
When there is input data and no output data to the end of the stream, it will
send GST_ELEMENT_ERROR and quit from playing.
The patch comments the GST_ELEMENT_ERROR() and just add GST_ERROR_OBJECT()
information instead.

(From OE-Core master rev: 0690a52bf48543351cdc85d2b3c8068d54b51768)

(From OE-Core rev: 0549cb132cbe457dc66f5e8f3df4f61450cb180a)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:34 +01:00
Yuqing Zhu
ad872f2757 gstreamer1.0-plugins-base: Bug fix for id3demux issue
Use g_utf16_to_utf8() instead of g_convert to fix the issue that
id3 tags utf16 charaters cannot be extreacted in id3demux when try
to get the id3v2 tag such as TIT2, TALB etc.

(From OE-Core master rev: 9f8c49862ee67f7f618f102f29f067ec2d712136)

(From OE-Core rev: f8a2ecb6995fdafef175fc084df6ab2d06335764)

Signed-off-by: Yuqing Zhu <b54851@freescale.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:34 +01:00
Joshua Lock
baab91ee8c lib/oe/package_manager: fix opkg feed generation
The insert_feed_uris() method of OpkgPM was creating an initial
entry in the feeds list which pointed to the root of the ipk
directory, however the on-device package manager can't consume
this feed resulting in runtime errors - therefore we remove the
code to generate that initial feed uri.

(From OE-Core master rev: 18e5dcfc610a255e490e4425f11213b8e14c6e00)

(From OE-Core rev: 886a31054808f40b563b7ff5f402f3f0d115759a)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:33 +01:00
Joshua Lock
f22f5b2e52 cairo: make xlib and libxcb dependencies explicit
(From OE-Core master rev: 963ee40b6653741af9a22af7a01ad31bd6ca97a9)

(From OE-Core rev: e4cb0bf63b74c3b5c29850452248c8f4ad09bda7)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-09-01 21:19:33 +01:00
Aníbal Limón
cd2c9acdbd license_class: Fix choose_lic_set into incompatible license
Use canonical_license when doing evaluation of license expresion
since INCOMPATIBLE_LICENSE are already canonized.

[YOCTO #8080]

(From OE-Core rev: 64a4faf66f6d28acf575307079c1843a70efb71c)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-20 11:26:44 +01:00
Reinette Chatre
08f9fbbc97 perf: fix build breakage on kernels after 4.1
A recent commit fixed perf build failures with a change that duplicates
a fix that can be found in kernels after 4.1. Unfortunately there is a
conflict between these two fixes and we see perf build failures when
building perf in kernels that contain the fix already. The problem is
that the fix from the recipe modifies the location of .config-detected
to $(OUTPUT).config-detected. In a 4.2 kernel the location will be
changed to $(OUTPUT)$(OUTPUT).config-detected.

We change the recipe to require a space in the pattern to only change
kernel sources that do not already place file in $(OUTPUT).

The recent commit that introduced the build failure is:

   commit ea9016b60b
    Author: Richard Purdie <richard.purdie@linuxfoundation.org>
    Date:   Sat Jul 25 14:37:58 2015 +0100

        perf: Fix config file conflict with 4.1 kernels

        If you setup mutlitlibs and then:

        bitbake perf libb32-perf
        bitbake perf libb32-perf -c cleansstate
        bitbake perf libb32-perf

        you will see races where the two builds get confused about which directory
        they should be using and they corrupt each other.

        The issue is that .config-detected is created in ${S}, not $(OUTPUT).
        We can fix this by moving the file to $(OUTPUT).

        [YCOTO #8043]

        (From OE-Core rev: 00608cffffb586e8d2a2075117e710113c471448)

        (From OE-Core rev: 57df1ebd910e42af47a0039830a60f41a3bd29b6)

        Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

The commit in the kernel source that fixes the problem from kernel side is:
    commit 642273795fa81da11290ffa90bce6ff242f2a7bb
    Author: Aaro Koskinen <aaro.koskinen@nokia.com>
    Date:   Wed Jul 1 14:54:42 2015 +0300

        perf tools: Create config.detected into OUTPUT directory

        Create config.detected into OUTPUT directory instead of source
        directory.

        This fixes parallel builds that share the same source directory.

        Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
        Acked-by: Jiri Olsa <jolsa@kernel.org>
        Cc: Paul Mackerras <paulus@samba.org>
        Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
        Link: http://lkml.kernel.org/r/1435751683-18500-1-git-send-email-aaro.koskinen@nokia.com
        Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

(From OE-Core rev: 6546771a502a09c63e33679be8784818be0ef93b)

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-12 15:43:36 -07:00
Martin Jansa
5954c4e593 mesa: respect MESA_EGL_NO_X11_HEADERS even with x11 in PACKAGECONFIG
* commit a5ebdb6ad8e4f94ac819275d55575230e057e4ae
  Author: Valentin Popa <valentin.popa@intel.com>
  Date:   Tue Feb 18 13:32:16 2014 +0200
  Subject: mesa: upgrade to 9.2.5

  introduced this do_install_append, but doesn't explain why it doesn't
  respect MESA_EGL_NO_X11_HEADERS flag anymore.

  Not respecting MESA_EGL_NO_X11_HEADERS breaks any build which is using
  qtdeclarative+egl in distribution which has x11 in mesa PACKAGECONFIG
  (e.g. my bitbake world builds).

  The problem is that qtdeclarative is using "None" symbol in
  QSGTexture::Filtering enum, it's possible to rename it in qtdeclarative,
  but it's quite invasive and changes qtdeclarative public APIs, see:
  31aa85787a
  so it was rejected by upstream and I don't want to maintain it in
  meta-qt5 - changing public API in OE build is even worse than if upstream
  does it.

* This change returns MESA_EGL_NO_X11_HEADERS flag so it's relatively
  easy to resolve this conflict in such setups by preventing Xlib.h
  inclusion.

(From OE-Core rev: e5bf7aeac6f6855040e462d0b7cea8c4ea64805a)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Tobias Olausson <tobias.olausson@pelagicore.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
Tobias Olausson
9d9cc9dfbc Revert "mesa: fix do_install_append"
The commit changed an #ifdef to #if defined(), but the source
code for 10.4 branch of mesa still uses #ifdef.

This reverts OE-Core commit 12e467f436fbc22f274558c753f0ac9756ce1071.

(From OE-Core rev: 3eaaa488c811b6a8f7b855f9f2a666d106dbe433)

Signed-off-by: Tobias Olausson <tobias.olausson@pelagicore.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
Kevin Hao
4b824d5bed u-boot: fix extern inline build errors for gcc 5
The gcc 5 change its default standard from gnu89 to gnu11. These two
standards do have different semantics for inline functions. And the
gcc 5 will emit the following errors on the "extern inline" functions:
    arch/powerpc/cpu/mpc8xxx/fsl_lbc.o: In function `ld_le16':
    ./arch/powerpc/include/asm/byteorder.h:12: multiple definition of `ld_le16'
    arch/powerpc/cpu/mpc8xxx/fdt.o:./arch/powerpc/include/asm/byteorder.h:12: first defined here

Fix these build errors by using "-fgnu89-inline" to enforce the gnu89
inline semantics as suggested in [1].

[1] https://gcc.gnu.org/gcc-5/porting_to.html

(From OE-Core rev: a1c83bb5556837d31d934b9af130cdbac19d5e97)

(From OE-Core rev: c07aaa7214ac7e0244ee1b5987dbd2dda5aab286)

Signed-off-by: Kevin Hao <kexin.hao@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
André Draszik
3ff9e84883 opkg-utils: use ${bindir} instead of hardcoding /usr/bin
(From OE-Core rev: 48e04a93c357fb494470d2f175e644a6f43a7d63)

(From OE-Core rev: 65ea72434fe227374147041b4b5fff19d8a18efb)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
André Draszik
01a50376df run-postinsts: use ${localstatedir} instead of hardcoding /var/lib
(From OE-Core rev: 48d735a8938ec7c49754a57019182ebcd9a2d8b6)

(From OE-Core rev: dcfe46aab5ceae780dda52c5bfae38b8918c4614)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
André Draszik
7e9d0f0c7d initscripts: urandom: respect ${localstatedir} instead of hardcoding /var
(From OE-Core rev: 5f3f4196988675e9be5aea8eac56687641b90c10)

(From OE-Core rev: ab9bae919489c22d1969fbb33a5dbc8e1c432847)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
André Draszik
65dfd5efd5 opkg: read config file from ${sysconfdir} instead of /etc
Opkg's configure script doesn't use the value from --sysconfdir to determine
the location of the conf file, it uses the value from --with-opkgetcdir

(From OE-Core rev: d32f7f86b5d2b48222bdaada2697cd5e23cfe1c9)

(From OE-Core rev: dcda6e1e7b95f13dc4a9bb136e6a31c46c76ea9e)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
André Draszik
fac23dfd45 rsync: use ${sysconfdir} instead of hardcoding /etc
(From OE-Core rev: 3bf20e3a67099f54a20c6534fea5db169c63dbec)

(From OE-Core rev: 7f76d444286cf39c58308dde2fb9eed0fee78895)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:45 -07:00
Zhixiong Chi
66941f0c08 dhcp: fix installed not shipped warning for lib32
Modify the dhcp.inc with using the variable ${PN} instead of direct
packagename, so that the content will not be override after expanding
while we build the lib32-dhcp package with FILES_${PN}-xxxx_append.

(From OE-Core rev: c758dcc3109a5b491d13373073214bf526943497)

(From OE-Core rev: 7436d12c9b40502a5e1ec670d76cc9ab755cbaba)

Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Alejandro Hernandez
13e7544ae9 opkg: solve inconsistency of using different lists directories
Default behavior of opkg was to use ${OPKGLIBDIR}/opkg/lists;
but in our recipe we modify it to ${OPKGLIBDIR}/opkg/${OPKGLIBDIR}/opkg/,
when appending package-management to IMAGE_FEATURES these lists are
populated during build time (using the default directory),
but since our config was different these populated lists were never used at runtime,
this patch solves this inconsistency by using default behavior for both build time and runtime.

[YOCTO #6966]

(From OE-Core rev: a71b29ffc514892ca394fc8de275294b910586f0)

(From OE-Core rev: f49fc4fc5c5f150dad9807d92239ada885bca5fd)

Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Roy Li
e2ca16c6d3 alsa-utils: assume the alsa storing is success if machine has no sound card
(From OE-Core rev: eb14c2ea542cf1209a7b743c27a64f82dc907991)

(From OE-Core rev: 9ebfc72eb5674d2f36479ee7ee394a3a6e4fd95b)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Li Zhou
f9a8370345 tzdata: Add marking for config files in recipe
The tzdata recipe does not mark the /etc/timezone file and
/etc/localtime link as configuration files. An on target update would
then overwite the user modified versions of those files.
Add those files in CONFFILES_${PN}.

(From OE-Core rev: 1eefbf6bdf5e720767673a754e95c62f2ffcc82f)

(From OE-Core rev: 75c8f094ddd652e6f91c8f879537c10ec08b7043)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Ed Bartosh
6dd71217a8 wic: Make sure file exists before removing it
Bunch of os.remove calls were added to the partition.py lately.
They're causing wic to fail with OSError: [Errno 2] No such file or directory
if file doesn't exist.

Added check for file existence to all recently added calls of
os.remove. That should fix this regression.

(From OE-Core rev: 75162b05b5ad9aac307f7911caecb2b8a017acbf)

(From OE-Core rev: 41f08393643ceb2607cad44d2c485b3dc9da7ec9)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Alexandre Belloni
417c86b42b wic: remove intermediate partitions
Remove intermediate partitions that may have been created by a previous
wic invocation. Those partitions are causing issues on some systems. In
particular vfat partition creation is hanging on mcopy execution on
Fedora.

(From OE-Core rev: 8d2587d87601a7ff0fad840dabc07d66363b2810)

(From OE-Core rev: 8bea23a89968db3d44b9fae2ceb242dfd89a4880)

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Richard Purdie
ea9016b60b perf: Fix config file conflict with 4.1 kernels
If you setup mutlitlibs and then:

bitbake perf libb32-perf
bitbake perf libb32-perf -c cleansstate
bitbake perf libb32-perf

you will see races where the two builds get confused about which directory
they should be using and they corrupt each other.

The issue is that .config-detected is created in ${S}, not $(OUTPUT).
We can fix this by moving the file to $(OUTPUT).

[YCOTO #8043]

(From OE-Core rev: 00608cffffb586e8d2a2075117e710113c471448)

(From OE-Core rev: 57df1ebd910e42af47a0039830a60f41a3bd29b6)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Bruce Ashfield
3b732f01c9 perf: fix build (and feature tests) for 4.1-rcX
The way that perf detects features has changed/moved via commit e6c76d620
[perf build: Move feature checks code under tools/build].

This code movement resulted in the definition of CC being dropped, and
in turn the passing of --sysroot not part of the build.

This results in feature tests failing with errors such as:

  In file included from test-pthread-attr-setaffinity-np.c:1:0:
  sysroots/x86_64-linux/usr/lib/x86_64-poky-linux/gcc/x86_64-poky-linux/4.9.2/include/stdint.h:9:26:
  fatal error: stdint.h: No such file or directory
  # include_next <stdint.h>
                          ^
  compilation terminated.

While the fix is going upstream, we can modify the perf recipe to add
the definition of CC into the Makefile, and we'll continue to work on
patched and unpatched kernels.

Upstream-status: Pending

(From OE-Core rev: 46f842039422aa35f62b03f11b648c02980ea1b1)

(From OE-Core rev: bff717cb51bfe4a5fb080ebfb6a5e9e0423855f3)

Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:44 -07:00
Kai Kang
f81b891959 volatile-binds: correct path of command umount
It calls /sbin/umount to stop service var-volatile-lib. But umount is
installed into directory /bin. Correct it.

(From OE-Core rev: 55851c6f389cb027496c96f6e0609c8892032e4d)

(From OE-Core rev: a56df1b057b6d77861ac73db6252472ca7e35d08)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Martin Jansa
411a70dea3 connman-conf: fix SRC_URI_append
* add leading space so that it works even with some .bbappend adding
  additional files to SRC_URI without trailing space

(From OE-Core rev: 0f282f1d4946ac6e81959c66172c115405632a26)

(From OE-Core rev: a8dd5d64c2ff2fe8bb4d39260ed82f6bf0d0277f)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Roy Li
4e224f3922 bootchart2: add runtime dependency
Bootchartd needs the command lsb_release and pidof to run, pidof maybe
provided by sysvinit or procpus;
To native bootchart2, only pybootchartgui is used, and which is not needed
both pidof and lsb_release

(From OE-Core rev: d0d641bf8cbf96d7c30dfcbdf2572d2709b56858)

(From OE-Core rev: a8f64210776ee2399d25c6249b4deb715938c4f9)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Chen Qi
2f2b0e8428 nfs-utils: fix to start nfs-server correctly in systemd
Add /etc/modules-load.d/nfsd.conf so that the system loads nfsd at start-up.

Add proc-fs-nfsd.mount systemd unit file because it's needed for nfs server
to start correctly.

After this change, in a systemd based image, we can use `systemctl start
nfs-server' to start the nfs server and things would work correctly.

(From OE-Core rev: 3d4380bb36eb108dc75fee7215b615f7800b0990)

(From OE-Core rev: 27633405aa3509c207d986b434d430f2cd380541)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Joshua Lock
c9f56848e0 systemd: fix immediate unmount of mountpoints not in fstab
Systemd 219 immediately unmounts any mounts which don't exist
in fstab. See FDo bug #89383:
https://bugs.freedesktop.org/show_bug.cgi?id=89383

Patch from Fedora:
http://pkgs.fedoraproject.org/cgit/systemd.git/commit/?h=f22&id=9bbe0e92dc59d5a42258c729b105a7d9901eb35e

(From OE-Core rev: a708514a58fd609b7f8c1a4bd4ab35902681f59b)

(From OE-Core rev: 0cd5a0d5445ff95a8ef4abe24fef705957935e81)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Thomas Perrot
d46acb9296 volatile-binds: Set S to prevent QA warning
Also need to correct the path to COPYING.MIT.

(From OE-Core rev: 4c46a6813772d8d35dd1432dbc59f9ff4b3bd074)

(From OE-Core rev: 82661c1cbc619956bb71fc2ee0f10b4048435414)

(From OE-Core rev: 8a861d4cf062591cf565ec42f3a356f2d0354fa0)

Signed-off-by: Thomas Perrot <thomas.perrot@tupi.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Thomas Perrot
ef7eb171a4 systemd-serialgetty: Set S to prevent QA warning
(From OE-Core rev: c3c240138a38799b611fcc695a51e0c188aa1327)

(From OE-Core rev: 344ed7576603a8202c08a6d28477ef43774a62a8)

(From OE-Core rev: 12d210928c12671dcc98d388f957455e6590c086)

Signed-off-by: Thomas Perrot <thomas.perrot@tupi.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Joshua Lock
65a51fe6bf wpa-supplicant: Apply fix CVE-2015-4142
The cherry-pick from the master branch added the patch file but didn't apply
it in the recipe.

(From OE-Core rev: 375674fa5f2534198036be60972d39e1e6793d3a)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-08-09 16:37:43 -07:00
Richard Purdie
08d3259041 dpkg: Fix for Fedora22 and new versions of tar
They managed to 'break' tar. Again. Sorry, they fixed a regression
which broke dpkg-deb.

The addition of:
http://git.savannah.gnu.org/cgit/tar.git/commit/?id=163e96a0e619a900eab6de827c7c5749ecc9d3f2
("Bugfix: entries read from the -T file did not get proper matching_flag.")
means that the no-recursion option gets lost. This leads to many files getting included
multiple times, along with files which shouldn't be there.

The commit message is horrendous. The patch actually makes the option positional
(as documnted since 2003) and therefore doesn't affect the input from the -T option.

Moving the --no-reursion option to earlier in the command avoids the bug.

The bug was not present in tar 1.28 however it has been backported in at least
Fedora 22 and heading into Fedora 21.

Redhat reports of issue:
https://bugzilla.redhat.com/show_bug.cgi?id=1230762 [tar]
https://bugzilla.redhat.com/show_bug.cgi?id=1241508 [dpkg]

Discussion of bug in upstream tar:
http://www.mail-archive.com/bug-tar@gnu.org/msg04799.html

[YOCTO #7988]

(From OE-Core rev: 6be698b7270f73f40d38713ecf13f12aec0ced61)

(From OE-Core rev: 1c916ddebc3009d3817359144b02745c3ecbd5c4)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-27 12:25:42 +01:00
Jan Wetter
83aa565d93 openssl: upgrade to 1.0.2d
This upgrade fixes CVE-2015-1793
Removed openssl-fix-link.patch. The linking issue has been fixed in openssl.

(From OE-Core master rev: 631632addbc81b06b7accfca8f8a9871d6b09111)

(From OE-Core rev: 7b151426fb8a69cfdd25b7f1de2b506cbcffcac6)

Signed-off-by: Jan Wetter <jan.wetter@mikrom.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-15 15:25:40 +01:00
Roy Li
0b506a72f4 openssl: upgrade to 1.0.2c
upgrade to fix the CVE: CVE-2015-1788..CVE-2015-1792 and CVE-2014-8176
remove a backport patch
update the c_rehash-compat.patch

(From OE-Core master rev: 5a70e45b8c6cb0fa7ea4fe1b326ad604508d00cb)

(From OE-Core rev: 7bc77f508a6ba6a409568be818a1795770261dc6)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-15 15:25:40 +01:00
Roy Li
ee88b51cf2 unzip: drop 12-cve-2014-9636-test-compr-eb.patch
12-cve-2014-9636-test-compr-eb.patch is same as unzip-6.0_overflow3.diff,
is to fix CVE-2014-9636

(From OE-Core rev: 43cc77f6dd1615ec6797a159647a1ad677c1df23)

(From OE-Core rev: 0a849983d066cd1beee64cef94b2c8421275b45c)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:17 +01:00
Roy Li
3773a7d16c unzip: fix four CVE defects
Port four patches from unzip_6.0-8+deb7u2.debian.tar.gz to fix:
     cve-2014-8139
     cve-2014-8140
     cve-2014-8141
     cve-2014-9636

(From OE-Core rev: 2bf9165f5db5edd946a064dc5e877f97817dbae0)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:17 +01:00
Richard Purdie
e4453c98bd oeqa/bbtests: Fix to ensure DL_DIR is set
write_config overwrites the config rather than appends to it, so
ensure we write both variables in one go.

(From OE-Core rev: c94ba6160d5965d4d2071154b43112eb87f4c898)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:17 +01:00
Richard Purdie
23c8b861d1 oeqa/bbtests: Fix race over DL_DIR and SSTATE_DIR
Running "-c cleanall" on shared DL_DIR and SSTATE_DIR is antisocial.
It leads to hard to debug races where we wonder why files disappear
and reappear from those directories.

Fix this by using a specific set of directories for these tests. This
avoids a long standing bug on the autobuilder where aspell and man
sources would disappear.

[YOCTO #6276]

(From OE-Core rev: 6b089c4a79dc3aae00c8a6e7ab0f6ba4b4b5f138)

(From OE-Core rev: f1447c256e027553442cf507e217323f7868000c)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:17 +01:00
Mariano Lopez
a77d2cc81c report-error.bbclass: Added file syncronization.
errorreport_handler would fail if several errors are
triggered at the same time because of two proccess
writting to the same file. This patch add the required
syncronization to handle concurrent process.

[YP #7899]

(From OE-Core rev: c7bff5e7fdd2cbf6f22bfe9a74ceb6e19ef3b5d8)

Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:17 +01:00
Saul Wold
43969db1c7 rootfs.py: Add check for kernel modules before running depmod
Add a check for kernel modules so we don't un-necessarily run the depmods, this
will also handle the case with linux-dummy does not place the kernel-abiversion
since it also does not have kernel modules.

[YOCTO #7884]

(From OE-Core rev: 2b87991be82f4bcf76f8cc3a79bcefc225bae8ba)

Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
fan.xin
8f8327d99b wpa-supplicant: Fix CVE-2015-4142
wpa-supplicant: backport patch to fix CVE-2015-4142

Backport patch to fix CVE-2015-4142. This patch is originally from:

http://w1.fi/security/2015-3/0001-AP-WMM-Fix-integer-underflow-in-WMM-Action-frame-par.patch

(From OE-Core rev: 61f2a6a18dcda22d7b0e236f9150674bff2764a7)

(From OE-Core rev: 844eecf6fdb6c1a835e5c85ba5496ac9182f503b)

Signed-off-by: Fan Xin <fan.xin@jp.fujitsu.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Paul Eggleton
08607f7864 oe-selftest: devtool: fix test_devtool_update_recipe_git
Make this test work after recent changes to the mtd-utils recipe, and
hopefully make it robust against any future changes.

(From OE-Core rev: 5be62624a6537659f9f6229c82762da45909f902)

(From OE-Core rev: fd4b4390af0bcbfdaee0d4ddbc6766d7775c52d0)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Khem Raj
2468978cb4 mtd-utils: update to latest and fix static inlining
use static storage class instead of extern for inline functions
and remove duplicate definitions as a result

Change-Id: I72e8c5f19dff656c18f719d1e9e2ca697c9a856f
(From OE-Core rev: 1a9d92b9891c06ede91af05d516a429e1f81777d)

(From OE-Core rev: efada40a7a785446f9c46aa8a7d0e1c7407376e9)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Khem Raj
5bda039a8e u-boot-mkimage: Backport fix from upstream to fix build with gcc-5
Change-Id: I5322f1ff8653009b45ddee1a2d3a0d96584d3327
(From OE-Core rev: 54fc9c0d1cc5cafa44e4b392ef087900e4102464)

(From OE-Core rev: 4de87a731b71a1764ec53ff2782c184a69638fc0)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Andreas Oberritter
8fd70a3d70 gdb: Add missing runtime dependency for python option
With python enabled, gdb refuses to start without core
python modules:

| Could not find platform independent libraries <prefix>
| Could not find platform dependent libraries <exec_prefix>
| Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]
| ImportError: No module named site

It also complains if python-codecs is missing.

(From OE-Core rev: 646adb4d90030970f6e2136f65b51b3c8b0c9d5c)

(From OE-Core rev: c1c2c9c7f20b289928c94beb7adfe03f03c4b64e)

Signed-off-by: Andreas Oberritter <obi@opendreambox.org>
Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Kang Kai
0e2c483f7d gst-plugins-bad: fix CVE-2015-0797
Backport patch from debian to fix CVE-2015-0797.

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=784220
https://sources.debian.net/data/main/g/gst-plugins-bad0.10/0.10.23-7.1+deb7u2/debian/patches/buffer-overflow-mp4.patch

Backported to oe-core fido from meta-oe/meta-multimedia:

http://git.openembedded.org/meta-openembedded/commit/?id=6cb3b63559bf33946f1c5d43626413d9a651e83f

(From OE-Core rev: 7aa1090d22459bff1159f8193b60166a079d5bd6)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:16 +01:00
Andre McCurdy
010a940ba1 gnutls: use pkg-config to locate zlib
AC_LIB_HAVE_LINKFLAGS can sometimes find host libs and is therefore not
robust when cross-compiling. Remove it for zlib and use PKG_CHECK_MODULES
instead.

(From OE-Core rev: 78a0e916882a747c267808c08ab8bc615198b5a8)

(From OE-Core rev: aaeacca50808e12eb81a373972c802d3f01c01af)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Richard Purdie
5977435538 lib/devtool/standard: Fix patch cleanup
If patches fail to apply with git, quilt it used as a fallback. If that
happens, the code in this class is meant to handle cleanup of these patch
files. In the case where ${S} is a subdir of the git tree, the code doesn't
correctly set the patches directory.

This change correctly sets the patches directory (which is different to the
location of the git repository).

[YOCTO #7911]

(From OE-Core master rev: de6e0f3af5e858960676ea291036e59105fd806f)

(From OE-Core rev: 03dbc60c165a511894d1ae10ac1d90c1fadcc268)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Saul Wold
5cdbf0ad06 binutils: Add -momit-lock-prefix support
This patch is needed for certain cpus and has been accepted into upstream

(From OE-Core rev: 3371b42a4ac5becb063157f1b258918601211ebf)

Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Richard Purdie
33973cd841 lib/oe/patch: Fix git patch application for source in subdirectory
Similarly to:
http://git.yoctoproject.org/cgit.cgi/poky/commit/meta/lib/oe/patch.py?id=f205ccaf48ac36f4b26efc4aeb2e9d2939b28646
we need to fix patch application for source which is in a subdirectory.

Passing "." as the git directory or work-dir appears to work (or is ignored)
in some versions of git but does not work in others, probably quite correctly.

Since we have reporoot from the above patch, pass this in directly.

This bug caused this sanity test failure on some machines:

FAIL: test_devtool_modify_git (oeqa.selftest.devtool.DevtoolTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/pokybuild/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/meta/lib/oeqa/selftest/devtool.py", line 390, in test_devtool_modify_git
    self.assertEqual(result.output.strip(), "", 'Created git repo is not clean')
AssertionError: '?? util/mkelfImage/patches/' != '' : Created git repo is not clean

since git apply would fail, it would then fall back to quilt
and the git tree would be left unclean.

[YOCTO #7911]

(From OE-Core rev: 91d76e632336d6af96f24bcf92be25f41a216856)

(From OE-Core rev: e35e40c95a067376634d7b019f4c1d3db724ceae)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Richard Purdie
cfb195ae80 oeqa/parselogs: Whitelist qemumips64 runtime error
Similarly to qemumips, ignore these errors upon bootup so that
we have a good QA baseline for new errors.

(From OE-Core rev: bb404d1727e6744e52d01d3c52bef3266bd3d1ac)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Richard Purdie
55eee7ae3c testimage: Don't test xorg/vnc on qemuarm64
The qemuarm64 machine doesn't have graphics so don't test xorg/vnc
as they won't work.

[YOCTO #7103]

(From OE-Core rev: 89f085fcabbacf524bfa84328e41fd95492f1ffa)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:15 +01:00
Richard Purdie
0ece3d8ab5 oeqa/parselogs: Whitelist qemuarm64 runtime errors
The qemuarm64 machine doesn't have graphics so whitelist the
X server failures to start.

(From OE-Core rev: 716d4a3525d19a15f5506c4ceff80fa5b4f55342)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:14 +01:00
Leonardo Sandoval
1137495bbd terminal.py: Allow devshell/menuconfig on recent gnome-terminal
Recent versions of gnome-terminal does not support non-UTF8 charset:
https://bugzilla.gnome.org/show_bug.cgi?id=732127 as a result, devshell and
menuconfig tasks silently hang  (error found on trace log of 'strace -f -v
-s 8192 -e write=2 bitbake -c devshell quilt-native': "Non UTF-8 locale
(ANSI_X3.4-1968) is not supported!"). As a workaround, clearing the LC_ALL
environment variable so it uses the locale. Once fixed on the gnome-terminal
project, this should be removed.

Tested on gnome-terminal versions:

       GNOME Terminal 3.4.1.1
       GNOME Terminal 3.14.2 (Default on Ubuntu 15.04)

[YOCTO #7791]

(From OE-Core rev: e0807cdfaa8bcb7cbf08386c3696883a7df26f46)

Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-07-08 13:07:14 +01:00
Richard Purdie
58b038b778 bitbake: cooker: Fire BuildCompleted before finishing the command
Some handlers hook on BuildComplete so it avoids certain event races
to finish the command after the BuildComplete event is sent out.

This means the UI is available to handle events until the command
completes.

What appears to be a race on one of the sanity tests for event handlers
triggered this change although the failure is hard to reproduce.

[YOCTO #7921]

(Bitbake rev: ac66fac162e68b568f986fe1917772e61c982f8e)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-29 09:49:12 +01:00
Richard Purdie
f6430d42b4 subversion: Fix subversion-native on Fedora22
Similarly to:
http://git.yoctoproject.org/cgit.cgi/poky/commit/?id=9b19d6548a345009a6de79a6820c07a72054d961

we also need to fix the subversion-native case with gcc5 by using
the same fix to the BUILD_CPPFLAGS.

(From OE-Core rev: a5e7a1e597e7bbe3bbc547f43a89d00a8a9a9924)

(From OE-Core rev: 7d445547df528aa9e5bfb85568a7270e27f633ef)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:45:42 +01:00
Khem Raj
b24aeb7b42 subversion: Add -P to CPPFLAGS
see https://gcc.gnu.org/gcc-5/porting_to.html

we need to stop the preprocessor from generating the #line directives
or we run into issues like

| checking for apr_int64_t Python/C API format string...
| configure: error: failed to recognize APR_INT64_T_FMT on this platform
| Configure failed. The contents of all config.log files follows to aid
debugging
| ERROR: oe_runconf failed

Rightly subversion should be fixed but lets leave that to subversion
folks

Change-Id: I02a89798ff949f79967ab0a73adcddaa4218662d
(From OE-Core rev: 7793b1c425077ed6ed11a9bc2a8b1b96612b1c96)

(From OE-Core rev: a240d28492f05c22198dd4b20c11c0d510f0c897)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:45:42 +01:00
Chen Qi
1cd4b260b5 bitbake: bitbake-diffsigs: consider the situation where sigdata and siginfo files having the same hash values
For now, `bitbake-diffsigs -t <recipe> <task>' doesn't work. It always outputs
nothing.

The problem is that bitbake-diffsigs are comparing sigdata and siginfo files
that have the same hash value. This is not what we want. These two files are
actually duplicates considering the purpose of bitbake-diffsigs. So we need
to remove one of them so that bitbake-diffsigs could actually compare the
correct signature files.

(Bitbake rev: e14873d6847fae8abd3baf4bdc804d52d3b0c4f5)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Marcin Smoczyński
5ce20aeb02 bitbake: fetch/git: Fix uri in git checkstatus
Pass proper repository url without arguments after a semicolon.

Executing checkuri on a rule with git repository in SRC_URI does
not report errors when working offline because wrong repository
url is passed to the ls-remote command. For example
"bitbake -c checkuri glibc" command executes:
"git -c core.fsyncobjectfiles=0 ls-remote git://sourceware.org/git/glibc.git;branch=release/2.21/master"
command in a shell subprocess to determine if url is valid.
Shell subprocess executes in fact 2 commands:
"git -c core.fsyncobjectfiles=0 ls-remote git://sourceware.org/git/glibc.git"
and
"branch=release/2.21/master"

First one returns 127 or 128 depending on error but second one
returns 0 because it is just env variable setup. Therefore we're not catching
connection error.

[YOCTO #7558]

(Bitbake rev: cb8224f0c73c06879783665e2de39ecca7f6a350)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Jagadeesh Krishnanjanappa
9c245f1d79 runqemu-internal: set mutual exclusiveness for serial and nographic options
Use "-nographic" option only if "serial" option is not
specified. Otherwise we get below error when
'runqemu <kernel_image> <rootfs_image> serial' is executed,

(snip)
QEMU 2.2.0 monitor - type 'help' for more information
(qemu) qemu-system-aarch64: -serial stdio: cannot use stdio by multiple
character devices
-- CUT --

(From OE-Core rev: 8b0527951ab71c4a4dc4d1238cd9e9e60a6eb5ee)

(From OE-Core rev: c3a44794de957b216aaea19da371657194c86fc3)

Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Jagadeesh Krishnanjanappa
d3959f672a runqemu-script: define console for qemuarm NFS booting
Add console=ttyAMA0,115200 as one of the boot parameters
for qemuarm, in order to print bootlog messages on the
console.

(From OE-Core rev: 2d2db8f517ea719f097c957559175a07ecee82ad)

(From OE-Core rev: 7113153c50e0d9bb04c6b422be2c75152f3105c9)

Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Jagadeesh Krishnanjanappa
e9c47914f2 runqemu-internal: add support to boot arm64 qemu target via NFS
Add required boot parameters inorder to boot arm64 qemu
target via NFS

(From OE-Core rev: 0b614317b38b933a4845cd006b0ad734adfa559d)

(From OE-Core rev: 4311b8f59b2a551f2928a4705d4e85901a39995e)

Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Jagadeesh Krishnanjanappa
fed3899694 runqemu: fix MACHINE being detected as qemuarm for qemuarm64 kernel image
Basically, runqemu script autodetects MACHINE type based on the
kernel image name; if MACHINE name is not specified. Since 'qemuarm'
string is common in both qemuarm amnd qemuarm64 kernel image names, the
MACHINE type is considered as 'qemuarm' even when qemuarm64 kernel
image name is given in command line.

(From OE-Core rev: 388b243668a5c28fb69b760ce9be5adbc85352d8)

(From OE-Core rev: eeae1fb7afd30174616cfec6204b4c97c94879ca)

Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:19 +01:00
Aníbal Limón
6ae42d8851 classes/license.bbclass: Improve generic license copy validation.
Remove + char in any position for cover cases when license has
the form like GPL-2.0+-with-OpenSSL-exception.

[YOCTO #7584]

(From OE-Core rev: 9cff9d4e8c8ca7d6f41c4df16e484087213ae990)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Alejandro Hernandez
f76f0555b9 python3-ctypes: Fix cross compilation for arm targets
When cross compiling for arm targets ctypes compilation fails because
it uses _sysconfigdata from the HOST, this patches makes it use the
one from TARGET fixing compilation of this module

[YOCTO #7873]

(From OE-Core rev: a676ee838aae1ac05fa6542d1b0791d61ff9f05f)

Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Jonas Göransson <jonas.goransson@qmatic.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Jussi Kukkonen
affbc3f649 dbus: CVE-2015-0245: prevent forged ActivationFailure
Fix CVE-2015-0245 by preventing non-root and non-systemd processes
from fooling the dbus daemon into thinking systemd service activation
failed.

(From OE-Core rev: 961aaa50ed363a680b08be77a44ac13ce984b2f3)

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Mark Hatle
919c7bf5c6 rpm: Fix lua 'print' statement capture
The print statement should capture the output and send it to the script
processing engine, and not display it directly to the screen.

Note, this is only a bug if 'lua' support has been enabled in the RPM
recipe's PACKAGECONFIG.

This patch is from: http://rpm5.org/cvs/patchset?cn=17671

(From OE-Core rev: 6bc0e8207d0e7b1d6f2eac8ed1b75a3fd9fab87b)

(From OE-Core rev: 7d4230b7eb7aa09087a6267dd6e686f713ac6f72)

Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Leonardo Sandoval
e4f3e5440b rpm: Fix CVE-2013-6435
Backport to fix CVE-2013-6435. Description on [1] and original
patch taken from [2].

[1] https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2013-6435
[2] https://bugzilla.redhat.com/attachment.cgi?id=956207

[YOCTO #7181]

(From OE-Core rev: 6bf846ed5ccd1a4d01b36630708b2b9aa9e69ed5)

(From OE-Core rev: 0e26cd974a97f5a8543cb4153a83d1fa977a3468)

Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Leonardo Sandoval
274d571316 rpm: Fix CVE-2014-8118
Backport patch to fix CVE-2014-8118. Description is on [1] and
original patch taken from [2].

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1168715
[2] https://bugzilla.redhat.com/attachment.cgi?id=962159

[YOCTO #7181]

(From OE-Core rev: 0a1f924157cb75d0f67cf534762c89dc8656d352)

(From OE-Core rev: e90be120d2751ac95c88abf7ba7bcac2c8fe7d0b)

Signed-off-by: Leonardo Sandoval <leonardo.sandoval.gonzalez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Roy Li
f3324915ff babeltrace: Fix invalid pointer free with trace collection
This fixed the bug https://bugs.lttng.org/issues/790

(From OE-Core rev: 8152bcadba8581f75822b75e13c2a43dd6464cd3)

(From OE-Core rev: 8a406a67704bc81c104c18581ba11c5e99a7e0ca)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Alejandro Hernandez
e834984ce7 distutils: regenerate pyc files after being modified by sed
py files are edited by sed and therefore *.pyc files are recreated on first boot, but if you have a read-only filesystem this is not possible. This patch creates pyc files directly after the py files are modified.

[YOCTO #7722]

(From OE-Core rev: a0460ac8a2595d4b064b483ca1f282a255ae6411)

(From OE-Core rev: 46e9e59510e19a3ab22bdeb09f3de7bac1030f38)

Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Thomas Roos <roosesweb@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:18 +01:00
Joshua Lock
aa88803046 distutils-common-base: add to, don't set, FILES_${PN}
If we set FILES_${PN} and a recipe inherits other classes that
modify FILES_${PN} *before* distutils-common-base is included, any
changes to FILES_${PN} made by those classes are lost.

Instead, append the additional directories we want to include in
FILES_${PN}

(From OE-Core rev: f6478e8c73f9cfb79d1f7680b7bf3ff957eb51cb)

(From OE-Core rev: 3e5ecb970eec3ba3199d2fc2a336d310f072594c)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Richard Purdie
903cf70f3a wayland: Fix hardlink corruption issue
The way this code was working, the m4 file is hardlinked to the
copies which would be packaged and could lead to the native m4
file being used in the target packages.

By removing the file first the hardlink is broken and this avoids
corruption (since cp uses open to change the file contents).

(From OE-Core rev: 8f3be1925b9da20526a722149b03f697247ea1bf)

(From OE-Core rev: 2ac51bcace97d16ca678d85e0100611fecfd818c)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Yue Tao
8045026d49 libxml2: Security Advisory - libxml2 - CVE-2015-1819
for CVE-2015-1819 Enforce the reader to run in constant memory

(From OE-Core rev: 9e67d8ae592a37d7c92d6566466b09c83e9ec6a7)

(From OE-Core rev: d1288821b709f47f48bbdb6764f1a35bf2589de7)

Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Krishnanjanappa, Jagadeesh
60836f602a valgrind: add configure option to build only 32-bit or 64-bit components
Building both 32-bit and 64-bit binaries in valgrind at a time would
lead to following QA issue as below,

(snip)
 ERROR: QA Issue: Architecture did not match (62 to 3) on ${WORKDIR}/valgrind/3.10.1-r0/packages-split/valgrind-dbg/usr/lib64/valgrind/.debug/vgpreload_exp-sgcheck-x86-linux.so
 ERROR: QA Issue: Architecture did not match (62 to 3) on ${WORKDIR}/valgrind/3.10.1-r0/packages-split/valgrind-dbg/usr/lib64/valgrind/.debug/getoff-x86-linux
 ERROR: QA Issue: Architecture did not match (62 to 3) on ${WORKDIR}/valgrind/3.10.1-r0/packages-split/valgrind-dbg/usr/lib64/valgrind/.debug/vgpreload_core-x86-linux.so
 ERROR: QA Issue: Architecture did not match (62 to 3) on ${WORKDIR}/valgrind/3.10.1-r0/packages-split/valgrind-dbg/usr/lib64/valgrind/.debug/vgpreload_memcheck-x86-linux.so
-- CUT --

hence perform only one type of build 32-bit or 64-bit, but not both.

(From OE-Core rev: 53afa26655d0b5f75ef2dd6bccef76281a14655c)

(From OE-Core rev: cc79ca38c6f8af4f47fb1e466a836bc8764cd938)

Signed-off-by: Krishnanjanappa, Jagadeesh <jagadeesh.krishnanjanappa@caviumnetworks.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Khem Raj
179c17970a grub: Backport const qualifier fix for gcc-5
gcc-5 is stricter and complains about const to non-const
conversions, we backport the patch from upstream into 2.00

Change-Id: I17db365fdd253daaa1ab726e2a70ecad0ac7b2ae
(From OE-Core rev: ea3d48471db19a2432e4afd86df8caad51ee5166)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Martin Stolpe
e118d980da ncurses: fix native builds when host has gcc5
GCC"s preprocessor starts to add newlines which are not
handled properly by ncurses build system startin from
version 5.0.

See also: https://bugzilla.yoctoproject.org/show_bug.cgi?id=7870

(From OE-Core rev: 3a5435b371c84ec28b6936b8c8fa6541a592d061)

Signed-off-by: Martin Stolpe <martin.stolpe@gmail.com>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
George McCollister
45d0819daf binutils: fix native builds when host has gcc5
Cherry pick upstream commit to fix -Werror=logical-not-parentheses error
when building with native gcc5.

(From OE-Core rev: b3bd0dba3139a3e79bfcebe137248c7bdcadf04d)

Signed-off-by: George McCollister <george.mccollister@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Kai Kang
4acf353ffd qt4: fix CVE issues
Backport patches to fix qt4 CVE issues:

* CVE-2015-1858
* CVE-2015-1859
* CVE-2015-1860

(From OE-Core rev: e57a090d8f806f55b99649e072b4d2dde6f036ee)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:17 +01:00
Aníbal Limón
4dd8c7e805 license_class: Add explicity avoid of CLOSED license in validations
The CLOSED license isn't a generic license it is a set and can
be any closed source license.

[YOCTO #7752]

(From OE-Core rev: 56c673af4363a9c690eabff8b1fdaa202efb95ce)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Robert Yang
a8d4f5cd2b libpostproc: pass correct libdir
When MACHINE=qemux86-64 and enable multilib:
ERROR: QA Issue: libpostproc: Files/directories were installed but not shipped in any package:
  /usr/lib
  /usr/lib/libpostproc.so.52.3.0
  /usr/lib/libpostproc.so
  /usr/lib/libpostproc.so.52
  /usr/lib/.debug
  /usr/lib/.debug/libpostproc.so.52.3.0
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install. [installed-vs-shipped]

Pass the right libdir to configure as otherwise it assumes $prefix/lib
which may be wrong.

(From OE-Core rev: 7cb4ca779a01c3ce935682373fe2a5b02abc91a2)

(From OE-Core rev: 0dc77f11553b5d50cb186f2cc00df28ecea07bb6)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Lei Maohui
3716298102 cracklib:Fix an error in the patch
To fix an error in the patch.Otherwise,the dictionary would be wrong.

(From OE-Core rev: 8670b99b06ce14ed391b4713d7887af90d44a2c8)

(From OE-Core rev: 6dde232fc4943ddb55e8d895610afc39e92526d6)

Signed-off-by: Lei Maohui <leimaohui@cn.fujitsu.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Robert Yang
ed010c7a38 sysstat: DEPENDS on base-passwd
Fixed:
| install -m 644 -g man man/sa1.8 /path/to/tmp/work/i586-poky-linux/sysstat/11.1.4-r0/image/usr/share/man/man8
| install: invalid group `man'

(From OE-Core rev: 153c3dd4d4c5eab52b953901fb6bc681c349a710)

(From OE-Core rev: ddaedc9fe601469cdd5bf9e87754e8a4aa549081)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Robert Yang
3746f83469 gstreamer1.0-libav: fix build for i586 with gcc
Backport a patch from debian to fix the build for i586 with gcc, the
patch is similar to libav's
workaround-to-build-libav-for-i586-with-gcc.patch.

(From OE-Core rev: 186df51c49987b44bfcf21d133ad9fe80f0790bb)

(From OE-Core rev: 99ce2b9624f35f0e775dc9559b04322ae8e08bfc)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Dave Lerner
4a2af0eaa9 valgrind: remove arm tests that don't compile
[Yocto #7453]

Corrects the original commit for the patch that removed ARM ptest CFLAGS
settings. Since the flags could be set by a user, the flags should
be kept in place during compilation.  By keeping the original up-stream
CFLAGS for the tests, then additional tests successfully compile
for all tested ARM tunings.

However, there were still two tests listed below that did not compile
for any beaglebone tuning that is valid for valgrind. With the updated
patch, the set of excluded ARM ptests and their respective build
failures are:
  intdiv - fails for all beaglebone tunings with 2 errors:
  {standard input}:(40 or 41): Error: selected processor does not
       support Thumb mode `udiv r3,r9,r10'
  {standard input}:(72 or 73): Error: selected processor does not
       support Thumb mode `sdiv r3,r9,r10'

  vcvt_fixed_float_VFP - fails for all beaglebone tunings in one of
  two ways:
    with neon tuning (-mfpu=neon) fails with Internal Compiler Error
    without neon tuning fails with 3 errors:
    {standard input}:33: Error: selected FPU does not support
      instruction -- `vcvt.f32.s32 s15,s15,#1'
    {standard input}:58: Error: selected FPU does not support
      instruction -- `vcvt.f32.s32 s15,s15,#32'
    {standard input}:136: Error: selected FPU does not support
      instruction -- `vcvt.f32.u32 s15,s15,#1'

After applying this commit, the valgrind ARM ptests compile without
errors for tunings:
  armv7[t][hf][b][-neon] cortexa8[t][hf][-neon]
where the tuning [option] was successfully compiled, both with
and without the 'option', and in combination with all other options.

(From OE-Core rev: 2fb0edcb47a14e47780d545f60885b36e71fca71)

(From OE-Core rev: 132886498816f6407416196fd5ccf8d1b8c589ab)

Signed-off-by: Dave Lerner <dave.lerner@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Yue Tao
c75869a7f8 libsndfile: Security Advisory - libsndfile - CVE-2014-9496
Backport two commits from libsndfile upstream to fix a segfault and
two potential buffer overflows.

(From OE-Core rev: 9907e20868397a9823cc1e755ee1b697da6be2f3)

(From OE-Core rev: 82b481afc21604603b9c2d6c6b4c428d445cad92)

Signed-off-by: Yue Tao <Yue.Tao@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Richard Purdie
d31b9e6326 soc-family.inc: Add a default SOC_FAMILY value
Otherwise, if MACHINEOVERRIDES is expanded before SOC_FAMILY is set
(which may happen as MACHINEOVERRIDES is included in OVERRIDES) we can
see:

ExpansionError: Failure expanding variable MACHINEOVERRIDES, expression was
${@['', '${SOC_FAMILY}:']['${SOC_FAMILY}' != '']}p1022ds
which triggered exception SyntaxError: EOL while scanning string literal (MACHINEOVERRIDES, line 1)

To avoid this, give SOC_FAMILY a default empty value so it doesn't
get read as None.

(From OE-Core rev: dee005b6e1bc353230f9f27a469b2054a644e542)

(From OE-Core rev: 7c763846bca4347d6b9e8cc388ad075f00123235)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:16 +01:00
Richard Purdie
20eab30866 base: Fix license checksum rebuild problems
"MACHINE=qemux86-64 bitbake init-ifupdown; MACHINE=genericx86-64 bitbake init-ifupdown"
shows a rebuild when it would be expected. The reason is a LIC_FILES_CHKSUM which
contains file://${WORKDIR}, an absolute path which doesn't exist in the first build
but does in the second, causing a signature change and a rebuild.

Fix the problem by ignoring any file:// url which resolves since TMPDIR for
license file dependency purposes.

(From OE-Core rev: f27ddf0de23871fc72cfc31f514f0e144aaa2082)

(From OE-Core rev: d88bb3759c36f2a30550529468c8a8c511b1661c)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
d7f6451ad1 oe-selftest: devtool: add a proper test to see if tap devices exist
Check up front in test_devtool_deploy_target whether the tap devices
exist and skip if not. If we don't do this we get a significantly less
comprehensible error via pexpect.

(From OE-Core master rev: 2258345e19efff7717fe19a5026ec55f1b6f90b6)

(From OE-Core rev: cdad3ea375590f6fa9330f481b6712681ad00cd2)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
520c455b83 devtool: if workspace layer exists, still ensure it's in bblayers.conf
When we run devtool, if the workspace layer already exists but isn't in
bblayers.conf (perhaps because it was previously created but
subsequently removed from bblayers.conf by the user) then we should add
it and notify the user, otherwise devtool operations won't work.

(From OE-Core master rev: 313b622a6c6613092ed18a2158e090521344f6c0)

(From OE-Core rev: 2904c1130ea7cc1abde0609f1ba1394e0f31a6fa)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
b317d79fb7 devtool: fix build env command execution error handling
If we execute an external command, we ought to prepare for the
possibility that it can fail and handle the failure appropriately. We
can especially expect this to happen when running bitbake in this
scenario. Ensure we return the appropriate exit code to the calling
process.

Fixes [YOCTO #7757].

(From OE-Core master rev: 98a716d79bfc5434a5b42d3ca683eab3eea30a41)

(From OE-Core rev: 2791fe9236f7173e6b998cf9b40fe238566ed8ee)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
8c9551a7a3 recipetool: ensure git clone is standalone when extracting
If -x is specified and the specified URI was a git repository, we need
to ensure that the resulting clone is a sandalone and not one that has
pointers into the temporary fetch location or DL_DIR (since the git
fetcher does a local clone with -s). Split out the code from devtool
that already does this for "devtool modify -x" and reuse that.

(From OE-Core master rev: fc47e8652ef32e7399f57c80593df90dc52d8b84)

(From OE-Core rev: d8f151b6a385f81abead65624ba15d42cbd90e11)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
6bc56e634a recipetool: avoid second-level subdir when extracting
When -x was specified, we were getting the normal unpack subdirectory
which we don't really want - if there's only one subdirectory unpacked
then we should effectively copy just it to the extraction path, not as a
subdirectory under it.

(From OE-Core master rev: 0eeecce96a0aa757c2c4c4ac4d82e3bcbf0f982c)

(From OE-Core rev: 3378c932570ba2301cd02103225fcf7629de656f)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:15 +01:00
Paul Eggleton
f64d73f8c4 devtool: update-recipe: check if source tree is a git repository
If you've done "devtool add" (or "devtool modify" without -x) then it's
possible that the external source tree is not a git repository, so we
should handle that case here instead of printing a traceback.

(From OE-Core master rev: eb2147aa8facd4ef33a0749e9ae660ec686dad48)

(From OE-Core rev: c5dc3e819c1bb224e3cb667381faa5abf1888362)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Paul Eggleton
f1d3b5f185 devtool: update-recipe: handle unversioned bbappends
Use the proper bbappend file name, don't just assume it will have a
version suffix (because it won't if the original recipe doesn't).

Fixes [YOCTO #7651].

(From OE-Core master rev: 3332d68ef7b2a300ce8dcf5021497d98e5b17baa)

(From OE-Core rev: 3d5ea16a1f53c12d86c4e8df6af864964541cf02)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Paul Eggleton
d1b6e1dfdb devtool: add: use correct bbappend file name with -V option
We weren't adding the version into the bbappend file name when -V was
specified which meant that building or resetting failed.

Also adjust one of the tests so that we're testing devtool add both with
and without this option.

Fixes [YOCTO #7647].

(From OE-Core master rev: bdbeff0cd342e31053d7203d78fc5dda611052b1)

(From OE-Core rev: 0b9e8817fc8ba375a1045a66d04b3fd2b498427b)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Paul Eggleton
2bc3328b8b devtool: handle . in recipe name
Names such as glib-2.0 are valid (and used) recipe names, so we need to
support them.

Fixes [YOCTO #7643].

(From OE-Core master rev: b9fd8d4d4dfae72de2e81e9b14de072e12cecdcf)

(From OE-Core rev: 36df1bb9bb3c92d096118b74fdf11a243be3f7d5)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Markus Lehtonen
d768a80391 devtool: include bbappends in recipe parsing
In order to get correct metadata, SRCREV for example.

Fixes [YOCTO #7648].

(From OE-Core master rev: 8b1794559dd7fd956716179d628e61cffdce1686)

(From OE-Core rev: becbd5d50a091fe4a980361d9c99efa01f43edcc)

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Markus Lehtonen
66dd73d1d1 devtool: modify: implement --no-same-dir
This option can be used to have a separate build directory, in order to
keep the srctree directory clean for packages that do not need to be
built in the source directory.

(From OE-Core master rev: 5cc348c0a3016e4ccc1e80d099e2e197b3b38bd2)

(From OE-Core rev: a7316a4c564901b30af740ece6631a6f68355bb4)

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Markus Lehtonen
eabd7359d1 devtool: modify: use B=S if that is the default for the recipe
Makes the build succeed for packages which do not support separate build
directory, e.g. zlib. The same outcome could be achieved with the
--same-dir option, but, it's generally hard to tell if a random package
would need that option. The negative side effect of this patch is that
dev srctree (of some packages that build fine without this modification)
gets dirtied by build artefacts.

(From OE-Core master rev: 6ac5692426956e276ba2119f917b0f30791e6cd6)

(From OE-Core rev: 97078c56e8b8a235e923d964253775e20112a36f)

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
Acked-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Markus Lehtonen
af86c079dd devtool: call parse_recipe with correct arguments
Give the correct data object ("config data" instead of "recipe data") as
an argument to oe.recipeutils.patch_recipe()

Fixes [YOCTO #7595]

(From OE-Core master rev: 7d2b918019b0afe215a6489dad697afac34f73e9)

(From OE-Core rev: f8427fe565e44e46246146bdaae66a5d83ae8c9d)

Signed-off-by: Markus Lehtonen <markus.lehtonen@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:14 +01:00
Roy Li
a8d1d48cba rsync: backport a patch to fix CVE-2014-8242
(From OE-Core rev: 81d06ef0a566793e644686ec604ad7d46546d2b0)

(From OE-Core rev: 2ebf9ad9791e4b38465bfc456aac1d6009078d82)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Andre McCurdy
34afb7cb38 glibc: Fix __memcpy_chk on non-SSE2 CPUs
Backport from upstream glibc:

  https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=132a1328eccd20621b77f7810eebbeec0a1af187

Note that the fix is only required when glibc is built for i686/multiarch,
so is not applicable in the default oe-core x86 configuration (which builds
glibc for i586 and therefore does not include SSE2 optimised memcpy etc).

(From OE-Core rev: e643b9bc4c459ea8b59573cf67f2494388e7a377)

(From OE-Core rev: 38b0095c3a3416725ef5f19ab940e84f45a8a01a)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Martin Jansa
606a6d36de squashfs-tools: build and install unsquashfs as well
* it's useful for debugging corrupt squashfs images from mksquashfs

(From OE-Core rev: af3c9bbf2db5a712f63145697d045d2f1ddce271)

(From OE-Core rev: 07961604732405c14a292cc963006f48a4a82bfd)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Saul Wold
cefb6645d7 lttng-modules: Update to stable version 2.6.1
This fixes a build issue with the 3.19.5 kernel where the regmap prototypes
have changed. The patch is rebased do to changes in the new version of the
Makefile.

[YOCTO #7737]

(From OE-Core rev: 787fde133c6b50c5df6ce8f90b2906b7955b41e4)

(From OE-Core rev: 2a355d2efb44a70571586bc5f6e500fa5d73db33)

Signed-off-by: Saul Wold <sgw@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Robert Yang
1ee92bc5d5 python3: fix build for shared object
Fixed when build on armv7a_vfp_neon:
Python-3.3.3/Modules/_struct.o: relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC

All the archs should use -fPIC when build shared object for linux.

(From OE-Core rev: 60c1f76f65060cbea458b06f9719a2536f50474e)

(From OE-Core rev: d9c3d3036da6f36d1f494987aa854d0c76968a27)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Kai Kang
34195e3210 grep: fix CVE-2015-1345
Backport patch to fix CVE-2015-1345. The issue was introduced with
v2.18-90-g73893ff, and version 2.5.1a is not affected.

Replace tab with spaces in SRC_URI as well.

(From OE-Core rev: ea97b1dee834594358c342515720559ad5d56f33)

(From OE-Core rev: f5e18f8dbac54231441b8b6260bf608edc377f66)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Kai Kang
c498744945 gpgme: fix CVE-2014-3564
Backport patch to fix CVE-2014-3564.

http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commit;h=2cbd76f

(From OE-Core rev: 421e21b08a6a32db88aaf46033ca503a99e49b74)

(From OE-Core rev: 204f24855a00f595ddfa040ae149b4184721603f)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Roy Li
bf28314e59 ppp: Security Advisory - CVE-2015-3310
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-3310

Buffer overflow in the rc_mksid function in plugins/radius/util.c in
Paul's PPP Package (ppp) 2.4.6 and earlier, when the PID for pppd is
greater than 65535, allows remote attackers to cause a denial of
service (crash) via a start accounting message to the RADIUS server.

oe-core is using ppp 2.4.7, and this CVE say ppp 2.4.7 was not
effected, but I found this buggy codes are same between 2.4.6 and
2.4.7, and 2.4.7 should have this issue.

(From OE-Core rev: 5b549c6d73e91fdbd0b618a752d618deb1449ef9)

(From OE-Core rev: 5450caccd45a2ee35ee227cdd64e66a304909a0e)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:13 +01:00
Kai Kang
7606fba211 qemu: fix CVE-2015-3456
Backport patch to fix qemuc CVE issue CVE-2015-3456.

Refs:
https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-3456
http://git.qemu.org/?p=qemu.git;a=commit;h=e907746266721f305d67bc0718795fedee2e824c

(From OE-Core rev: 1d9e6ef173bea8181fabc6abf0dbb53990b15fd8)

(From OE-Core rev: eec51579ee7a99e3ac2527ecb6ee57b494a7992f)

Signed-off-by: Kai Kang <kai.kang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:12 +01:00
Roy Li
ccaae1890e openssl: drop the padlock_conf.patch
padlock_conf.patch will enable the padlock engine by default,
but this engine does not work on some 32bit machine, and lead
to openssl unable to work

(From OE-Core rev: f7d186abca6ed9b48ae7393b8f244e1bfb46cb41)

(From OE-Core rev: bbc41bc086009726f307edeedbd380c68b1be6a7)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:12 +01:00
Andre McCurdy
b610e29670 gnutls: remove --with-libz-prefix configure option
The default search path in sysroot is sufficient to find zlib, so the
--with-libz-prefix configure option seems to be unnecessary.

For target builds, relying on sysroot also prevents an absolute path
from being hardcoded in the gnutls.pc pkg-config file.

(From OE-Core rev: 7a800bfeb6c8c83ee7cc74739f496982cd71c8e8)

(From OE-Core rev: f46c2ac0fd05f0e10258d8f03bfb2ebd0c2bcbe3)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:12 +01:00
Andre McCurdy
6a52d6d368 toolchain-scripts.bbclass: fix quoting for CCACHE_PATH
Single quotes prevent expansion of $sdkpathnative$bindir.

(From OE-Core rev: 986e5f37f3450077c843777c22df6b2d0f9502c5)

(From OE-Core rev: cd80d52fd213b15670d45f761538424180840f7d)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:12 +01:00
Peter Seebach
ab84c98f9f rootfs.py: Make set -x not break rootfs creation
The rootfs logfile check errors out if it finds an "exit 1" in
a log. But consider the shell idiom:
	if ! $command; then exit 1; fi
and consider a postinstall script with a "set -x" for debugging
purposes (to get log output in /var/log/postinstall.log.)

Solution: Ignore lines prefixed with a +, because those show shell
code even if a specific fragment won't be executed.

(From OE-Core rev: f23f129dba66144abf8fe8450320e01fa4c02f5c)

(From OE-Core rev: a13185ba4a29fca319b4eb4a76fdbdfcfe767322)

Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:12 +01:00
Jussi Kukkonen
e82008724e sanity.bbclass: import subprocess in correct function
check_sanity() no longer needs the subprocess module but
sanity_handle_abichanges() does use subprocess.call().

(From OE-Core rev: 469b53fb3bb94c7e5e9fb53d07cec2292b13c87d)

(From OE-Core rev: f0bf36c669790f1bcb2f897e61c82b075cb0a83b)

Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:11 +01:00
Florian Boor
34f38540d8 gtk-engines: Make gtk-engines-dev installable by dropping dependency to not generated gtk-engines package.
(From OE-Core rev: da96efe73c2338fa660a80d043479106f732f1f5)

(From OE-Core rev: 659cc47b142e0f14ace989d10277e4f83d7ffb75)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:10 +01:00
Ed Bartosh
a9ddd71880 rootfs.py: Improve rpm log_check_regex
Current regex can cause false negatives if paths in bitbake log files
contain "ERR" or "Fail". do_rootfs fails with return code 1 in
this case.

Improved regexp is based on error messages produced by rpm.
Those are found by analyzing rpm source code.

[YOCTO #7789]

(From OE-Core rev: 38871dc0295fb2516e1c8b1dc9948c2d2fc4d2cd)

(From OE-Core rev: 4a7f15e1d64a5d4ca4cd9b46a0ee5903e441b4e0)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:09 +01:00
Ross Burton
53f761d05e zlib: clean up base_libdir symlink
libz.so symbolic link created in ${libdir} is
../../${base_libdir}/libz.so.1.2.8.  This doesn't work if base_libdir or libdir
is changed, so use oe.path.relative to construct the correct path at build time.

(From OE-Core rev: ada8972ec40441b06e50d3e9ccbc07241a48e30a)

(From OE-Core rev: 20a60f137a9a1ae2689286241cc3d68a0392803d)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
André Draszik
c583473a2b icu-native: fix hard paths in native icu
The icu recipe installs icu-native twice, once in the usual location,
and once for cross builds into the path given by --with-cross-build.

This latter path is not included in the list of paths recognised by
chrpath.bbclass, hence the binaries in there retain the rpath as used
during compilation. This causes the package to not be relocateable
from sstate
[YOCTO #6851]

We use the infrastructure that is in place already, and simply set
PREPROCESS_RELOCATE_DIRS as necessary, and things start to work.

(From OE-Core rev: e7fcaa534511e3f65b630b01cf0c824ee5a5fd4d)

(From OE-Core rev: 922faf8ed42cd2d105e30a8c92836664d6b5bb18)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Roy Li
71676e587f pcmciautils: fix the parallel building issue
The building failure still display after upstream commit 055a5bbfc[
pcmciautils: fix for parallel build], so refix it.

(From OE-Core rev: fb426a1f5a103a1dc096977533dfbec2aefe07ae)

(From OE-Core rev: 14b5556ad3a4d7e817442e004b73601041f31b69)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Haris Okanovic
86bf04ca9b glibc: CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow
Backport Arjun Shankar's patch for CVE-2015-1781:

A buffer overflow flaw was found in the way glibc's gethostbyname_r() and
other related functions computed the size of a buffer when passed a
misaligned buffer as input. An attacker able to make an application call
any of these functions with a misaligned buffer could use this flaw to
crash the application or, potentially, execute arbitrary code with the
permissions of the user running the application.

https://sourceware.org/bugzilla/show_bug.cgi?id=18287

(From OE-Core rev: c0f0b6e6ef1edc0a9f9e1ceffb1cdbbef2e409c6)

(From OE-Core rev: 54f5e2001249c117cdfc1c26631ba50bc7a155dd)

Signed-off-by: Haris Okanovic <haris.okanovic@ni.com>
Reviewed-by: Ben Shelton <ben.shelton@ni.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Mario Domenech Goulart
d3f6656683 native.bbclass: avoid unintended substring replacement when setting PROVIDES
The way native_virtclass_handler was implemented leaded to
unintended substring replacements when setting PROVIDES for
native providers, in case the original PROVIDES value contains
providees with common substrings.

Here's a practical case where the old behavior was problematic:
the oracle-jse-jdk-x86-64 recipe provides both virtual/java and
virtual/javac:

Before:

$ bitbake -e oracle-jse-jdk-x86-64-native | grep ^PROVIDES=
PROVIDES="oracle-jse-jdk-x86-64-native  virtual/java-native virtual/java-nativec"

After:

$ bitbake -e oracle-jse-jdk-x86-64-native | grep ^PROVIDES=
PROVIDES="oracle-jse-jdk-x86-64-native virtual/java-native virtual/javac-native"

Change-Id: I8186992dae58e37c2a2364586360ff9b7da9198f
(From OE-Core rev: c28291f1fb07fbc80275d9bceefed642c963e204)

(From OE-Core rev: e0814f2306e1404fffafc7695862c6ee542b08fa)

Signed-off-by: Mario Domenech Goulart <mario@ossystems.com.br>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Otavio Salvador
cdc2c8aeaa gstreamer1.0-plugins-bad: Move EGL requirement for Wayland
The EGL is used by the Wayland backend. When building using Software
Rendering and without Wayland support the EGL backend is not available
so we should not require EGL for GLES2 support.

This fixes following build error:

,----
| ...
| checking for bcm_host_init in -lbcm_host... no
| checking for WAYLAND_EGL... no
| configure: error: Could not find the required EGL libraries
| Configure failed. The contents of all config.log files follows to aid debugging
| ERROR: oe_runconf failed
`----

(From OE-Core rev: 9c3a94aea1de3ab98e5693640926bfc86acde2db)

(From OE-Core rev: 2a0a2f276ef631bf7d60ec9821800d9b40a5832b)

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Martin Jansa
c495dccf58 boost: properly fix do_boostconfig re-execution
* it was partially fixed in:
  commit 291e20a51544c640d07767d1dc32d762f4370f41
  Author: Venkata ramana gollamudi <ramana.gollamudi@huawei.com>
  Date:   Fri Apr 13 11:42:46 2012 +0000
  Subject: boost: fix re-execution of task

  but with disadvantage that when CXX or *FLAGS variables were changed
  it was continuing to use old values
* just remove the line before appending it with current values to fix
  that

(From OE-Core rev: 8ce9584a78079b3db88eabfa902025a94443378d)

(From OE-Core rev: f055d084ad74a01a431ea87ead6bfdcaca0d7bde)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Bruno Bottazzini
8fc71f4247 systemd: removing workaround odering journal after remote-fs.target
This workaround is not needed in version 219 since the fix is upstreamed with:
919699ec301ea507edce4a619141ed22e789ac0d

(From OE-Core rev: e3330d0602fb3ad347f028063d25f634a36ea344)

(From OE-Core rev: fdcbbb50a9946733bd204b8db45606c929e43822)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:08 +01:00
Christophe Guillon
10ee6be5b8 ncurses: inherit pkgconfig
Without pkgconfig being present at build time it's possible for the .pc files to
not be installed correctly.

(From OE-Core rev: f049a53078b3876be9fefc1e5f64404a3f378724)

(From OE-Core rev: c6e39f271a737aa867a15f70c2975987e9d7b209)

Signed-off-by: Christophe Guillon <christophe.guillon@st.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Martin Jansa
5b8a8f9490 e2fsprogs: install populate-extfs.sh
* install populate-extfs.sh from contrib, be aware that in order
  to use it you need to set DEBUGFS shell variable, otherwise it will
  try to use debugfs from relative path which is almost always
  incorrect:
    CONTRIB_DIR=$(dirname $(readlink -f $0))
    DEBUGFS="$CONTRIB_DIR/../debugfs/debugfs"

(From OE-Core rev: 525b7b587a00466e4322450c171d920b47201e56)

(From OE-Core rev: 32e847f6988eb488dad23badf1cabae92ef803df)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Robert Yang
fb3f5c68fd mesa: fix do_install_append
"ifdef MESA_EGL_NO_X11_HEADERS" -> "if defined(MESA_EGL_NO_X11_HEADERS)"

(From OE-Core master rev: 3a464d67b60f70b865f7db768e7edc53e40ff450)

(From OE-Core rev: 12e467f436fbc22f274558c753f0ac9756ce1071)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Richard Purdie
342958fce1 glibc: Fix x32 make race
On x32 builds, sysd-syscalls appears malformed since the make-target-directory
appears on the wrong line. This causes races during the build process where you can
see failures like:

Assembler messages:
Fatal error: can't create [...]glibc/2.21-r0/build-x86_64-poky-linux-gnux32/time/gettimeofday.os: No such file or directory
Assembler messages:
Fatal error: can't create [...]glibc/2.21-r0/build-x86_64-poky-linux-gnux32/time/time.os: No such file or directory

The issue is that the carriage return is being escaped when it should
not be. The change to sysd-syscalls with this change:

before:

"""
$(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,time).os): \
                $(..)sysdeps/unix/make-syscalls.sh      $(make-target-directory)
        (echo '#include <dl-vdso.h>';
"""

after:

"""
$(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,time).os): \
                $(..)sysdeps/unix/make-syscalls.sh
        $(make-target-directory)
        (echo '#include <dl-vdso.h>';
"""

which ensures the target directory is correctly created. Only x32 uses the vdso
code which contains the bug which is why the error only really appears on x32.

(From OE-Core rev: ae4729ed6c5e5443c42f8825dd85873f06a3570e)

(From OE-Core rev: c945453a8453dd6dab5aa5a132bea20e73ae4d6d)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Richard Purdie
744d1ff8ce base: Avoid find race
In a similar way to http://git.yoctoproject.org/cgit.cgi/poky/commit/?id=aa1438b56f30515f9c31b306decef7f562dda81f
and http://git.yoctoproject.org/cgit.cgi/poky/commit/?id=527b28c10955daf0387597020d69593ce24bcaa4
there is a find race in base.bbclass.

For recipes with PACKAGES_remove = "${PN}", the find which removes
.la files can race against deletion of other directories in WORKDIR
e.g.:

find: '/home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/sstate-build-populate_lic': No such file or directory
| WARNING: /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/temp/run.do_configure.6558:1 exit 1 from
| find /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7 -name \*.la -delete

Fix the race in the same way.

[YOCTO #7522]

(From OE-Core rev: 90861b8908d254154f4d1d613471070df8013da8)

(From OE-Core rev: 220141c63161f7c4f4112ac8b95bf44775843a9f)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Robert Yang
7d88afbdfd alsa-tools: set CLEANBROKEN
Fixed:
make[1]: Entering directory `alsa-tools-1.0.28/envy24control'
make[1]: *** No rule to make target `clean'.  Stop.

There is no "make clean" in envy24control when DISTRO_FEATURES is
changed from no-x11 to x11.

(From OE-Core rev: 8ccc47c37765487b535c4d6a8b43c2b6365ff000)

(From OE-Core rev: 4ff4bca025277fd19f11a6ba86102fca8563a1ff)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Roy Li
08a09c3410 unzip: Security Advisory -CVE-2014-9636 and CVE-2015-1315
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9636

unzip 6.0 allows remote attackers to cause a denial of service
(out-of-bounds read or write and crash) via an extra field with
an uncompressed size smaller than the compressed field size in a
zip archive that advertises STORED method compression.

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1315

Buffer overflow in the charset_to_intern function in unix/unix.c in
Info-Zip UnZip 6.10b allows remote attackers to execute arbitrary code
via a crafted string, as demonstrated by converting a string from CP866
to UTF-8.

(From OE-Core rev: f86a178fd7036541a45bf31a46bddf634c133802)

(From OE-Core rev: d868f9e8a6a5d4dc9c38e2881a329f7e3210eab8)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Bruce Ashfield
d271a8e004 kernel-yocto: propagate in tree defconfigs to WORKDIR
As reported by Steffen Pankratz <Steffen.Pankratz@elektrobit.com>, the
previous logic of KBUILD_DEFCONFIG processing would not propagate an in
tree defcofig to WORKDIR if one was not already present.

We fix the propagation by copying the in tee config if a defconfig is
not already in WORKDIR.

Additionally we only warn (versus copying) if an in tree configuration
is specified, is different than the WORKDIR version and isn't copied.

(From OE-Core rev: 58cc903a5156063b24e48011438a709cb6e09f54)

(From OE-Core rev: 0b12cc3a326740bd95bb199d4f1b38bf5beadfa9)

Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:07 +01:00
Bruce Ashfield
409bdca8e3 linux-yocto: fix race between checkout and meta data generation
There are two tasks that must run before a linux-yocto kernel is built.

  - Kernel checkout and relocation to work-shared (kernel_checkout)
  - Meta data gathering and configuration prep (kernel_metadata)

The current task definitions for both are simply "before do_patch",
which is correct, but kernel_checkout must run before and not race with
kernel_metadata.

So we set the definition of kernel_checkout to be more specific and
enforce the proper ordering.

[YOCTO: #7731]

(From OE-Core rev: 9d806f3d05de918952f839f5e595cb71cd1261db)

(From OE-Core rev: 561b7776d93d40cac009360ec95b8de78888f1ca)

Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Roy Li
dc70442747 e2fsprogs: fix the CVE-2015-1572
Backport a patch to fix CVE-2015-1572
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-1572

(From OE-Core rev: 203e1024cc7517cad28423cc04f641376cc8f2f5)

(From OE-Core rev: 7cfbeeec098e19bd27e342cd09a3fa22de6e7e93)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Ed Bartosh
e34336da87 kernel.bbclass: Fix race condition
Race condition between do_compile_kernelmodules and do_shared_workdir
tasks occurs when do_compile_kernelmodules changes files in
include/generated/* while do_shared_workdir tries to copy them to
shared working directory.

Fixed race by moving do_shared_workdir after do_compile but before
do_compile_kernelmodules.

[YOCTO #7321]

(From OE-Core rev: b4ec689f71fe9504559c1921c893f5e096d6b744)

(From OE-Core rev: a224584b6b0b7f12e0d1962d889587ce50957c60)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Richard Purdie
3b8170562c directfb: Correct bashism
Fix builds of directfb on systems with dash as /bin/sh

(From OE-Core rev: 8848517fb4c81b9e9cfc985dd20b9baf374764c0)

(From OE-Core rev: 493ecc520202851bba664eaf4f1150ce624bf2b1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Robert Yang
f0d6f7fe95 bind: remove 5 backport patches
They are backport patches, and verified that the patches are in the
source.

(From OE-Core rev: 6e4a10ab030c192e2437592538e4713b1ee2032b)

(From OE-Core rev: fd5115556a12c8c2d95c02f077dc38ea4c9253f5)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Mike Crowe
2cc0ea83d3 libcap: Avoid passing "-e" to make
oe-core 51540b64f62234c145fc32cfa3fbbaaebbeece08 altered libcap.inc (at the
time) to append to EXTRA_OEMAKE rather than assign to it. The default value
for EXTRA_OEMAKE contains "-e". This means that the change caused "-e" to
be passed to make for the first time.

Unfortunately passing "-e" subtly changes the behaviour of libcap's
Make.Rules under recursive make when prefix="" (which it is for us since
we're using meta-micro.)

Without "-e" the prefix comes from the command line in both the parent and
submakes. This takes precedence over any attempt to reassign it with a
simple "=" operation so the headers are correctly installed in (empty
string)/include.

With "-e" the prefix still comes from the command line in the parent make
but from the environment in the submake. The attempt to assign it fails in
the parent make as before, but not in the submake so the headers are
installed incorrectly in /usr/include.

In all four cases the "ifdef prefix" else clause is executed.

So, let's assign EXTRA_OEMAKE in order to avoid using "-e" at all.

(From OE-Core rev: a8d35fa4fd76ea4a70063492cd5eab0858f2edb6)

(From OE-Core rev: 24a98efa442b323667e1471886ad874e607ff320)

Signed-off-by: Mike Crowe <mac@mcrowe.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Roy Li
def79f5f31 elfutils: Security Advisory - CVE-2015-0255
Directory traversal vulnerability in the read_long_names function in
libelf/elf_begin.c in elfutils 0.152 and 0.161 allows remote attackers
to write to arbitrary files to the root directory via a / (slash) in a
crafted archive, as demonstrated using the ar program.

https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-9447

(From OE-Core rev: 4a65944b89a76f18c8ff6e148f17508882d387cf)

(From OE-Core rev: 5eda84a62201461b9c69498ec35585d2c8142dec)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Robert Yang
7620a4ad38 pcmciautils: fix for parallel build
Fixed:
Compiling lex_config.c.
  src/lex_config.l:34:25: fatal error: yacc_config.h: No such file or directory

There was a patch for fixing the paralle issue before, so modify the
patch again.

(From OE-Core rev: 055a5bbfc7686c8eec3aad2bcbcf90c40031cc34)

(From OE-Core rev: 45e105e08c56eef5ef8282f2f84778f4c291798a)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Khem Raj
6182fc36ae curl: Fix wrong assumption about sizeof off_t on largefile systems
This issue was reported on poky ml as well see
https://lists.yoctoproject.org/pipermail/poky/2013-December/009435.html

Change-Id: Iedf22467889893111fde0433e411fd0546a38546
(From OE-Core rev: 3c58712465494e441c4036a7cf21d2e6d343efab)

(From OE-Core rev: 49c848018484827c433e1bcf9c63416640456f3e)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:06 +01:00
Robert Yang
1901d6b02c elfutils: enable fix-build-gcc-4.8.patch
The patch fixes a warning seen with gcc 4.8 (especially on ubuntu 13.10)

(From OE-Core rev: c577a52b252ccbad9a8dde79c6a4a4f23376d9d8)

(From OE-Core rev: 1878cadb02aa01a58f6985d2b7a9268df4f381a6)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
50338c36c8 texinfo: remove enumerate_greater_than_ten.patch
It is a backport patch, and verified that the patch is in the source.

(From OE-Core rev: a46976b9de5a2270f041a73661a6ed635bf4eb43)

(From OE-Core rev: 94116f5be3b3581b364e18c6a008e088f3b1dae9)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
f831a73052 libaio: remove libaio-generic.patch
It is already in the source.

(From OE-Core rev: e6b2def565c1201c3b0a0d2a8c296b65e6cafb02)

(From OE-Core rev: 6c931a231dbb90e16fd092187d6fea42dd7f5908)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
9e14d6efa2 lttng-modules: remove bio-bvec-iter.patch
It is aready in the source.

(From OE-Core rev: 4ac3e70f8f39dc6b585e0acb3679d4137f60b296)

(From OE-Core rev: 78e377d37a0ef36d595dcdc00c9c51674d828f02)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
50241173b7 openssl: remove 3 patches
Removed:
 - openssl-avoid-NULL-pointer-dereference-in-dh_pub_encode.patch
 - upgate-vegsion-script-for-1.0.2.patch
   Since they are already in the source.
 - make-targets.patch
   It removed test dir from DIRS, which is not needed any more since we
   need build it.

(From OE-Core rev: 5fa533c69f92f2dd46c795509b0830b36413b814)

(From OE-Core rev: 2635d1dbe0ef0b43c7505d9c43494eac0f2e6760)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
c97d806d2f logrotate: remove logrotate-CVE-2011-1548.patch
It is a backport patch, and verified that the patch is in the source.

(From OE-Core rev: 370dc496c2d6f8fa97a18af49747d15a41fc7bcf)

(From OE-Core rev: 3cf413bd3f7b022488473aaee15e28cf343c6b12)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
2f1a4d0f73 libxml2: remove libxml2-CVE-2014-3660.patch
It is a backport patch, and verified that the patch is in the source.

(From OE-Core rev: 9a3178b4d3c454e76a0af59afc7b326589c4c666)

(From OE-Core rev: 9834785d0b4ee1759d6a469c585a566652cbc38a)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
b9b7c619da nspr: remove nspr-CVE-2014-1545.patch
It is a backport patch, and verified that the patch is in the source.

(From OE-Core rev: a7e723bd78e280ae48e6de725b2881b35ae21f5c)

(From OE-Core rev: f5ef99247b84ac1a39b92daf02a4249d39aacbf1)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:05 +01:00
Robert Yang
3599cb53f8 python3: remove sys_platform_is_now_always_linux2.patch
It is aready in the source.

(From OE-Core rev: 99f9df3add049ec18dbcd604646a67dc59b3db16)

(From OE-Core rev: 6c1b44872d9cd09ad46fd9d2cc3555f9cd3a55e6)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:04 +01:00
Robert Yang
e7b12a4e63 python-numpy: remove 2 dangling patches
Removed:
- unbreak-assumptions.diff
  This patch changs the dir to /non-existant-dir, the source code has
  changed the dir to /deadir, so it is not needed any more.

- trycompile.diff
  There is no try_compile or try_run in numpy/core/setup.py any more, so
  assumed that it is not needed.

(From OE-Core rev: 56aac948ca9686d79a2c56f4f034f8de445ff37b)

(From OE-Core rev: 7f0d86dd43a10a981aa2ad8acde66fe345fe4096)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:04 +01:00
Richard Purdie
276606afe6 sstate: Use SSTATE_DIR for FILESPATH
FILESPATH was only being overridden in one fetch location, it should be
equally handled in both.

Also use SSTATE_DIR as FILESPATH so that mirror urls which do remapping
can search the local SSTATE_DIR for other paths.

Also ensure that MIRRORS is removed in both locations, previously
it was only unset in one but both codepaths should be consistent.

(From OE-Core rev: ab6bebddbdefec323e284b6438d9c57b3d8a2cc3)

(From OE-Core rev: ac255ca3eacece98f60a1a5d8cfc468f73aa67c7)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-28 09:44:04 +01:00
Richard Purdie
eb4a134a60 scripts/combo-layer: Fix exit codes and tty handling
If combo-layer is called from a non-interactive context we should exit
with a correct error code rather than try and drop to a shell.

This patch cleans up a few error case exit codes as well as
detecting and handling non-interactive usage.

(From OE-Core rev: 3b1d89a51445cf526ca84eb5b53de434f9585d6e)

(From OE-Core rev: b08ee8478f0cc2e2f9394c7e209dae45de2d845e)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-06-11 15:00:20 +01:00
Patrick Ohly
508c4cac32 combo-layer: handle unset dest_dir in sanity_check()
The previous "clean up dest_dir checking" patch (f8cdbe7497) improved
handling of empty dest_dir but made handling of unset dest_dir worse:
instead showing the "Option dest_dir is not defined for component ..."
error, it fails with a Python exception.

Avoid that by providing a sane fallback for the unset case. With that
change, dest_dir is no longer strictly required, but the check for it
is kept to ensure that a combo-layer.conf also works with older
combo-layer versions.

[Yocto #7773]

(From OE-Core rev: d4bf858b2c15bef128fd6d606b08203a318e2d4c)

(From OE-Core rev: b266977372f2d5704d00dd07b29ea49898ebf70e)

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-29 13:01:37 +01:00
Patrick Ohly
e9ae2f8417 combo-layer: improve merge commit handling
When the head of a branch is a merge commit, combo-layer did not
record that commit as last_revision because it only considers applied
patches, and the merge commit never gets applied.

This causes problems when the merge commit leads to multiple patches
and the commit id that gets recorded only reaches some of these
patches. The next run then will try to re-apply the other patches.

This special case is now detected and dealt with by bumping
last_revision to the branch commit. The behavior where the head is a
normal commit is intentionally not changed, because some users might
prefer the traditional behavior.

(From OE-Core rev: 701bcd52c208f22a9a6c48a11a35bcf1c4e413df)

(From OE-Core rev: 1bc46199e569411150b050818ff17abc66f899f2)

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-29 13:01:36 +01:00
Paul Eggleton
12cc076832 bitbake: lib/bb/utils: fix several bugs in edit_metadata_file()
* Fix unchanged assignments being dropped if other lines changed
* Fix not passing variable name from single-line assignments to the
  function
* Fix not trimming the trailing quote from values

(Bitbake master rev: 0b0c82f49cf2de887967d305768cbd95314bb171)

(Bitbake rev: cd92e5dce5f5d61ecb7838bf964a7812e905509a)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-23 08:21:42 +01:00
Paul Eggleton
ca6ef30c7a bitbake: lib/bb/utils: add function to get layer containing a file
In certain contexts it can be useful to find the layer that a file (e.g.
a recipe) appears in.

Implements [YOCTO #7723].

(Bitbake master rev: 3bf9c8830c5d5eea5502230d5af84ebd87ad5849)

(Bitbake rev: 8dcd83e5edb1cf3307b610d3bb8d54733ea7356d)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-23 08:21:41 +01:00
Ed Bartosh
59e4f9fc12 split_and_strip_files: regroup hardlinks to make build deterministic
Reverted 7c0fd561bad0250a00cef63e3d787573112a59cf

Created separate group of hardlinks for the files inside
the same package. This should prevent stripped files to be
populated outside of package directories.

This turns out not to be straightforward and has overlap with the
other hardlink handling code in this area. The code is condensed
into a more concise and documented form.

[Original patch from Ed with tweaks from RP]

[YOCTO #7586]

(From OE-Core master rev: 82d00f7254b7d3bb6a167d675d798134884d1b19)

(From OE-Core rev: 2abacf00ee3f60735bf7c0dc7130c72267822b30)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:13:38 +01:00
Richard Purdie
4dc652a0c3 bitbake: bitbake-layers: ensure non-extended recipe name is preferred
In show-recipes and show-overlayed, we only list one variant of each
recipe where multiple exist, therefore we should show the main one (e.g.
in OpenEmbedded, we now show openssl and not nativesdk-openssl which
would otherwise sort first.)

Fixes [YOCTO #7514].

(Bitbake rev: 8e0211d121e4cb1124dfe879db751ad00f5c978b)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:50 +01:00
Christopher Larson
83ac75ffb3 bitbake: runqueue: pass finalized metadata to scenequeue callbacks
This ensures that _append, _prepend, overrides, etc are functional when used
on sstate variables (e.g. SSTATE_DIR).

[YOCTO #7564]

(Bitbake rev: 0a9eaa570fdf3862ef26ee537fc74f3be75fd554)

Signed-off-by: Christopher Larson <kergoth@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:50 +01:00
Ross Burton
e23ec53caa systemd: bring back the patch to customise root's $HOME
This patch appears to have been accidently dropped in the move to 219-stable,
probably because it didn't apply.  Update the patch and re-add it.

(From OE-Core master rev: 51aaa647b203d0f7ddd2f53f7191c4d2918b09b8)

(From OE-Core rev: 16684ce4072e8cffd321d25303de91fd0e32529c)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:50 +01:00
Joshua Lock
45592f15d8 systemd: remove unused patches
These patches are no longer required since 7bfc9891ff

(From OE-Core master rev: e45b8bf579f2050ebdb1aa1a4c2f9c3b530c9ad6)

(From OE-Core rev: d8b4b70df507f2ef82378a7bfa501fe81ad2a21a)

Signed-off-by: Joshua Lock <joshua.lock@collabora.co.uk>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Dmitry Eremin-Solenikov
08dcacb083 bitbake.conf: add sed-native to ASSUME_PROVIDED
There is no reason to build sed for the host, however now:
ERROR: Nothing RPROVIDES 'sed-native' (but virtual:native:/OE/sources/openembedded-core/meta/recipes-extended/groff/groff_1.22.2.bb RDEPENDS on or otherwise requires it)

(From OE-Core rev: f09dcaab4afb6aad5a707418741e97625473b890)

Signed-off-by: Dmitry Eremin-Solenikov <dmitry_eremin@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Bryan Evenson
944b46c223 util-linux: Add lastb to alternatives
util-linux creates lastb as a symlink to last during the build.
Just as other applications may provide last, other applications
may provide lastb.

Add alternatives designations for lastb to avoid installation
conflicts with other applications.

(From OE-Core rev: cde6a85fd327407320adaad21203079a8dacbf23)

(From OE-Core rev: 2665431f75ebc9eb1f47dee7d3ef362dcf5917a9)

Signed-off-by: Bryan Evenson <bevenson@melinkcorp.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Chen Qi
26e18a143b shadow: add 'util-linux-sulogin' to RDEPENDS
If shadow is installed, sulogin from busybox cannot work correctly because
it still assumes that /etc/shadow is not there. This leads to the problem
when booting into rescue mode in an image with shadow installed but not
sulogin from util-linux.

To fix this problem, we add 'util-linux-sulogin' to RDEPENDS of shadow.
This runtime dependency is specific to OE, because we have to ensure
that sulogin can work correctly and sulogin from busybox cannot because
FEATURE_SHADOWPASSWORDS is not enabled by default. And we cannot enable
it by default for busybox, because that would lead to utilities in busybox
to assume the existence of /etc/shadow which is not always true in OE.

[YOCTO #6698]

(From OE-Core rev: 9b45b990d2fc870df556f05908dcb48b9ebcfc02)

(From OE-Core rev: d2e348537786966fd29187ff7fb9ae42614695af)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Chen Qi
704a053dd5 util-linux: split out util-linux-sulogin
[YOCTO #6698]

(From OE-Core rev: 4bde182ed236243547929dd98763f1c09eddd097)

(From OE-Core rev: eeaf4ca1e5fea56fe7472076bc0372f597876fdc)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Chunrong Guo
09eb069ccf groff: add runtime dependency on sed
This is to suppress the following QA warning:
  groff-1.22.2: groff requires /bin/sed, but no providers in its RDEPENDS [file-rdeps]

(From OE-Core rev: f1e5913bee28f59efb252045a0113cae701d848d)

Signed-off-by: Chunrong Guo <B40290@freescale.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:49 +01:00
Richard Purdie
67d83673ea autotools: Fix find races on source directory
In a similar way to http://git.yoctoproject.org/cgit.cgi/poky/commit/?id=aa1438b56f30515f9c31b306decef7f562dda81f
there are more find races in the autotools class.

For recipes with PACKAGES_remove = "${PN}", the find which removes
.la files can race against deletion of other directories in WORKDIR
e.g.:
find: '/home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/sstate-build-populate_lic': No such file or directory
| WARNING: /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/temp/run.do_configure.6558:1 exit 1 from
| find /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7 -name \*.la -delete

Fix the remaining races in the same way.

[YOCTO #7522]

(From OE-Core rev: 79770ca14a0cc2f4112fb4d8dc2d8832701b6d5d)

(From OE-Core rev: 699e1570e66cb28e4bfd0eb15d41f3af2bed5b62)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:48 +01:00
Li Zhou
6504fa687a libxfont: Security Advisory - libxfont - CVE-2015-1804
bdfReadCharacters: ensure metrics fit into xCharInfo struct

We use 32-bit ints to read from the bdf file, but then try to stick
into a 16-bit int in the xCharInfo struct, so make sure they won't
overflow that range.

(From OE-Core rev: 4dd4b96b6d60246338bb30ede9f3ab1b2e757be9)

(From OE-Core rev: 1e2a947e65f5fb6e01459c9ddd6515a7131d92c7)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:48 +01:00
Li Zhou
7a277e901d libxfont: Security Advisory - libxfont - CVE-2015-1803
bdfReadCharacters: bailout if a char's bitmap cannot be read

Previously would charge on ahead with a NULL pointer in ci->bits, and
then crash later in FontCharInkMetrics() trying to access the bits.

(From OE-Core rev: 2c7a15a074501beb6b8a4c7bdf30604b1a432a6b)

(From OE-Core rev: 7827e9756e82c31707ce87d27c7d0b0392fc0812)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:48 +01:00
Li Zhou
b611530351 libxfont: Security Advisory - libxfont - CVE-2015-1802
bdfReadProperties: property count needs range check

Avoid integer overflow or underflow when allocating memory arrays
by multiplying the number of properties reported for a BDF font.

(From OE-Core rev: 0ff9f2bf0e44a7b47a98234a12714c780825e286)

(From OE-Core rev: ddc4889d7028d0388b1521d49ab1d3b8decba524)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:48 +01:00
Li Zhou
3e3507d02e libarchive: Security Advisory - libarchive - CVE-2015-2304
libarchive: Updated libarchive packages fix security vulnerability

Alexander Cherepanov discovered that bsdcpio, an implementation of the "cpio"
program part of the libarchive project, is susceptible to a directory
traversal vulnerability via absolute paths.

(From OE-Core master rev: e64a961e9c5e94e643896e4b68b85bd5b4c27470)

(From OE-Core rev: c944c1ee3f039979d93022bbbd76f61f57b1577f)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:48 +01:00
Junling Zheng
8d07cacde3 less: fix CVE-2014-9488
An out of bounds read access in the UTF-8 decoding can be triggered with
a malformed file in the tool less. The access happens in the function
is_utf8_well_formed due to a truncated multibyte character in the sample
file.

The bug does not crash less, it can only be made visible by running less
with valgrind or compiling it with Address Sanitizer.

Version 475 of less contains a fix for this issue. The file version.c
contains some entry mentioning this issue (without any credit):

 - v475 3/2/15 Fix possible buffer overrun with invalid UTF-8

The fix is in the file line.c. We derive this patch from:

https://blog.fuzzing-project.org/3-less-out-of-bounds-read-access-TFPA-0022014.html

Thank Claire Robinson for validating it on Mageia 4 i586. Refer to:

https://bugs.mageia.org/show_bug.cgi?id=15567

(From OE-Core master rev: 68994284f3c059b737bfc5afc2600ebd09bdf47f)

(From OE-Core rev: 7195d219f7af2b94dffb87a94077ec98dacdcdb0)

Signed-off-by: Junling Zheng <zhengjunling@huawei.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Roy Li
205e9ed896 rsync: backport a patch to fix CVE-2014-9512
rsync 3.1.1 allows remote attackers to write to arbitrary files via a symlink
attack on a file in the synchronization path.

Backport Complain-if-an-inc-recursive-path-is-not-right-for-i.patch to fix it

(From OE-Core master rev: f280b4f28231ea5a416266ae022d6e4c4ea91117)

(From OE-Core rev: a42af2e434c01c04af36d6ed7a7a5480a7a255a5)

Signed-off-by: Roy Li <rongqing.li@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Robert Yang
edb2b4760c kernel-devsrc: depends on virtual/kernel:do_install
The linux-yocto.inc may remove the meta dir:
do_install_append(){
	if [ -n "${KMETA}" ]; then
		rm -rf ${STAGING_KERNEL_DIR}/${KMETA}
	fi
}

Which may cause the error:
[snip]
find: `./meta/cfg/kernel-cache/bsp/altera-socfpga/0073-FogBugz-116676-Align-clk.c-with-kernel.org.patch': No such file or directory
find: `./meta/cfg/kernel-cache/bsp/altera-socfpga/0047-FogBugz-90657-Fix-SD-MMC-driver-for-VT.patch': No such file or directory
find: `./meta/cfg/kernel-cache/bsp/altera-socfpga/0006-spi-qspi-cadence-Add-spi-and-qspi-driver.patch': No such file or directory
[snip]
cpio: ./meta/scripts/kgit-config-cleaner: Cannot stat: No such file or directory
cpio: ./meta/scripts/kgit-s2q: Cannot stat: No such file or directory
cpio: ./meta/scripts/kgit-clean: Cannot stat: No such file or directory
[snip]

(From OE-Core master rev: 0866086c6a9d9f518388f2962db784ab15d49330)

(From OE-Core rev: ecf26a6e4aaac6d7f24eeb38215365c4c72b81a8)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Robert Yang
b749898186 gnu-efi: fix parallel issue
Fixed:
Assembler messages:
Fatal error: can't create runtime/rtlock.o: No such file or directory
Assembler messages:
Fatal error: can't create runtime/rtdata.o: No such file or directory
Assembler messages:
Fatal error: can't create runtime/vm.o: No such file or directory
Assembler messages:
Fatal error: can't create runtime/efirtlib.o: No such file or directory

(From OE-Core master rev: 86d428775c95a900c9b452f03548b56cb980b64c)

(From OE-Core rev: a86bc60ac3ef18f22690e1a77578cb991aede9f5)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Ken Sharp
7b7b67fcef udev-cache: improve error handling
If an error occurs while the udev cache is being populated, the system
is left in a state where udev is stopped.  Remedy this with a clean up
function to restart udev and remove any intermediate files.

(From OE-Core master rev: af911b272ded95884079dc307eeeb1811f0584c9)

(From OE-Core rev: 70214bb02bad6a6f0d6f25ff227d6e380c1b9fb3)

Signed-off-by: Ken Sharp <ken.sharp@ni.com>
Reviewed-by: Ben Shelton <ben.shelton@ni.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Ken Sharp
3857acab1a udev-cache: Remove unnecessary tar read from stdin
xargs already formats the inputs to tar correctly, so the
'-T -' argument to tar is unnecessary.

(From OE-Core master rev: d18e1964dede530c5fae6ae349d6a78fa5342382)

(From OE-Core rev: d666072445ec5323a7849ae0c80ba9f293a5464b)

Signed-off-by: Ken Sharp <ken.sharp@ni.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:47 +01:00
Mike Looijmans
dc97c54915 alsa-utils: Remove double dependency on udev
"udev" is already added when PACKAGECONFIG includes it, so it should
not be in the DEPENDS list on itself.

This caused udev to be built for systems that don't use it.

(From OE-Core rev: 2ea67db71ba37285c5d16428ba9629412adcfa47)

(From OE-Core rev: 6fb1b306bd1a1ca6ecc6c8d91e0007cc65a6a0d6)

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Paul Eggleton
2dd79784e8 mkefidisk.sh: fix hanging on non-writeable device
If cleanup() is called early on, as happens when the device isn't
writeable, then none of the mount point variables are set; thus the
script was calling grep with only one argument and appeared to hang
since it was waiting for input on stdin.

(From OE-Core master rev: cf4a18eec2a65d840352d1a2862242d116e8a409)

(From OE-Core rev: f8b8fbeee3f5c51f6b3e39200f935156be3936f3)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Paul Eggleton
e4ccc4dae3 mkefidisk.sh: use script mode when running parted
This avoids parted showing prompts and thus effectively hanging the
script in in the case of initially malformed disks.

(From OE-Core master rev: 8f6eb9a86ce64b4c534342fe315069eb4064de88)

(From OE-Core rev: 8e72fd01071694b73ec092657f5378dbadd4f396)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Bruno Bottazzini
732cdba31e systemd 219 -> system 219-stable
The upstream systemd git repo only contains the main systemd branch that
progresses at a quick pace, continuously bringing both bugfixes and new features.

Distributions usually prefer basing their releases on stabilized versions
that receive the bugfixes but not the features.

(From OE-Core master rev: c21bf9d7bb0cb90392ed50a44c57a3d068b88ef9)

(From OE-Core rev: c3da0d750ce7b45fee9db3e985f585f5fb2e193d)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Cristian Iorga
af3518a605 oeqa/selftest/toaster: fix bad indent
oe-selftest --list-classes crashes because
of a bad indent (see below). Fixed.

systemd-build$ oe-selftest --list-classes
2015-04-22 12:12:39,141 - selftest - INFO - Listing all available test modules:
_sstatetests_noauto (hidden)
 -- SStateBase
 -- RebuildFromSState
 --  -- test_sstate_rebuild
 --  -- test_sstate_relocation
_toaster (hidden)
Traceback (most recent call last):
  File "/mnt/Yo/yoctoproject/poky/scripts/oe-selftest", line 201, in <module>
    ret = main()
  File "/mnt/Yo/yoctoproject/poky/scripts/oe-selftest", line 157, in main
    modlib = importlib.import_module(test)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/mnt/Yo/yoctoproject/poky/meta/lib/oeqa/selftest/_toaster.py", line 438
    time.sleep(3)
    ^
IndentationError: unexpected indent

(From OE-Core master rev: 46869abf72c1c5babce49537f221d7a4f53ca820)

(From OE-Core rev: f01d4df7568fed5fe2feb0b1e8abb2214b567c07)

Signed-off-by: Cristian Iorga <cristian.iorga@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Chen Qi
f4b1bcbc38 populate_sdk_base: avoid executing empty function
`bitbake uninative-tarball' raises the following warning.

    WARNING: Function  doesn't exist

This is because SDK_PACKAGING_FUNC is set to "" in its recipe.
Anyway, we need to check this variable to avoid executing empty function.

[YOCTO #7598]

(From OE-Core rev: 4c0ae7cce06de15f6881654ecec7f8bb743ff389)

(From OE-Core rev: 7c0c2b3037dfc2790446968572daf5bf0a17e2f8)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Chen Qi
605e8fad88 uninative-tarball: delete the packagedata task
This task is meaningless for uninative-tarball as the package task
has been deleted. Besides, sometimes it would cause problems. To
reproduce, use the following command.

bitbake uninative-tarball -c cleansstate && bitbake uninative-tarball &&
bitbake uninative-tarball -c clean && bitbake uninative-tarball

The error is something like below.

File: 'sstate.bbclass', lineno: 33, function: sstate_installpkg
     0029:        bb.build.exec_func(f, d)
     0030:
     0031:    for state in ss['dirs']:
     0032:        prepdir(state[1])
 *** 0033:        os.rename(sstateinst + state[0], state[1])
     0034:    sstate_install(ss, d)
     0035:
     0036:    for plain in ss['plaindirs']:
     0037:        workdir = d.getVar('WORKDIR', True)
Exception: OSError: [Errno 2] No such file or directory

[YOCTO #7597]

(From OE-Core rev: 8f905077aaed3dbeeed04787add1cf725fa87bdc)

(From OE-Core rev: e94864c1589986fb8a59ee86cae0fd3b430ebf09)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
Chen Qi
636cde886f shadow: fix `su' behaviour
0001-su.c-fix-to-exec-command-correctly.patch is removed. Below is the reason.
This patch is introduced to solve the 'su: applet not found' problem when
executing `su -l xxx -c env'. The patch references codes of previous release
of shadow. However, this patch introduces bug#5359. So it's not correct.

Let's first look at the root cause of 'su: applet not found' problem.
This problem appears when /bin/sh is provided by busybox.
When executing `su -l xxx -c env' command, the following function is invoked.
    execve("/bin/sh", ["-su", "-c", "env"], [/* 6 vars */])
Note that the argv[0] provided to new executable file (/bin/sh) is "-su".
As /bin/sh is a symlink to /bin/busybox. It's /bin/busybox that is executed.
In busybox's appletlib.c, it would examine argv[0], try to find an applet
that has the same name, and then try to execute the main function of the
applet. This logic results in `su' applet from busybox to be executed.
However, we default to set 'BUSYBOX_SPLIT_SUID' to "1", so 'su' is not found.
Further more, even if we set 'BUSYBOX_SPLIT_SUID' to "0", so that 'su' applet
is found. The whole behaviour is still not correct. Because 'su' from shadow
takes higher priority than that from busybox, so 'su' from busybox should never
be executed on such system unless it's specified clearly by the end user.
The logic of busybox's appletlib.c is totally correct from the point of busybox
itself. It's an integration problem.

To solve the above problem, this patch comment out SU_NAME in /etc/login.defs
so that the final function executed in shadow's su is as below.
    execve("/bin/sh", ["-sh", "-c", "env"], [/* 6 vars */])

[YOCTO #5359]
[YOCTO #7137]

(From OE-Core rev: 6820f05dad0b4f9b9bbcf7c2a0af8c34f66199ae)

(From OE-Core rev: c7ba25a1e2fd36789ad6f55f05b41c3dc9b7f089)

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:46 +01:00
tprrt
b5ada042b5 image: zap_empty_root_password doesn't handle passwd file in shadow case
/etc/passwd isn't editted if /etc/shadow exists and should be else
it can cause problems with some login providers such as toybox.

(From OE-Core rev: 09ac2664fba223111c20c3000af6b8d5cdaabeb1)

(From OE-Core rev: ec4dba57eb95e31954dc74dd6489f70575b54d6f)

Signed-off-by: tprrt <tprrt@tupi.fr>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Krishnanjanappa, Jagadeesh
9f524997ff ghostscript: add objarch.h for armeb
ghostscript application fails to fetch objarch.h file while building for armeb.
The fetch failure is due to absence of this file in the default set of
directories that the OpenEmbedded build system searches (i.e FILESPATH)
for patches and files. This patch adds the required objarch.h file for
armeb in one of the default locations where OpenEmbedded build system searches.

(From OE-Core rev: c520165f8fe7c01865ddb2565908211c0cfd2185)

(From OE-Core rev: e56dea7dd588da62d33d33b21f857020d612e9f0)

Signed-off-by: Krishnanjanappa, Jagadeesh <jagadeesh.krishnanjanappa@caviumnetworks.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Paul Eggleton
4b64fb5baa classes/populate_sdk_ext: disable network connectivity check
Most of the time we shouldn't be downloading anything within the
extensible SDK (since it's all pre-built and we have the sstate
artifacts) therefore there's really no need for a connectivity
check, in fact it may just get in the way.

(From OE-Core rev: beaf851ae8aadb5b9e3c0b9840479efcbb05be23)

(From OE-Core rev: cc65df3aeb84e53a2608535c81e1e3f4dd9e8bc4)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Paul Eggleton
d730e14639 devtool: force use of bash when running build within extensible SDK
Ubuntu's default dash shell causes oe-init-build-env to behave a bit
differently - (a) it can't pick up the OE root directory and (b) it
can't see any build directory specified as a command-line argument
(since dash doesn't pass through any arguments specified to sourced
scripts). We could work around these but doing so requires some internal
knowledge of the script; a much simpler fix is just to force running the
command under bash since it's expected to be installed on every distro.

Thanks to Chen Qi <Qi.Chen@windriver.com> for this fix.

Fixes [YOCTO #7614].

(From OE-Core rev: 27942f546e6b08cdf9f2dbda2e24d237cde7f5f5)

(From OE-Core rev: f83f108f83766d4c141946084b7c4be730c2865e)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Carlos Rafael Giani
75a982e74f u-boot.inc: make sure all counter variables are properly unset
The script does "i == j" checks to retrieve the config <-> type pairs from
the UBOOT_MACHINE and UBOOT_CONFIG lists. This check however requires both
j and i to be initially unset. Ensure this by explicitely unsetting i.

This fixes broken u-boot SPL installations with SolidRun machines
(the SPL wasn't being installed and deployed.)

(From OE-Core rev: 50233dc2544fe8eeee69a5dc07f505db29fc9e0e)

(From OE-Core rev: a00cf56b0caf2327bd85b80c7d0db6f4d8620a36)

Signed-off-by: Carlos Rafael Giani <dv@pseudoterminal.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Reinette Chatre
1e64bf4a7e init-install-efi.sh: fix gummiboot entry installation
After selecting the "install" gummiboot option of a Live image we are
seeing boot failure resulting from the gummiboot entries not being
installed correctly. This seems to be a problem in this init-install-efi.sh
script where it incorrectly installs the gummiboot entries into the root
filesystem, not the boot partition. We fix it by installing the entries in
the boot partition.

(From OE-Core master rev: c9b06c79ed8a082d1b385e9f61721aeeda9bf1af)

(From OE-Core rev: 5d38c46689c9065992838b58e280886f4091f8fd)

Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Acked-by: Darren Hart <dvhart@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Robert Yang
427c70443d aspell: inherit binconfig-disabled
There is a pspell-config.

(From OE-Core master rev: 53c8a954e699b3ae3e7a0a2b3860cf7c9ad1288e)

(From OE-Core rev: 27bf71420b535678640f8edd0c6bc551bd322f1c)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:45 +01:00
Koen Kooi
0456e83de4 strace: fix build for aarch64
Upstream added aarch64 support but forgot to update 'make dist' leading to missing files in the tarball.

(From OE-Core master rev: a40309f284805e8cda024f7299a676cfdf8f97a5)

(From OE-Core rev: fd11110b7d63fce6a1f7a26f123ae7a8ddee3175)

Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Andre McCurdy
c18b02e5e9 busybox: remove CVE-2014-9645 patch (already upstream in 1.23.x)
The CVE-2014-9645 fix was merged in Busybox prior to the 1.23.0
release [1]. The fix was then reworked in Busybox 1.23.1, in such
a way that the original change was no longer required [2].

Although oe-core's CVE-2014-9645 patch still applies cleanly to
Busybox 1.23.1 and 1.23.2, applying it partially reverts the second
version of the upstream fix.

  [1] http://git.busybox.net/busybox/commit/modutils/modprobe.c?h=1_23_stable&id=4e314faa0aecb66717418e9a47a4451aec59262b
  [2] http://git.busybox.net/busybox/commit/modutils/modprobe.c?h=1_23_stable&id=1ecfe811fe2f70380170ef7d820e8150054e88ca

(From OE-Core master rev: a753d3d8884b96baad5ed1a03335a81586420b86)

(From OE-Core rev: ef1748f26ab246d893f51141caa24dd4ae6b5ec0)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Dmitry Eremin-Solenikov
aa263849ba lsb: provide lsb-core-ARCH
Some lsb packages depend on correct lsb-core-ARCH package being
installed (or rather provided) on the target file system. Provide this
package name by main lsb package.

(From OE-Core master rev: 981109b7388dcd0de9fd2e9cdfe2a920b9f8facb)

(From OE-Core rev: 65276d62f655926a82a17f02bb3a4ae0f08e6518)

Signed-off-by: Dmitry Eremin-Solenikov <dmitry_eremin@mentor.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Armin Kuster
534d2f3a5d crypto: use bigint in x86-64 perl
on some hosts openssl fails to build with this error:

ghash-x86_64.s: Assembler messages:
ghash-x86_64.s:890: Error: junk '.15473355479995e+19' after expression

backported fix from community.

(From OE-Core master rev: 8230f873921d5c16106e3ebf57053a646bc6ad78)

(From OE-Core rev: b981717484c70c6c9bcd6dacb736c2844fa863ed)

Signed-off-by: Armin Kuster <akuster@mvista.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Junling Zheng
2c3ae1ed7a elfutils: fix an incorrect patch for 0.161
The original uclibc-support.patch is not compatible with elfutils-0.161.
It should be corrected through adjusting context.

So regenerate a new patch for elfutils-0.161, rename the patch for
elfutils-0.148, and put them into respective directories.

(From OE-Core master rev: 64acb72e7ec63528073d8290137fe74d3382f876)

(From OE-Core rev: d4924543c265ca497d4c419d4571cf1f8ef31d09)

Signed-off-by: Junling Zheng <zhengjunling@huawei.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Gary Thomas
0c20afe810 gst-player: Fix typo
The subtitle (shown in desktop icon) should say
  Basic media player
    -not-
  Basic media plaer

(From OE-Core master rev: f672fae1b1647f7a628ba9ba92fd4fab81d91546)

(From OE-Core rev: d1f9764375a3f9187d523fa45639731a6619a691)

Signed-off-by: Gary Thomas <gary@mlbassoc.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Koen Kooi
aab4a03e19 libgpg-error 1.18: simplify tupple handling and add armv8b support
Add a default option to the case statement and remove the duplicates. Also add support for armv8b architectures.

(From OE-Core master rev: 8d207e55031c0b93387e728f4312b8cb34ad5b12)

(From OE-Core rev: 95a0b9305a17afb9eb317d9d946f721c462e0db6)

Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:44 +01:00
Khem Raj
47876b91e9 ppp: Add extra include dirs
Just run configure, the configure script is not really
a autoconf generated script so just run it

Include path is needed to be there since
the headers from it are used during build in subcomponents

Change-Id: Ib1f24fd18bc8564e3c74ab834b7cf0fdf955d0e1
(From OE-Core master rev: c64c9f7ffc88018404afdde373dfd7ef2bdf7ae8)

(From OE-Core rev: a11ebe122bc31127bae59a65dbabe9ce5c3f568c)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Jean-Benoit MARTIN
2536f8d363 package_manager: RpmPM: Fix scriptlet for rpm 4
Path of rpm post install script is different between rpm 4 and 5

(From OE-Core master rev: a880669f767532ce3c39eb160fa9deb9fce29677)

(From OE-Core rev: cc57a6827d383380b37d9df14ef799b10a62a469)

Signed-off-by: Jean-Benoit MARTIN <jean-benoit.martin@open.eurogiciel.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Robert Yang
c6269fbbc4 pcmciautils: fix for parallel build
Fixed:
Compiling lex_config.c.
  src/lex_config.l:34:25: fatal error: yacc_config.h: No such file or directory

There was a patch for fixing the paralle issue before, so modify the
patch again.

(From OE-Core master rev: e1193feb30fbbfacb430ccbb9f33cd782f7cb87d)

(From OE-Core rev: 0907c61d7b9ad892ae815d68393ed2e30881e289)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Mariano Lopez
52c03366ec kexec-tools: Add support for build with x32 ABI in x86_64
Add autoconf test for detect when build is x32 ABI this enables to
test into purgatory Makefile to avoid use -mcmodel=large flag in CC.

Add ELFCLASS read and syscall number into kexec, see patch.

[YOCTO #7419]

(From OE-Core master rev: 7b75430c2e3ffedb9ef4198fabf259b757b9ce5a)

(From OE-Core rev: 75e493b82e7ddb2730b0ede9aeb448c62d8bf032)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Aníbal Limón
c53661af38 nss: Fix build in x32 ABI
When try to build nss with x32 ABI enabled fails because
it need to be specified USE_X32 env var.

[YOCTO #7420]

(From OE-Core master rev: 2898c2cf94bd690ebfc4ab5f4d220e6ea05aca82)

(From OE-Core rev: 9eb690e7ce168bcf97055ba0e5325bd0b0107cb4)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Jukka Rissanen
2bb285d6b8 connman: Create connman.service at proper moment
ConnMan commit ac332c5d01b0737c18cb58c8ccc67cf6b0427e1d changes
how the connman.service file is created from .in file. After
that commit, the file is created by Makefile instead of configure.
This means that we need to tweak the service file in compile
time instead of configure time because the generated file will not
be there after the configuration.

This commit can be used even with older ConnMan version as the
connman.service file is there when the compilation happens.

(From OE-Core master rev: 32839103727d92a6580f916b6dd8e4439b2347c8)

(From OE-Core rev: 66d8cec7225cae7269c539d9372a1364c9cefc0d)

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Gary Thomas
5553c4cd8d libgpg-error: Fix native build on i686
Most modern x86 systems return i686 as the system type.  This
patch handles i486, i586 and i686 correctly.

(From OE-Core master rev: 1b24eaa71702c07e525d8a62c08c0983e9917468)

(From OE-Core rev: 8951cce6b9c68e3100ab2c568baf5148c1a0221d)

Signed-off-by: Gary Thomas <gary@mlbassoc.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:43 +01:00
Martin Jansa
aefa1a6eea tzdata: fix postinst
* add quotes around possibly empty tz variable
* use exit instead of return, because we're not in function and postinst
  fails:
  line 9: return: can only `return' from a function or sourced script"

(From OE-Core master rev: 87429d37e72b1fd2f329d693b4d1b1229a90e0a2)

(From OE-Core rev: ff58b2b6d07725adedddb709000775af8da3c5db)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Martin Jansa
bd7710bff7 pango: fix postinst
* merge postinst_prologue with the append in the do_split_packages call
  Now we can call correct pango-querymodules binary and respect D
  variable, otherwise we're trying to regenerate it on host which fails:
  pango-module-basic-fc.postinst: line 17: /usr/bin/pango-querymodules:
  No such file or directory

(From OE-Core master rev: f5d189b80a1fd7187f47678935f9a584ccff8d0a)

(From OE-Core rev: 3bbdb42c17222e78e3a4d043f26c9b2dce6d6891)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Krishnanjanappa, Jagadeesh
62675e990f dpkg: add triplet entry to fix build error for armeb
Cross-compling dpkg application for armeb fails with below error
during configure task,

(snip)
 configure:23141: checking dpkg cpu type
 configure:23148: result: armeb
 configure:23150: WARNING: armeb not found in cputable
 configure:23162: checking dpkg operating system type
 configure:23169: result: linux-gnueabi
 configure:23171: WARNING: linux-gnueabi not found in ostable
 configure:23183: checking dpkg architecture name
 configure:23189: error: cannot determine host dpkg architecture
-- CUT --

Add the required combination of "gnueabi-linux-armeb" entry in
triplet list.

(From OE-Core master rev: 63eb33bced1fc1e5451988fc5249ab362fb82615)

(From OE-Core rev: 0c83ca720ccfbef6964ac34fedfefa9006c484c4)

Signed-off-by: Krishnanjanappa, Jagadeesh <jagadeesh.krishnanjanappa@caviumnetworks.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Koen Kooi
006aafcb3c gst-ffmpeg: fix libav-9.patch
The patch has a stray '>' in an #incude directive leading to build
failures when used.

(From OE-Core master rev: f2a45c0c1b9878319890fe03f26dd4e0db740091)

(From OE-Core rev: 882cc6f7bb50022c2ed428537ffb09fd497de16d)

Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Koen Kooi
882f8c5743 gst-ffmpeg: remove bogus patch that leads to build failures
'0001-huffyuvdec-check-width-more-completely-avoid-out-of-.patch'
patches the internal copy of ffmpeg with a hunk that generates a compile
failure because AV_PIX_FMT_YUV422P is undefined.

(From OE-Core master rev: 3657e0fc2cd48a08035c7a0ab4da7e6666d2d91d)

(From OE-Core rev: b487d0a37536bb412cf332610f692d5eb3c8f3d9)

Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Koen Kooi
d685adb430 gst-ffmpeg: fix internal-libav builds with inherit autotools-brokensep
Building the internal copy of ffmpeg is broken when using S!=B, so
inherit autotools-brokensep

(From OE-Core master rev: 4ac5d1011fe6b5bba9511416082891e925cbd03c)

(From OE-Core rev: 0d118d0216f75221f17644ecd154637288c68c1c)

Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Andre McCurdy
35bbff5e5d libpcap.inc: remove obsolete libnl1 PACKAGECONFIG
There's no libnl1 recipe in oe-core (or any other layer in the layer
index).

Keeping the libnl1 PACKAGECONFIG is likely to cause problems for the
libnl PACKAGECONFIG since libnl and libnl1 both use --with-libnl and
--without-libnl.

(From OE-Core master rev: 4c820481147e9c11160b00f7df7ca8c329b23eac)

(From OE-Core rev: c914254e9ec218d590fc77b921dbddf31b2d41c7)

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:42 +01:00
Li Zhou
8766cae8b4 xorg-server: Security Advisory - xorg-server - CVE-2015-0255
Updated x11-server packages fix security vulnerability:

Olivier Fourdan from Red Hat has discovered a protocol handling issue in
the way the X server code base handles the XkbSetGeometry request, where
the server trusts the client to send valid string lengths. A malicious
client with string lengths exceeding the request length can cause the server
to copy adjacent memory data into the XKB structs. This data is then
available to the client via the XkbGetGeometry request. This can lead to
information disclosure issues, as well as possibly a denial of service if a
similar request can cause the server to crash (CVE-2015-0255).

(From OE-Core master rev: 564e2f9732ac4318bb5923dd1ff771514c9afd2f)

(From OE-Core rev: edde2ef38d483888e5daa7c00007cb1b84de6336)

Signed-off-by: Li Zhou <li.zhou@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Khem Raj
f416e2b9bb libffi: Use proper compiler define for linux platform
Change-Id: I8253249a2e1c5e9ded0d028545f21cfdc093c3cd
(From OE-Core master rev: f7307ea20c8aa4aed4c38a7c15fb9b3b6b836035)

(From OE-Core rev: df99dd90255e46b226f4eea7b3c0d81f548adaf9)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Khem Raj
0c045cab74 libusb-compat: Include sys/types.h in usb.h
Fixes compile errors when usb.h is included in
other packages, it expects sys/types.h to be
there, instead it should include it itself

Change-Id: Ib49477b7d3f3cd97d65c9578bdc33f2ee33f5a26
(From OE-Core master rev: 577b5c6ce6753b9ae3587da47caf6ecfac358668)

(From OE-Core rev: 833165b96b8b51292ad9758a491abce7f380f6de)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Khem Raj
8d6080ebe0 bluez4: Fix encrypt symbol namespace collision
| Makefile:3352: recipe for target 'test/l2test.o' failed
| make[1]: *** [test/l2test.o] Error 1
| make[1]: *** Waiting for unfinished jobs....
| test/rctest.c:82:12: error: 'encrypt' redeclared as different kind of
symbol
|  static int encrypt = 0;
|             ^
| In file included from test/rctest.c:33:0:

Change-Id: Iaf2f644ef3cef6f96c6e4bc421c9e78a0e23e674
(From OE-Core master rev: 795a409919774f3a2a4c859799de36f1064efd83)

(From OE-Core rev: 899a6f213eb350334987e818094c8acd7ab513ab)

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Matt Madison
c3613297f0 shadow: split files needed for PAM use into separate package
The rootfs creator automatically removes shadow for read-only
root filesystems, which breaks use of PAM plugins for login and
other process identity management utilities.  Package those programs
and config files separately, so they don't get removed.

(From OE-Core master rev: a7d8eaef04c9dd6ede8d4efd8c4b776efbe3c767)

(From OE-Core rev: 783982314f140611ba2056a280421085bba5c155)

Signed-off-by: Matt Madison <matt@madison.systems>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Nathan Rossi
ec3a90915f python: Change python 2.7.9 to use libffi from the system
Changes in python 2.7.9 from 2.7.3 cause issues when building the in
tree libffi for ctypes. These issues primarily affect less common
platforms (e.g. MicroBlaze) that are supported by libffi but the python
overrides for the in tree libffi are not able to detect correctly.

This patch changes the python 2.7.9 recipe to match how the python 3
recipe handles libffi by configuring the build to use the system
libffi. This brings consistency between the libffi used for different
python versions as well as with the system.

(From OE-Core master rev: 4302cc20dbe0f0490a5e7b62baeb632322c40200)

(From OE-Core rev: 9f7b0133b63d315703d0c44e877ae81d4a9a1692)

Signed-off-by: Nathan Rossi <nathan.rossi@xilinx.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Wenzong Fan
75c0781c5e perl: module overload rdpends on overloading
Fix perl runtime issue:

* Can't locate overloading.pm in @INC (you may need to install the
overloading module ...) at /usr/lib64/perl/5.20.0/overload.pm line 83.

(From OE-Core master rev: 3dec9ad1cd6ad1236950b0100f6327df7a0bf7db)

(From OE-Core rev: cecac1d52143e34b6e1142e38a1c874188dd74e9)

Signed-off-by: Wenzong Fan <wenzong.fan@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:41 +01:00
Denys Dmytriyenko
e267a38cd7 security_flags.inc: elfutils on ARM fails with PIE flags
The error messages look like this:
R_ARM_TLS_LE32 relocation not permitted in shared object

(From OE-Core master rev: a915adfd1eaad9a0d65dffe9da92811284e491c8)

(From OE-Core rev: 1d8cbf8354e734253e335fee2c423b3a108454bd)

Signed-off-by: Denys Dmytriyenko <denys@ti.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Christopher Larson
5b7487567c oe.sstatesig: align swspec handling with sstate.bbclass
The logic tries to remove the -native suffix from pn to handle this (though it
doesn't succeed, as it doesn't assign the new pn to the variable), but we need
to do more for the swspec tasks than just not set the extrapath, we also need
to change from SSTATE_PKGSPEC to SSTATE_SWSPEC. Alter to correct the spec for
these cases, and also add preconfigure to align with the current logic in
sstate.bbclass, which includes that task as well in the list of tasks to
adjust to use swspec.

[YOCTO #7563]

(From OE-Core master rev: c9105597763be4bf5bc0ec97cc999566d0f10678)

(From OE-Core rev: 4f9cde9d8e700d10cdb1da82bf7489df5633c549)

Signed-off-by: Christopher Larson <kergoth@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Mario Domenech Goulart
66fc24c6cb useradd_base.bbclass: typo fixes (s/scucess/success/)
(From OE-Core master rev: eace0a2c13721d1b8952a01abac30eb2661fcd85)

(From OE-Core rev: b073f927ec332c5a3608277751ef27d9280c51d8)

Signed-off-by: Mario Domenech Goulart <mario@ossystems.com.br>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Matthieu Crapet
310e37485b util-linux: add lastb.1 and nologin.8 to update-alternatives
/usr/share/man/man1/lastb.1
is also provided by sysvinit recipe.

/usr/share/man/man8/nologin.8
is also provided by shadow recipe.

(From OE-Core master rev: 8fdf9a355291e7341f9c9a6c219349cf95326171)

(From OE-Core rev: 1aaa289be5aeb066e378c2119be9f5ac055d4803)

Signed-off-by: Matthieu Crapet <Matthieu.Crapet@ingenico.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Aníbal Limón
5edbe941f9 lzop: Fix build using x32 ABI
When tries to build lzop using x32 ABI fails trying to get
FLAGS register that is 64-bit and destination variable is
32-bit size_t.

[YOCTO #7424]

(From OE-Core master rev: 6122c5e02b96ab786204d08b470177d824004d24)

(From OE-Core rev: 842558c5fb2ef0520b7a11516dc720694e5acf04)

Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Junling Zheng
66b63d921b uclibc: fix undefinition of '_dl_strchr' in libdl.a
The orign_path.patch introduced '_dl_strchr' in ldso/ldso/dl-elf.c, and
caused the following undefined referencing compiling error:

  | .../libdl.a(libdl.os): In function `search_for_named_library':
  | .../dl-elf.c:156: undefined reference to `_dl_strchr'
  | collect2: error: ld returned 1 exit status

I found this problem when compiling gdb in static mode using uclibc.

So, add the definition of '_dl_strchr' to fix it. The '_dl_strstr' is
added as well.

And I regenerated a patch to replace the original one.

(From OE-Core master rev: 34b82b8452aa721146f95321cfd1a1fee3f0d6c8)

(From OE-Core rev: c39c0d0426b2f9b2c13403705167e2d8201df1ff)

Signed-off-by: Junling Zheng <zhengjunling@huawei.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Joe Slater
08b10e93c4 nss: generate debug info
Because the build of nss seems to ignore CFLAGS, we never
have put source code in the -dbg package.  We do not address
the CFLAGS issue, but we do add -g to the definition of CC
so that we will generate debug info.

We also let package.bbclass populate the -dbg package instead
of forcing the contents locally.

(From OE-Core master rev: 0ec01bbd845b61798366441b2c7e5b8738db6b32)

(From OE-Core rev: 24a55a1e9658fdfd7b314ce1d9f40e0374990b7a)

Signed-off-by: Joe Slater <jslater@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:40 +01:00
Jun Zhu
a536594605 meta/lib/oe/utils.py: Corrected the return value of both_contain()
oe.utils.both_contain() should return the result as "checkvalue" or "",
but the latest implement returns as "set(['checkvalue'])" or "";

It causes that bitbake.conf generates the wrong result of COMBINED_FEATURES,
which contains the common components in both DISTRO_FEATURE and MACHINE_FEATURES.

For example, build in Dizzy branch, COMBINED_FEATURES is "alsa usbhost ...",
but recently, COMBINED_FEATURES is like "set(['alsa']) set(['usbhost']) ...".

(From OE-Core master rev: c4ca9dbd4191fcff08e75035e3d276490ed80b05)

(From OE-Core rev: 9471b87ecadeeba8e8ffe6955ec1dedc976a2978)

Signed-off-by: Jun Zhu <R01007@freescale.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-15 18:12:39 +01:00
Scott Rifenbark
e2e522a6ed ref-manual; mega-manual: Edits to further define packaging process
In response to community input where developers were attempting to
locate information on how to write packages out to a directory
other than ${DEPLOY_DIR}/<package_type>, I updated the "Package
Feeds" section, added several new DEPLOY_DIR_* variables, updated
four classes, and updated four tasks.  Here are some details:

 * Made changes to the "Package Feeds" section to provide more
   accurate information in the package feeds directory structure
   used by the build system in build/tmp.  These changes included
   updating the figure itself and some explanatory text.

 * Updated the DEPLOY_DIR variable description.

 * Added new variable descriptions for DEPLOY_DIR_DEB, DEPLOY_DIR_IPK,
   DEPLOY_DIR_RPM, and DEPLOY_DIR_TAR.

 * Updated the related classes: package_deb, package_ipk, package_rpm,
   and package_tar.

 * Updated the related tasks: do_package_write_deb, do_package_write_ipk,
   do_package_write_rpm, and do_package_write_tar.

Reported-by: Trieu Nguyen <trieu.t.nguyen@intel.com>
(From yocto-docs rev: a8d499850dec72f8decd81ec6714809c3a580ffc)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-03 11:49:38 +01:00
Scott Rifenbark
145fe000ac ref-manual: Updated the "Image Features" section
Removed the requirement that debug-tweaks is needed in order to
individually use the allow-empty-passowrk, empty-root-password,
and post-install-logging features.  These three features can be
individually turned on an off regardless of debug-tweaks.

(From yocto-docs rev: e9f2e2b0f094cf243d601ee3fcdf9588cc81e003)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-03 11:49:38 +01:00
Scott Rifenbark
4206fcbf22 dev-manual: Updates to add Luna support for Eclipse
Adding Luna and dropping Juno. Pretty much went through the
"Working With Eclipse" section and dropped Juno and added
Luna.  A major deletion was the BitBake Commander section using
Hob.  Todor told me to drop this section completely.  Note that
I also added a couple new YoctoProjectTools that appear on the
menu: SystemTap and yocto-bsp.

(From yocto-docs rev: 6dc7d842acb0f190138418c7bf874999219cbead)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-05-03 11:49:38 +01:00
Scott Rifenbark
f366ff2c03 ref-manual: Updated the ELF Binary QA warning message
Fixes [YOCTO #7630]

I applied some feedback from Laszlo Papp suggesting that the user
can also use '-fpic' as well as '-fPIC' for a command-line option.

(From yocto-docs rev: 750ff4d3203f358595df8d10cc57e8d63a9fef4a)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-28 16:31:00 +01:00
Scott Rifenbark
320a2206e0 dev-manual; ref-manual: Fixed &dash; issue
Fixes [YOCTO #7386]

Apparently the "&dash;" ENTITY used throughout the YP manual set to
get literal "-" characters in example commands renders into a unicode
that is not a dash.  This results in users getting errors if they
attempt to cut-and-paste a sample command that uses a "-" character
from the manual into a shell.  I have universally replaced all the
"&dash;" strings in the YP manual set to "-" strings.

(From yocto-docs rev: 1309e124d83fdf3c98be5c3ff1943f1c0d496c20)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-28 16:31:00 +01:00
Maxin B. John
e4f3cf8950 curl: several security fixes
Fixes below listed bugs:
1. CVE-2015-3143
2. CVE-2015-3144
3. CVE-2015-3145
4. CVE-2015-3148

(From OE-Core rev: cd3da9c95f48899e134a5b7ed1754fd18985df4f)

Signed-off-by: Maxin B. John <maxin.john@enea.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-27 15:25:43 +01:00
Martin Jansa
2a9486875d fontcache: allow to pass different fontconfig cache dir
(From OE-Core rev: adfb970efcb30af9b3b420b06b66e2aa6cc00ab4)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-27 15:02:35 +01:00
Martin Jansa
28e8418644 image.bbclass: Allow to remove do_rootfs -> virtual/kernel:do_packagedata dependency
* this is causing dependency loops in some cases
  e.g. linux-hp-tenderloin depends on initramfs-android-image, but
    commit 41f0f86ec0a3e0b6f6c9bb4ef71a4215c00bf66c
    Author: Richard Purdie <richard.purdie@linuxfoundation.org>
    Date:   Tue Jan 27 15:24:52 2015 +0000
    Subject: image: Add missing depends on virtual/kernel for depmod data
  adds also dependency between <image>.do_rootfs and virtual/kernel:do_packagedata
  causing this dependency loop:

Dependency loop #1 found:
  Task 78 (meta-smartphone/meta-hp/recipes-kernel/linux/linux-hp-tenderloin_git.bb, do_install)
    (dependent Tasks ['linux-hp-tenderloin, do_compile',
                      'pseudo, do_populate_sysroot'])
  Task 88 (meta-smartphone/meta-hp/recipes-kernel/linux/linux-hp-tenderloin_git.bb, do_package)
    (dependent Tasks ['rpm, do_populate_sysroot',
                      'pseudo, do_populate_sysroot',
                      'linux-hp-tenderloin, do_install',
                      'initramfs-android-image.bb, do_packagedata',
                      'glibc, do_packagedata',
                      'file, do_populate_sysroot',
                      'gcc-runtime, do_packagedata'])
  Task 89 (meta-smartphone/meta-hp/recipes-kernel/linux/linux-hp-tenderloin_git.bb, do_package_write_ipk)
    (dependent Tasks ['linux-hp-tenderloin, do_package',
                      'opkg-utils, do_populate_sysroot',
                      'linux-hp-tenderloin, do_packagedata',
                      'pseudo, do_populate_sysroot'])
  Task 560 (meta-smartphone/meta-android/recipes-core/images/initramfs-android-image.bb, do_rootfs)
    (dependent Tasks ['bash, do_package_write_ipk',
                      'run-postinsts, do_package_write_ipk',
                      'db, do_package_write_ipk',
                      'update-rc.d, do_populate_sysroot',
                      'android-tools-conf, do_package_write_ipk',
		      'base-passwd, do_package_write_ipk',
                      'initramfs-boot-android, do_package_write_ipk',
		      'expat, do_package_write_ipk',
                      'bzip2, do_packagedata',
		      'glibc-initial, do_packagedata',
                      'openssl, do_package_write_ipk',
                      'bzip2, do_package_write_ipk',
		      'busybox, do_packagedata',
                      'zlib, do_packagedata',
		      'qemuwrapper-cross, do_packagedata',
                      'base-passwd, do_packagedata',
		      'busybox, do_package_write_ipk',
                      'zlib, do_package_write_ipk',
		      'qemuwrapper-cross, do_package_write_ipk',
		      'gcc-runtime, do_package_write_ipk',
		      'gettext, do_packagedata',
		      'initramfs-boot-android, do_packagedata',
		      'gettext, do_package_write_ipk',
		      'libgcc-initial, do_packagedata',
                      'expat, do_packagedata',
                      'gdbm, do_packagedata',
		      'depmodwrapper-cross, do_package_write_ipk',
                      'libgcc-initial, do_package_write_ipk',
                      'glibc-initial, do_package_write_ipk',
                      'linux-libc-headers, do_packagedata',
                      'glibc, do_packagedata',
                      'initramfs-android-image.bb, do_packagedata',
                      'glibc, do_package_write_ipk',
                      'sqlite3, do_packagedata',
                      'initramfs-android-image.bb, do_package_write_ipk',
                      'sqlite3, do_package_write_ipk',
                      'android-tools-conf, do_packagedata',
                      'ncurses, do_packagedata',
                      'openssl, do_packagedata',
                      'android-tools, do_packagedata',
                      'ncurses, do_package_write_ipk',
                      'cryptodev-linux, do_packagedata',
                      'android-tools, do_package_write_ipk',
                      'pseudo, do_populate_sysroot',
                      'cryptodev-linux, do_package_write_ipk',
                      'linux-libc-headers, do_package_write_ipk',
                      'depmodwrapper-cross, do_packagedata',
                      'linux-hp-tenderloin, do_packagedata',
                      'readline, do_package_write_ipk',
                      'opkg-utils, do_packagedata',
                      'linux-hp-tenderloin, do_package_write_ipk',
                      'python, do_packagedata',
                      'gdbm, do_package_write_ipk',
                      'opkg, do_populate_sysroot',
                      'python, do_package_write_ipk',
                      'libtool-cross, do_packagedata',
                      'db, do_packagedata',
                      'libgcc, do_packagedata',
                      'libtool-cross, do_package_write_ipk',
                      'update-rc.d, do_packagedata',
                      'update-rc.d, do_package_write_ipk',
                      'libgcc, do_package_write_ipk',
                      'opkg-utils, do_populate_sysroot',
                      'makedevs, do_populate_sysroot',
                      'readline, do_packagedata',
                      'base-files, do_packagedata',
                      'gcc-runtime, do_packagedata',
                      'opkg-utils, do_package_write_ipk',
                      'base-files, do_package_write_ipk',
                      'ldconfig-native, do_populate_sysroot',
                      'bash, do_packagedata',
                      'run-postinsts, do_packagedata'])
  Task 82 (meta-smartphone/meta-hp/recipes-kernel/linux/linux-hp-tenderloin_git.bb, do_compile)
    (dependent Tasks ['initramfs-android-image.bb, do_rootfs',
                      'linux-hp-tenderloin, do_configure'])

(From OE-Core rev: 10399fd97439af12cc23f199ec668a43c230ded4)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-27 15:02:35 +01:00
Martin Jansa
97e5d37719 elfutils: fix build with -Os
(From OE-Core rev: cd8c20f10381595d44b9e8d251a1b5bd6c6176b2)

Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-27 15:02:34 +01:00
Paul Eggleton
7209c0bb13 bitbake: lib/bb/utils: add safeguard against recursively deleting things we shouldn't
Add some very basic safeguard against recursively deleting paths such
as / and /home in the event of bugs or user mistakes.

Addresses [YOCTO #7620].

(Bitbake master rev: 56cddeb9e1e4d249f84ccd6ef65db245636e38ea)

(Bitbake rev: 9178a708ecd75758be360a5a6bb04c77b69be5d8)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:33:11 +01:00
Anders Darander
4c8b3e10f7 bitbake: fetch/git: Remove a possible trailing '/' in subpath
If the subpath parameter to the git fetcher ends with a trailing '/',
 bb.utils.prunedir() will be called on '/'...

Fixes [YOCTO #7620].

(Bitbake master rev: 380a3fb372c8b0a53dd7528562e6e7a222dc76ef)

(Bitbake rev: 7110055ab26d40e2a4e83956177b59a58e9cdcfd)

Signed-off-by: Anders Darander <anders@chargestorm.se>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:33:11 +01:00
Scott Rifenbark
63ee4133b8 yocto-project-qs: Replaced GNOME Mobile with GTK+ wordings.
GNOME Mobile no longer applies.  I updated text to use the
GTK+ wordings.

(From yocto-docs rev: 978878d3f1a7ea07a68f0aeae93eeae7ba58b8f3)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:51 +01:00
Scott Rifenbark
47aee60bfe toaster-manual: Removed redundant video.
(From yocto-docs rev: 5ae1d89a1384790644016e79afea1a70edcf88f3)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:51 +01:00
Scott Rifenbark
69cdf9658a ref-manual: Added glossary entry for EXTERNAL_KERNEL_TOOLS
(From yocto-docs rev: b4f3b0c2efc6a162d714a2180bf48aac47684a27)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:51 +01:00
Scott Rifenbark
4a90b6b0d9 ref-manual: Updates to ELF binary QA warning
Fixes [YOCTO #7630]

Apparently the text relocation being done here can cause runtime
performance issues.  I documented a potential work-around for the
issue and provided a cross-reference link to an external site for
more general information about text relocation at runtime.

Reported-by: Laszlo Papp <lpapp@kde.org>
(From yocto-docs rev: f7f611a6668b6cd2ee3928ad44c72dbbe5307c38)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
0c7340105e ref-manual: Removed FAQ question for GNOME Mobile.
(From yocto-docs rev: 12e61c66685f3ab8dc49a5c0d808aabc0b524e21)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
ac91a56adc ref-manual: Fixed some dashes in the user input examples.
I typically try to use the underscore character to string together
multi-word user-input descriptors in examples.  I fixed a bunche
here.

(From yocto-docs rev: f7bc59cfb88537a2e3045a44978e974227b8ea9f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
831fe9fa27 ref-manual: Fixed some formatting on a user-input example.
(From yocto-docs rev: d27d950d8a128c06684c3bc9e55c73c5f4f9658b)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
0947319266 ref-manual: Removed tag from profile-manual cross-ref
In the introduction, the ref-manual references several other YP
manuals.  If the manual is build separately, these references resolve
to the appropriate manuals.  When the mega-manual is built, the
same references are designed to not become links.  In otherwords,
mega-manual.sed processes those links out.  This is by design.

I found a #profile-manual tag on one of the links in the introduction.
This resulted in a link in the mega-manual that would go nowhere.  I
removed the tag.

(From yocto-docs rev: 5284004cb4f619b0580b525f67a3ebc7be1cdb93)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
da7196cc2d bsp-guide: Fixed link to the OpenEmbedded style guide.
A link was going to an old YP page that talked about patch
style guide stuff.  That page simply redirects the user to a
styleguide of the OE.  I fixed the link in the manual to go
directly to that page now.

(From yocto-docs rev: 256285af25d46c1cfcd09daae1a5d1f8045bbb0d)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
8614206f39 adt-manual: fixed formatting for user-supplied data in example.
(From yocto-docs rev: c3c264f14961c1e43da7bb0177cee4e3b4440b92)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
06cbcff7be dev-manual: Applied some formatting for user input.
(From yocto-docs rev: 1463f3b5f51b82bd7a4dd953003a1d24ef01178b)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:50 +01:00
Scott Rifenbark
12cc91a768 dev-manual: Fixed link to Toaster Manual.
I found a link that is processed by the mega-manual.sed file correctly
but for the situation it does not resolve right.  The link is a
"naked" link.  In other words, it doesn't have a #<tag> part.
When the .sed file sees these types of links, no hyperlink is
generated.  I found a case in the dev-manual where I reference the
Toaster Manual in general and would like a link that would take the
user there.  So, I had to add a #<tag> part to the link in the XML

(From yocto-docs rev: 29c751888f16b9a2b73b64fe78eca6b7c661b2f4)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
fea38f087c dev-manual: Fixed a cross-ref link that used "here" as the link.
I don't like these.  I fixed it up.

(From yocto-docs rev: be9ec19a9ba0650efa6562de350c8d6bb83db85f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
fe996c253e dev-manual: Added Toaster to the list of ways to develop.
I put this in the intro list for the section that presents various
ways to use YP.

(From yocto-docs rev: f5dd577d9b72a6433c647816464213cf83fb9bad)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
9dcec27bd5 dev-manual: Removed a cross-ref link to "here"
This practice is not good.  I had one in the manual.  I reworded
the text to not use that term in a link.

(From yocto-docs rev: 8c56090d52a9844c4aa072b4eaa4ee32a03d8352)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
854edda7d7 dev-manual: Updated branch descriptions for better manual maintenance
The "Repositories, Tags, and Branches" section had some wording
that described how branches are maintained in the poky repo that
made it hard to maintain in the doc from release to release.  I had
a list of past releases by name and as such would have to update
it every release to make it reflect the last set.  Well... this
is not the best way to do this and proved out as it slipped through
the cracks for the YP 1.8 release.  Consequently, I recast the text
so it is "release proof".

(From yocto-docs rev: 5ed1238f53320a3aa1f00ea04191cacdad5fbe95)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
4aa45aca7a ref-manual: Removed "Intel Corporation" from the "Links" section.
In an attempt to keep the project as much open source as possible,
I removed the link to Intel from this list of resources.  We don't
list Linux, OpenedHand, Wind River, etc.

(From yocto-docs rev: 0c2223e788f8b87c376846ae724b7f8e26513559)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
c6a9013728 dev-manual: Updated the poky definition in the "Terms" section.
Added some stuff about "poky" meaning the default distribution
when using YP and the poky git repository to build an image.

(From yocto-docs rev: 8f78b6d29676b953ce1d09d785d259630e4acce0)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:49 +01:00
Scott Rifenbark
1cc6544d69 ref-manual: Updates to ELF binary QA warning - review changes
Applied some review edits from Paul.

Fixes [YOCTO #7630]

(From yocto-docs rev: 0b7b3d36565da6745a13f5f6d17174e9d69c072e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:48 +01:00
Michael Wood
19933e4474 dev-manual: Updated the "Enabling and Using the Tool" section
The send-error-report tool syntax has slightly changed since the
documentation was written.  Removed the [server] part of the
command and added more detail on its use and results.

Reported-by: Michael Wood <michael.g.wood@intel.com>
(From yocto-docs rev: b0d427ac0c520dbaff6b3222f1d0e4ac617f5d41)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:48 +01:00
Ed Bartosh
41432d9d79 dev-manual: Updated "Requirements" section for creating partitioned images
Wic is not using parted and other runtime dependencies from host
system anymore.  It uses native tools instead.  Removed host parted
from the list of requirements.  Added instructions to build native
tools.

(From yocto-docs rev: 6c84e9d4f969952240a869ec83ea149a75c17978)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:48 +01:00
Scott Rifenbark
7144eb7774 ref-manual: Updates to the TCLIBC variable description
An old note still existed in this entry that stated we don't support
glibc.  This is not true.  I deleted the note.

Reported-by: Paul Eggleton <paul.eggleton@intel.com>
(From yocto-docs rev: afebdfd994a4ff57cf8f5db1d0d7731433f831f2)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:48 +01:00
Scott Rifenbark
59e5021b1f ref-manual: Fixed style sheet
Style sheet was not spacing after the first paragraph for glossary
entries.

(From yocto-docs rev: 9a3e29acc18c89d00ba5b176bd6fcbabb32d4be0)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-24 11:07:48 +01:00
Bryan Evenson
17c5df02e2 initscripts: Remove /etc/volatile.cache on upgrade
/etc/volatile.cache is a cached copy of a script (which is
generated by /etc/init.d/populate-volatile.sh) that generates
the volatile filesystem directories.  Since volatile.cache is
a generated file, it is not necessarily changed if
populate-volatile.sh is updated.  As a result, the stale script
can add/remove the wrong directories on the next system boot.

If initscripts is being upgraded, make sure volatile.cache gets
deleted.

(From OE-Core rev: 1ee8bd05042087ffdced4cb40c55d0e45b06481c)

Signed-off-by: Bryan Evenson <bevenson@melinkcorp.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-20 15:03:11 +01:00
Bryan Evenson
075f0b2c88 base-files: Check for /run and /var/lock softlinks on upgrade
Commit ea647cd9ee moved the locations
of /run and /var/lock to match the FHS 3 draft specifications.
However, the install doesn't remove the existing directories.
As a result, upgrading a system may result in /run as a softlink
to /var/run and /var/run as a softlink to /run, creating a circular
link.

During pre-install, check for the existence of the old softlinks and
remove them so the new directories can be installed.

(From OE-Core rev: c1ee31acf509b054453f19cab162dadc295e10a4)

Signed-off-by: Bryan Evenson <bevenson@melinkcorp.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-20 15:03:11 +01:00
Richard Purdie
70832d863f toolchain-scripts: Allow the CONFIGSITE_CACHE variable to be overridden
In multilib and baremetal configurations, this variable can cause a variety of
problems due to the use of TCLIBC. At least allowing it to be overriden
is a start and allows various configurations to avoid the issue.

(From OE-Core rev: d343c6a7369cb409563b8149cbb423a6171221ee)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-15 15:56:02 +01:00
Scott Rifenbark
90d943ae62 ref-manual: Corrected the "package_rpm.bbclass" section.
A cut-and-paste error had left a "package_deb" string in the
first sentence of the section.  Replaced with "package_rpm."

Reported-by: Geoffroy VanCutsem <geoffroy.vancutsem@intel.com>
(From yocto-docs rev: 38b20d775ba41cb14d86177dddd85ada32fb3f86)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-10 14:47:50 +01:00
Scott Rifenbark
46669d3074 ref-manual: Update to oe-init-build-env-memres description.
Fixes [YOCTO #7559]

Removed the information stating that the port address 12345 is used.
Really what happens is a random port address is used.

(From yocto-docs rev: f469c2431b26593a762e348e9c5d0e84c582eab8)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-10 14:47:50 +01:00
Scott Rifenbark
8f39398dbf ref-manual: Updates to "Kernel Build Changes" in the 1.8 migration section.
Updated this according to some changes Richard and Paul wanted to
see make it into the 1.8 release.

Reported-by: Paul Eggleton <paul.eggleton@intel.com>
(From yocto-docs rev: f571e35169818355fea2a20715df3e8f7405134f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-10 14:47:50 +01:00
Scott Rifenbark
be46715a9d toaster-manual: Fixed release month in the manual table.
(From yocto-docs rev: 1c67a2a19d5dd75030928c6f571d516e5edd0b99)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-10 14:47:50 +01:00
Scott Rifenbark
f73d6752db toaster-manual: Added new video link for toaster configuration.
(From yocto-docs rev: 8e418e1b203d749bd939bf0f109fb8fce6053ceb)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
2015-04-10 14:47:50 +01:00
Richard Purdie
33558eacc8 build-appliance-image: Update to fido head revision
(From OE-Core rev: fbf82a3c5d891c298073077edcd894293ea4d8e3)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 20:32:54 +01:00
Scott Rifenbark
0db74ea8f4 tools: A real fix for thos mega-manual.sed file for Toaster.
The previous commit did not fix the problem.  This one does.

(From yocto-docs rev: d19c2096018db0127d11814ddcba919ad469e428)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 20:31:32 +01:00
Scott Rifenbark
08246fc7d4 tools: Updated the mega-manual.sed file to include the Toaster manual.
(From yocto-docs rev: 36f9685837da5d202372933bfa895e8a3724dd5c)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 20:31:32 +01:00
Scott Rifenbark
d691916ef8 toaster-manual: Review edits applied.
Some steps updated according to Belen and a video link fixed to
not point to Belen's Youtube area.

(From yocto-docs rev: 557c22fdd287160f6aabac0928ce6bd8d6af3394)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 20:31:31 +01:00
Scott Rifenbark
2f6a0659fe toaster-manual: Updated customization layer to not use local XSL file.
(From yocto-docs rev: f33dee9e57a8adc18d4674f97c0f77ccbbb4a6e5)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 20:31:31 +01:00
Scott Rifenbark
888fb56e97 dev-manual: Fixed bitbake -c populate_sysroot example.
This was incorrectly stated as 'bitbake -c install' in two
places.  I substituted the correct string.

(From yocto-docs rev: fe54de82cff054d4319c635a0ddba2de7cc6ebd6)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 17:42:24 +01:00
Scott Rifenbark
1444bef551 ref-manual: Edits to the 1.8 migration section.
(From yocto-docs rev: 9509c22e6e9fb1dfaabe634cb554f1f68d8ea434)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 17:42:24 +01:00
Scott Rifenbark
d1df6afab2 toaster-manual: Applied final review edits.
This should be it unless there are late coming comments.

(From yocto-docs rev: cb32e3330a6fe2d26425f8765689749afcd989e9)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:04:57 +01:00
Scott Rifenbark
faf19c5274 ref-manual: Added new migration section for going to 1.8
(From yocto-docs rev: b8c7fad5404eb111c0d6a39fae6e9ffcb4a615ba)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:04:56 +01:00
Scott Rifenbark
dee274305d ref-manual: Added new bluetooth class.
(From yocto-docs rev: 536117974fb08c1c6739af9c8200b228a59b7f6d)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:04:56 +01:00
Ed Bartosh
20d2d2096a package_manager: call createrepo with --dbpath pointing inside WORKDIR
Rpm database in staging area is used only by createrepo.
createrepo fails with the error
"rpmdb: BDB0060 PANIC: fatal region error detected"
if rpm database is broken during previous run of createrepo.

Made createrepo to create rpm db in $WORKDIR/rpmdb/ from scratch
for every build and architecture. This should potentially fix the
failure as every run of createrepo will be using separate db.

[YOCTO #6571]

(From OE-Core rev: db21bdcba5e2f646f0dc47295e8ea7e4d49a880d)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:02:49 +01:00
Ed Bartosh
a274e39f0c createrepo: Implement --dbpath command line option
--dbpath option can be used in cases where users don't want
createrepo to use system rpm db to avoid possible collisiouns
with other programs.

For bitbake builds it would be possible to specify different
databases even for every createrepo run. Considering that rootfs
builds can run multiple createrepo in parallel, it can help to avoid
race conditions caused by accessing or creating the same rpm database
by multiple createrepo instances at the same time.

(From OE-Core rev: 32324c0d7f669083cc7066e6dfc8c58248fb5429)

Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:02:49 +01:00
Robert Yang
dfaa74d34f glibc: fix a typo
Fixed a typo:
name-target-directory -> make-target-directory

There is no name-target-directory, it should be make-target-directory,
this fixed the error:
/bin/bash: /path/to/elf/runtime-linker.T: No such file or directory
Makefile:361: recipe for target '/path/to/elf/runtime-linker.st' failed

(From OE-Core rev: ff1366b0c9db9425d2a29eb823116353f3856dbb)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:02:48 +01:00
Robert Yang
d66075e595 db: fix parallel issue
Fixed parallel issue:
libtool: link: `bt_rec.lo' is not a valid libtool object
Makefile:867: recipe for target 'libdb-6.0.la' failed
make: *** [libdb-6.0.la] Error 1

(From OE-Core rev: 14b7787cfb1318e67ac2721c0d9d5dbf5be9dec4)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-02 12:02:48 +01:00
Scott Rifenbark
5f46b438a8 ref-manual: Updates to doc packages and reference links
I added xlstproc to Fedora and CentOS package lists for building out
the docs.

I abbreviated the list of references in the end chapter by leaving
just the main URLs for bigger areas such as Intel, OE, etc.  Then
I put in a link that goes back to the dev-manual list of other
informations as that is much more comprehensive.

(From yocto-docs rev: 81667b85cd8c639dd32cd5a8f614b4c890eb4dde)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:17 +01:00
Scott Rifenbark
674ffa8c68 bsp-guide: removed the BBLAYERS_NON_REMOVABLE from the example code.
(From yocto-docs rev: 35a92477897652a9af2b1a257a4576926612e054)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:16 +01:00
Scott Rifenbark
9b6eee9f30 dev-manual: Removed the detailed section on how to set up and use Toaster
(From yocto-docs rev: f3704c61a6def095cd6632ce2ad223ea84e35dac)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:16 +01:00
Scott Rifenbark
c636c22484 dev-manual: Added a small section to note Toaster as a development model.
(From yocto-docs rev: 63e73beca3b7d084c4776f296d3310a31dafcfc4)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:15 +01:00
Scott Rifenbark
98ae8387e3 dev-manual: Fixed a few broken links and added Toaster manual to list.
(From yocto-docs rev: 77e3a4c704836e599b8ef6b13e68ec783e6d642d)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:15 +01:00
Scott Rifenbark
f96ffe74a9 yocto-project-qs: Fixed broken link to AB nightly builds.
(From yocto-docs rev: 848dc6afa663a6730953736cf50f58130da30181)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:14 +01:00
Scott Rifenbark
66f1700481 ref-manual: Updated the OE_TERMINAL variable description
Removed an out-dated note near the bottom regarding a distro
we don't support

(From yocto-docs rev: 4211914f16d4ab01182633785068b56a258c0d04)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:14 +01:00
Scott Rifenbark
d2d94d071c ref-manual: Updated the supported distros list.
(From yocto-docs rev: 41a835409a912e55b37a64492ad2fe99fd412214)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:13 +01:00
Scott Rifenbark
0b82198c8d ref-manual: Backed out the bits for the context PNG images.
We did not have time to do this for 1.8.  So, I restored the look
of the glossary pre-images.  I did leave commented code in both
the glossary chapter and the style sheet for later.

(From yocto-docs rev: 9f1472b7d4cd86545e7927b0f693aafc88ae2791)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:13 +01:00
Scott Rifenbark
cf475ab8ea dev-manual, yocto-project-qs: Dropped Python 2.6 as a requirement
Fixes [YOCTO #7535]

Removed this from two places.

(From yocto-docs rev: d169ce99610745e8c1b4b53d898f526e557af665)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:12 +01:00
Scott Rifenbark
4ef59fe419 toaster-manual: Made some updates for virtual environment section.
I moved the note that tells the user they have to initialize the
virtual environment every time before starting Toaster to the
correct location.  I had it misplaced.

(From yocto-docs rev: 65258338e1ffb92ded573ea3b447b424b5f5fa97)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:12 +01:00
Scott Rifenbark
64ccb07092 toaster-manual: Added a new video that shows fido features.
(From yocto-docs rev: a94d6dec039d9b60468c0b26d48b9aa76c300afb)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:11 +01:00
Scott Rifenbark
acf41de1fa ref-manual: Downplayed the BBLAYERS_NON_REMOVABLE variable.
Applied some suggestions from Paul Eggleton to downplay the role
of this variable.  It is basically ignored now in all parts of the
manual set except for the descriptions of the variable itself
and the BBLAYERS variable.  I added some text reinforcing the fact
that BBLAYERS_NON_REMOVABLE is ignored by the build system and only
matters if you are using Hob.

(From yocto-docs rev: 98112751aaec6e25de48d9e3ee56592be3f53a07)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:11 +01:00
Scott Rifenbark
3eabeef5d6 dev-manual: Updates to the devtool section.
Applied review edits from Paul Eggleton.

(From yocto-docs rev: 4815556b6c9f45ce230afede7cb3b2aadf0bef1c)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:10 +01:00
Scott Rifenbark
2f050af982 dev-manual: Updates to the receiptool section.
Applied review comments from Paul Eggleton.

(From yocto-docs rev: 403c9ae5443eaf2a115e2224f07ee19f98c8139d)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:10 +01:00
Scott Rifenbark
dbab9c0ba1 toaster-manual: Created links to Youtube for the GUI vids
I could not get the embedded vids working very well. So we
defaulted to just linking to the Youtube locations directly.

(From yocto-docs rev: 95bef674ec04eec94f568ab00b94f7174d456011)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:09 +01:00
Scott Rifenbark
07fc680a4a toaster-manual: Added note telling user to initialize virtual env
The user must re-initialize the virtual environment (if installed)
prior to starting Toaster each time.

(From yocto-docs rev: b0daa23784f17778f758b0572f90f9293a822812)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:09 +01:00
Scott Rifenbark
8ab5bc3e1e documentation: Updates to try to fix CentOS docs build errors
The docs are not building on CentOS and we think it is due to the
XSL templates being called for the Eclipse parts.  I located all
the "current" templates and switched them out for "1.76.1" version
as are used by the mainstream doc builds.

(From yocto-docs rev: afbddde6524630433dfec973bbe886de32395bc8)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:09 +01:00
Scott Rifenbark
59813630e5 dev-manual: Added footnote crediting Trevor Woerner for devtool addition.
Trevor wrote a nice paper (tutorial) on the use of devtool that I found
to be very helpful in developing the information for this new workflow.
I decided to publicly credit this effort with a small footnote near
the top of the section.

(From yocto-docs rev: 97d234f2d535f85e5a50ac4e7f0c0a79579cd004)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:08 +01:00
Scott Rifenbark
ad7edfbde3 dev-manual: Applied review edits to the devtool section.
Paul Eggleton reviewed the section.

(From yocto-docs rev: 82d9750b4349b3c54f73118ec7d65f0bb96e3f7a)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:08 +01:00
Scott Rifenbark
6fdf368f76 mega-manual: Added two figures to the figures directory.
The figures I added are for the Toaster manual.

(From yocto-docs rev: fb9bb83e48afd2e7d24d68f0c167d8d64f5d25fd)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:07 +01:00
Scott Rifenbark
40db5ea7df mega-manual: Updated the chapter structure for the toaster manual.
Added the reference chapter in so it is included as part of the
mega-manual.

(From yocto-docs rev: 90a6ebabd0657d6dd7381a8c1fc7db5ea8b26a1f)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:07 +01:00
Scott Rifenbark
56a4b1e1d4 Makefile: Added figures to the mega-manual TARFILE list
Added the three Toaster Manual figures to the list of
mega-manual figures so they will be included in the tarball
generated for mega-manual.

(From yocto-docs rev: 2190bc43dfc20c0c0ef5da82c85570f9294e1788)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:06 +01:00
Scott Rifenbark
80f3b20060 Makefile: Added additional PNG files to toaster TARFILE list.
(From yocto-docs rev: b662062cd575f187918f6841983d5682426b266e)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:06 +01:00
Scott Rifenbark
693ba0b14f toaster-manual: Draft of Manual.
Fixes [YOCTO #6901]

(From yocto-docs rev: 258b46b0f3e23045b5fb8c97d03dceb69db5ce20)

Signed-off-by: Scott Rifenbark <scott.m.rifenbark@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-04-01 17:36:05 +01:00
Beth Flanagan
e7b07d33c2 distro_alias.inc: update/sort alias information.
Added new package data, and cleaned up whitespace.

I've also corrected some packaged data (replacement-tar from
my reading of the recipe is the tar normally found in distros).

One issue this patch exposed st I haven't had a chance to track
down is that when you attempt to get distrodata from
gcc-crosssdk-initial-x86_64. The produced .csv in tmp/log
is missing the Distro information. bitbake -e
shows that DISTRO_PN_ALIAS isn't even getting set in this case.

My guess here is that something is happening with the "_"
along the way, I've just not found it yet.

(From meta-yocto rev: 7008eb9ed1e823afe9a36678b91f56046647ba46)

Signed-off-by: Beth Flanagan <elizabeth.flanagan@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:55:01 +01:00
Richard Purdie
aa47ba52f0 bitbake: bin/image-writer: Add ext4 as a deployable image type
This is particularly problematic since qemu images switched to ext4 by
default and now cannot work properly with UIs like hob.

This patch adds in ext4 to the appropriate variable fixing this.

[YOCTO #7426]

(Bitbake rev: 4460e6de04844c4060f1fe87c8a4b247b731c63e)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:39:30 +01:00
Richard Purdie
00b2c3a5e4 bitbake: cooker: Ensure bbappend files are processed in a determistic order
self.appendlist is a dict and as such unordered. This can lead to cases
where appends with different names (e.g. x_%.bbappend vs. x_123.bbappend)
can be reordered in application which in turn reorders the variables
that those bbappend files might touch. Reorderd variables changes the sstate
cache signatures causing real world issues.

To avoid this, use a list for the append files instead.

This patch is conservative and just adds a new data structure alongside
the existing one and uses it to resolve the core issue. Later patches
(post release) can handle some of the wider but less problematic ones
(e.g. issues in bitbake-layers flatten).

[YOCTO #7511]

(Bitbake rev: ba14fb2df8793aae5d671a408c2ba2145a1a7284)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:39:30 +01:00
Richard Purdie
23a0e97d2e image_types: Add missing ext4 support
This is particularly problematic since qemu images switched to ext4 by
default and now cannot work properly with UIs like hob.

This patch adds in ext4 to the appropriate IMAGE* variables fixing this.

[YOCTO #7426]

(From OE-Core rev: 5faa85ed58210ca6fc01ed54a1b370c7aee30b18)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:39:29 +01:00
Alexandru DAMIAN
0fb825c5e5 bitbake: Revert "toaster: machine not searchable in all builds/projects"
This reverts commit 1a86ed8f95649c5f5a3a66984ce36978d93b0e01.

Bug [YOCTO #7334] was incompletly fixed, and the proper fix is
not straightfoward. Consequently we revert the partial fix, as
a incomplete fix is worse than no fix.

(Bitbake rev: 2a8b3b86fe1d5b8797f740c470a4fe5b69146bf4)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:30:18 +01:00
Alexandru DAMIAN
b0cb740fe0 bitbake: toastergui: add ext4 option for IMAGE_FSTYPES
This patch adds "ext4" as a selectable option in IMAGE_FSTYPES,
to keep in sync with the OE-Core capabilities.

(Bitbake rev: 451e85fe8592cab0a07a6866b2853a29cc38f14b)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:30:18 +01:00
Belen Barros Pena
6dd5e472eb bitbake: toasterui: rename 'targets' to 'recipes'
A recent round of informal user feedback has revealed
that the term 'target' is quite problematic. For
all the users we spoke to the word refers to the
target arch. In Toaster, it refers to the software
you build.

This patch replaces the word 'target' with 'recipe'
across the Toaster interface. This is by no means
self-explanatory, but at least it cannot be confused
with target hardware, and it is also consistent with
the terminology we use in the analysis portion of
the interface.

(Bitbake rev: ac10b5d83172feb10f1f3a3c894a54d2c4c4f09d)

Signed-off-by: Belen Barros Pena <belen.barros.pena@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:30:18 +01:00
Alexandru DAMIAN
3ff649953d bitbake: toastergui: prevent error on empty build list
This patch prevents errors being thrown on date limit
computations if the build list is empty.

[YOCTO #7513]

(Bitbake rev: 8068539b6c2913fed66a865b547a653159d8c794)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:30:17 +01:00
Richard Purdie
8db54a9cfa insane: Add baremetal mappings to the QA arch test
Add mappings for i586-elf, x86_64-elf and arm-eabi to binary lookup
table which allows for a variety of baremetal toolchain generation.

(From OE-Core rev: a570052f012298f895fb88be5b0a064bad04024c)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:28:35 +01:00
Richard Purdie
77b1711afb siteinfo: Add x86_64-elf support
Teach siteinfo about x86_64-elf so that baremetal toolchains parse/build.

(From OE-Core rev: 7d57887365d7f819a2cdf8efd5e6f325b6af52d8)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:28:34 +01:00
Paul Eggleton
1e551ec0c3 README.hardware: clarify NFS requirements for edgerouter
You don't need NFS/TFTP for a plain USB setup.

(From meta-yocto rev: 76ea21bdb1448417fb4e2e2f5659c911a30a5026)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:38 +01:00
Belen Barros Pena
e643f3defe toaster: updating toasterconf.json for fido release
We update the toasterconf.json file for the fido release.

A small update to the release help text in the
toasterconf.json file shipped with the meta-yocto layer.

We now make explicit that Toaster will build with the
tip of the selected branch. We also link the
Yocto Project Dizzy release to the git repository,
and not to the release page on the website.

(From meta-yocto rev: d9348157c4bee1789be7f7af9439c5ba287bb139)

Signed-off-by: Belen Barros Pena <belen.barros.pena@linux.intel.com>
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:37 +01:00
Randy Witt
31d301a3f6 populate_sdk_ext: Log the "Preparing build system" step
When using bitbake to do the setscene as part of sdk setup, it would be
useful to have a log in the case where it fails.

The log is called preparing_build_system.log and is in the top level
directory of the extracted sdk.

(From OE-Core rev: cdcfd2211c86880772a65827975ad94d8a5be478)

Signed-off-by: Randy Witt <randy.e.witt@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:37 +01:00
Richard Purdie
b803944ce6 dpkg-native: Avoid 'file changed' errors from tar
Hardlink count duing do_package_write_deb can change causing dpkg-deb
failures. We don't care about this error case so avoid it by checking
the tar exit code.

[YOCTO #7529]

(From OE-Core rev: 77e077a57536c764034f06723edd0749dc578626)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:36 +01:00
Otavio Salvador
64b75d4276 wpa-supplicant: Make SystemD D-Bus config conditional
The SystemD D-Bus configuration should only to be installed when
SystemD support is enabled.

(From OE-Core rev: e658ee16dc026b96f67a4c9666d3eb7bf7027de3)

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:36 +01:00
Chunrong Guo
2ac2706bb7 u-boot.inc: fix rename image error
Resolve mismatch between U-Boot configs and uboot image name.
   The ${S}/${config}/u-boot-${type}.${UBOOT_SUFFIX} may alway be false
   and repeat compile or install so we need to check if ${type} match ${config}

(From OE-Core rev: cc14f461a65b2266caa8acc2c24c0eec02f8e3d7)

Signed-off-by: Chunrong Guo <B40290@freescale.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:35 +01:00
Krishnanjanappa, Jagadeesh
a3360f2cc6 libart-lgpl: add art_config.h for armeb/aarch64be/aarch64be_32
The preprocessor macro values present in art_config.h
differ for individual architectures, basically libart-lgpl recipe will
pick up correct art_config.h file based on

ART_CONFIG = "${HOST_ARCH}/art_config.h"

and thereby having correct preprocessor macros definition
of each architectures.

(From OE-Core rev: a4e705930e3236bdb188192c0959d807587500ff)

Signed-off-by: Krishnanjanappa, Jagadeesh <jagadeesh.krishnanjanappa@caviumnetworks.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:35 +01:00
Patrick Ohly
ef73b474fb combo-layer: fix file_exclude for empty commits
The code detecting empty patches after removing files with
file_exclude failed for commits which were already empty before (like
the initial commit in some repos): such patches are completely empty
files, without a From line.

Detect that case and just let the normal empty patch detection deal
with it.

(From OE-Core rev: 6fd7f40728ebf57dfbc367dedeaf350b8d69784c)

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:34 +01:00
Patrick Ohly
b936350fc2 combo-layer: fix file_exclude for dest_dir = .
"filterdiff -x ./some/file" does not remove changes for some/file.
We must be more careful about constructing the path name and
only add the prefix when it really means a directory.

While at it, also better normalize the path in copy_selected_files()
early on, to handle double slashes. Useful should the function ever
gets used for something other that dest_dir (which gets normalized in
sanity_check()).

(From OE-Core rev: 6c93520b5aaceefecccd83dc77e8ad7681d312c6)

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:34 +01:00
Patrick Ohly
d81ee4d277 combo-layer: clean up dest_dir checking
Empty dest_dir is basically undocumented behavior. The sample conf
only mentions using just a dot for the current directory. In practice,
the empty string does not work because of code like this:

def action_splitpatch(conf, args):
    ...
        if dest_dir != ".":
            filerange_root = '%s -x "%s/*"' % (filerange_root, dest_dir)

However, the empty string was not explicitly checked for, leading to
strange errors when trying to apply patches:

[12:50:23] Applying: foobar: xyz
fatal: unable to stat newly created file '/foobar': No such file or directory

This patch turns the empty string into an alias for the dot. This seems
more user-friendly than throwing an error. This alias is intentionally
not document in the sample conf, because the dot is clearer and works also
with older copies of combo-layer.

Instead of checking for both all the time and normalizing the path when
needed (as done in some places), rewrite the value in sanity_check()
and then only check for '.'.

(From OE-Core rev: a8547b3c2c0b8bf3150043b1b6570f0d44b20335)

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:34 +01:00
Juro Bystricky
232ccf23cf glibc-testing: Specify location of c++ header files
Glibc test suite contains several c++ files. They are built
with g++ -nostdinc. In this case the location of c++ include files
needs to be specified explicitly, or the programs may fail to build.

The header locations are assumed to be:
    sysroot/usr/include/c++/<version>
    sysroot/usr/include/c++/<version>/<machine>

The new code parses "configparms" to get the actual CXX and sysroot
used for the glibc test suite, then it queries CXX to determine
CXX <version> and CXX <machine>. With the known values for <version>
and <machine> the code composes a new value for c++-sysincludes
and appends "configparms" with that value.

[YOCTO #7081]

(From OE-Core rev: 15c5e5e83af409509140eaf29d4e10d9db99eb8a)

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:33 +01:00
Juro Bystricky
a7e20761bd oe-git-proxy: Redirect error messages to STDERR
oe-git-proxy script needs socat. If socat is not found,
an error message is issued on STDOUT. This leads to a misleading
git message:

fatal: protocol error: bad line length character: ERRO

instead of the intended message:

ERROR: socat binary not in PATH

Redirecting the error message to STDERR fixes this issue.

(From OE-Core rev: d611d7009631aa8a372f248995b52938163966c6)

Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:33 +01:00
Richard Purdie
bc090aa673 autotools: Avoid find race for S = "${WORKDIR}"
For recipes with PACKAGES_remove = "${PN}", the find which removes .la files
can race against deletion of other directories in WORKDIR e.g.:

find: '/home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/sstate-build-populate_lic': No such file or directory
| WARNING: /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7/temp/run.do_configure.6558:1 exit 1 from
|   find /home/autobuilder/yocto-autobuilder/yocto-worker/nightly-oe-selftest/build/build/tmp/work/qemux86_64-poky-linux/init-ifupdown/1.0-r7 -name \*.la -delete

The simplest fix is to add the find option which ignores these kind of races.

[YOCTO #7522]

(From OE-Core rev: 7dd17effffc00cd6e58ba6a004b811c8452254d7)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:32 +01:00
Richard Purdie
6891ae6425 gcc: Tweak arm multilib endian patch for baremetal
In a baremetal build, TARGET_ENDIAN_OPTION isn't set leading to build
failures. Add in ifdefs to avoid this.

(From OE-Core rev: 5325c763a66b252c976ece3a08e5fc916fd6c416)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:32 +01:00
Ross Burton
a842038bca kernel-yocto: merge duplicate kernel_configme task definitions
The kernel_configme task was added twice (once in the .bbclass, one in a .inc)
with different ordering constraints.

Change this to be just one definition in the bbclass with the stronger ordering
constraints.

(From OE-Core rev: 0830078cd1d6a365543877bf8eda93c3fff71b0d)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:32 +01:00
Ross Burton
7c0846cc5b linux-yocto: add kern-tools-native to kernel_metadata depends
The autobuilder failed like this:

  temp/run.do_kernel_metadata.25242: line 165: createme: command not found

createme is provided by kern-tools-native.  do_patch has a dependency on
kern-tools-native, but do_kernel_metadata runs before do_patch.  So move the
dependency from do_patch to do_kernel_metadata, moving the statement from the
.inc to the class so it's alongside the task definition.

[ YOCTO #7531 ]

(From OE-Core rev: 938d0288adc2ace3c66dab5904ad958a4c7615cc)

Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:31 +01:00
Belen Barros Pena
47686dc42f toaster: update toasterconf.json for fido release
We update the toasterconf.json for the 1.8 "fido"
release.

A small update to the release help text in the
toasterconf.json file shipped with the
openembedded-core layer.

We now make explicit that Toaster will build with
the tip of the selected branch, and we add links
to the OpenEmbedded repository.

(From OE-Core rev: 6ab371da72ce119c1b32ec7428aec1250e7aaf15)

Signed-off-by: Belen Barros Pena <belen.barros.pena@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:31 +01:00
Alexandru DAMIAN
938fa5cebf toaster.bbclass: do not add symbolic links to artifacts
This patch removes the symbolic links from the artifact list.

[YOCTO #7184]

(From OE-Core rev: 1243b616e2b375061fafb6b504df7106a808f7d2)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:30 +01:00
Robert Yang
18661937e4 cpio: fix CVE-2015-1197
Additional directory traversal vulnerability via symlinks
cpio CVE-2015-1197

Initial report:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=774669
Upstream report:
https://lists.gnu.org/archive/html/bug-cpio/2015-01/msg00000.html

And fix the indent in SRC_URI.

[YOCTO #7182]

(From OE-Core rev: 87d8c11e7504210e377cb6201e672d32048e000c)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:30 +01:00
Robert Yang
c1d31cf2c7 patch: fix CVE-2015-1196
A directory traversal flaw was reported in patch:

References:
http://www.openwall.com/lists/oss-security/2015/01/18/6
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775227
https://bugzilla.redhat.com/show_bug.cgi?id=1182154

[YOCTO #7182]

(From OE-Core rev: bf986b527038821b49c81c4b9abc10e2dff32c38)

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-31 22:24:29 +01:00
Richard Purdie
8b3d3e7c95 build-appliance-image: Update to fido head revision
(From OE-Core rev: da6a62eac903e66174e32d749d1c463fc3e78b78)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-25 13:14:35 +00:00
Richard Purdie
fe5b98019d poky: Add 1.8 to sanity tested distro list
(From meta-yocto rev: 44f0d5fc79be64d18c8bb84326606c16621806d4)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-25 13:13:13 +00:00
Richard Purdie
184e00a36b build-appliance-image: Update to fido head revision
(From OE-Core rev: d343fbcad91d1f1379facec80b380b4ee75138cf)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-25 13:01:19 +00:00
Beth Flanagan
8f1decb32b poky.conf: Flip DISTRO_VERSION for pending 1.8 release
Flipping DISTRO_VERSION for fido.

(From meta-yocto rev: 5d025acb4a37f74c17562bba3f1a35e0852c883f)

Signed-off-by: Beth Flanagan <elizabeth.flanagan@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-25 12:55:37 +00:00
Richard Purdie
36ac2c6dfd bitbake: Update to version 1.26.0
(Bitbake rev: 71316d2239a42f9914e64f26fa9141dfe3232354)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2015-03-25 12:55:37 +00:00
6478 changed files with 376087 additions and 344649 deletions

16
.gitignore vendored
View File

@@ -1,7 +1,7 @@
*.pyc
*.pyo
/*.patch
/build*/
build*/
pyshtables.py
pstage/
scripts/oe-git-proxy-socks
@@ -14,18 +14,10 @@ hob-image-*.bb
*.orig
*.rej
*~
!meta-poky
!meta-yocto
!meta-yocto-bsp
!meta-yocto-imported
/documentation/*/eclipse/
/documentation/*/*.html
/documentation/*/*.pdf
/documentation/*/*.tgz
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.html
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.pdf
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.tgz
documentation/user-manual/user-manual.html
documentation/user-manual/user-manual.pdf
documentation/user-manual/user-manual.tgz
pull-*/
bitbake/lib/toaster/contrib/tts/backlog.txt
bitbake/lib/toaster/contrib/tts/log/*
bitbake/lib/toaster/contrib/tts/.cache/*

View File

@@ -1,2 +1,2 @@
# Template settings
TEMPLATECONF=${TEMPLATECONF:-meta-poky/conf}
TEMPLATECONF=${TEMPLATECONF:-meta-yocto/conf}

58
README Normal file
View File

@@ -0,0 +1,58 @@
Poky
====
Poky is an integration of various components to form a complete prepackaged
build system and development environment. It features support for building
customised embedded device style images. There are reference demo images
featuring a X11/Matchbox/GTK themed UI called Sato. The system supports
cross-architecture application development using QEMU emulation and a
standalone toolchain and SDK with IDE integration.
Additional information on the specifics of hardware that Poky supports
is available in README.hardware. Further hardware support can easily be added
in the form of layers which extend the systems capabilities in a modular way.
As an integration layer Poky consists of several upstream projects such as
BitBake, OpenEmbedded-Core, Yocto documentation and various sources of information
e.g. for the hardware support. Poky is in turn a component of the Yocto Project.
The Yocto Project has extensive documentation about the system including a
reference manual which can be found at:
http://yoctoproject.org/documentation
OpenEmbedded-Core is a layer containing the core metadata for current versions
of OpenEmbedded. It is distro-less (can build a functional image with
DISTRO = "nodistro") and contains only emulated machine support.
For information about OpenEmbedded, see the OpenEmbedded website:
http://www.openembedded.org/
Where to Send Patches
=====================
As Poky is an integration repository (built using a tool called combo-layer),
patches against the various components should be sent to their respective
upstreams:
bitbake:
Git repository: http://git.openembedded.org/bitbake/
Mailing list: bitbake-devel@lists.openembedded.org
documentation:
Git repository: http://git.yoctoproject.org/cgit/cgit.cgi/yocto-docs/
Mailing list: yocto@yoctoproject.org
meta-yocto(-bsp):
Git repository: http://git.yoctoproject.org/cgit/cgit.cgi/meta-yocto(-bsp)
Mailing list: poky@yoctoproject.org
Everything else should be sent to the OpenEmbedded Core mailing list. If in
doubt, check the oe-core git repository for the content you intend to modify.
Before sending, be sure the patches apply cleanly to the current oe-core git
repository.
Git repository: http://git.openembedded.org/openembedded-core/
Mailing list: openembedded-core@lists.openembedded.org
Note: The scripts directory should be treated with extra care as it is a mix of
oe-core and poky-specific files.

View File

@@ -1,26 +0,0 @@
OE-Core aims to be able to provide basic LSB compatible images. There
are some challenges for OE as LSB isn't always 100% relevant to its
target embedded and IoT audiences.
One challenge is that the LSB spec is no longer being actively
developed [https://github.com/LinuxStandardBase/lsb] and has
components which are end of life or significantly dated. OE
therefore provides compatibility with the following caveats:
* Qt4 is provided by the separate meta-qt4 layer. Its noted that Qt4
is end of life and this isn't something the core project regularly
tests any longer. Users are recommended to group together to support
maintenance of that layer. [http://git.yoctoproject.org/cgit/cgit.cgi/meta-qt4/]
* mailx has been dropped since its no longer being developed upstream
and there are better, more modern replacements such as s-nail
(http://sdaoden.eu/code.html) or mailutils (http://mailutils.org/).
* A few perl modules that were required by LSB 4.x aren't provided:
libclass-isa, libenv, libdumpvalue, libfile-checktree,
libi18n-collate, libpod-plainer.
* libpng 1.2 isn't provided; oe-core includes the latest release of libpng
instead.
* pax (POSIX standard archive) tool is not provided.

View File

@@ -1 +0,0 @@
meta-yocto-bsp/README.hardware

502
README.hardware Normal file
View File

@@ -0,0 +1,502 @@
Poky Hardware README
====================
This file gives details about using Poky with the reference machines
supported out of the box. A full list of supported reference target machines
can be found by looking in the following directories:
meta/conf/machine/
meta-yocto-bsp/conf/machine/
If you are in doubt about using Poky/OpenEmbedded with your hardware, consult
the documentation for your board/device.
Support for additional devices is normally added by creating BSP layers - for
more information please see the Yocto Board Support Package (BSP) Developer's
Guide - documentation source is in documentation/bspguide or download the PDF
from:
http://yoctoproject.org/documentation
Support for physical reference hardware has now been split out into a
meta-yocto-bsp layer which can be removed separately from other layers if not
needed.
QEMU Emulation Targets
======================
To simplify development, the build system supports building images to
work with the QEMU emulator in system emulation mode. Several architectures
are currently supported:
* ARM (qemuarm)
* x86 (qemux86)
* x86-64 (qemux86-64)
* PowerPC (qemuppc)
* MIPS (qemumips)
Use of the QEMU images is covered in the Yocto Project Reference Manual.
The appropriate MACHINE variable value corresponding to the target is given
in brackets.
Hardware Reference Boards
=========================
The following boards are supported by the meta-yocto-bsp layer:
* Texas Instruments Beaglebone (beaglebone)
* Freescale MPC8315E-RDB (mpc8315e-rdb)
For more information see the board's section below. The appropriate MACHINE
variable value corresponding to the board is given in brackets.
Reference Board Maintenance
===========================
Send pull requests, patches, comments or questions about meta-yocto-bsps to poky@yoctoproject.org
Maintainers: Kevin Hao <kexin.hao@windriver.com>
Bruce Ashfield <bruce.ashfield@windriver.com>
Consumer Devices
================
The following consumer devices are supported by the meta-yocto-bsp layer:
* Intel x86 based PCs and devices (genericx86)
* Ubiquiti Networks EdgeRouter Lite (edgerouter)
For more information see the device's section below. The appropriate MACHINE
variable value corresponding to the device is given in brackets.
Specific Hardware Documentation
===============================
Intel x86 based PCs and devices (genericx86)
==========================================
The genericx86 MACHINE is tested on the following platforms:
Intel Xeon/Core i-Series:
+ Intel Romley Server: Sandy Bridge Xeon processor, C600 PCH (Patsburg), (Canoe Pass CRB)
+ Intel Romley Server: Ivy Bridge Xeon processor, C600 PCH (Patsburg), (Intel SDP S2R3)
+ Intel Crystal Forest Server: Sandy Bridge Xeon processor, DH89xx PCH (Cave Creek), (Stargo CRB)
+ Intel Chief River Mobile: Ivy Bridge Mobile processor, QM77 PCH (Panther Point-M), (Emerald Lake II CRB, Sabino Canyon CRB)
+ Intel Huron River Mobile: Sandy Bridge processor, QM67 PCH (Cougar Point), (Emerald Lake CRB, EVOC EC7-1817LNAR board)
+ Intel Calpella Platform: Core i7 processor, QM57 PCH (Ibex Peak-M), (Red Fort CRB, Emerson MATXM CORE-411-B)
+ Intel Nehalem/Westmere-EP Server: Xeon 56xx/55xx processors, 5520 chipset, ICH10R IOH (82801), (Hanlan Creek CRB)
+ Intel Nehalem Workstation: Xeon 56xx/55xx processors, System SC5650SCWS (Greencity CRB)
+ Intel Picket Post Server: Xeon 56xx/55xx processors (Jasper Forest), 3420 chipset (Ibex Peak), (Osage CRB)
+ Intel Storage Platform: Sandy Bridge Xeon processor, C600 PCH (Patsburg), (Oak Creek Canyon CRB)
+ Intel Shark Bay Client Platform: Haswell processor, LynxPoint PCH, (Walnut Canyon CRB, Lava Canyon CRB, Basking Ridge CRB, Flathead Creek CRB)
+ Intel Shark Bay Ultrabook Platform: Haswell ULT processor, Lynx Point-LP PCH, (WhiteTip Mountain 1 CRB)
Intel Atom platforms:
+ Intel embedded Menlow: Intel Atom Z510/530 CPU, System Controller Hub US15W (Portwell NANO-8044)
+ Intel Luna Pier: Intel Atom N4xx/D5xx series CPU (aka: Pineview-D & -M), 82801HM I/O Hub (ICH8M), (Advantech AIMB-212, Moon Creek CRB)
+ Intel Queens Bay platform: Intel Atom E6xx CPU (aka: Tunnel Creek), Topcliff EG20T I/O Hub (Emerson NITX-315, Crown Bay CRB, Minnow Board)
+ Intel Fish River Island platform: Intel Atom E6xx CPU (aka: Tunnel Creek), Topcliff EG20T I/O Hub (Kontron KM2M806)
+ Intel Cedar Trail platform: Intel Atom N2000 & D2000 series CPU (aka: Cedarview), NM10 Express Chipset (Norco kit BIS-6630, Cedar Rock CRB)
and is likely to work on many unlisted Atom/Core/Xeon based devices. The MACHINE
type supports ethernet, wifi, sound, and Intel/vesa graphics by default in
addition to common PC input devices, busses, and so on. Note that it does not
included the binary-only graphic drivers used on some Atom platforms, for
accelerated graphics on these machines please refer to meta-intel.
Depending on the device, it can boot from a traditional hard-disk, a USB device,
or over the network. Writing generated images to physical media is
straightforward with a caveat for USB devices. The following examples assume the
target boot device is /dev/sdb, be sure to verify this and use the correct
device as the following commands are run as root and are not reversable.
USB Device:
1. Build a live image. This image type consists of a simple filesystem
without a partition table, which is suitable for USB keys, and with the
default setup for the genericx86 machine, this image type is built
automatically for any image you build. For example:
$ bitbake core-image-minimal
2. Use the "dd" utility to write the image to the raw block device. For
example:
# dd if=core-image-minimal-genericx86.hddimg of=/dev/sdb
If the device fails to boot with "Boot error" displayed, or apparently
stops just after the SYSLINUX version banner, it is likely the BIOS cannot
understand the physical layout of the disk (or rather it expects a
particular layout and cannot handle anything else). There are two possible
solutions to this problem:
1. Change the BIOS USB Device setting to HDD mode. The label will vary by
device, but the idea is to force BIOS to read the Cylinder/Head/Sector
geometry from the device.
2. Without such an option, the BIOS generally boots the device in USB-ZIP
mode. To write an image to a USB device that will be bootable in
USB-ZIP mode, carry out the following actions:
a. Determine the geometry of your USB device using fdisk:
# fdisk /dev/sdb
Command (m for help): p
Disk /dev/sdb: 4011 MB, 4011491328 bytes
124 heads, 62 sectors/track, 1019 cylinders, total 7834944 sectors
...
Command (m for help): q
b. Configure the USB device for USB-ZIP mode:
# mkdiskimage -4 /dev/sdb 1019 124 62
Where 1019, 124 and 62 are the cylinder, head and sectors/track counts
as reported by fdisk (substitute the values reported for your device).
When the operation has finished and the access LED (if any) on the
device stops flashing, remove and reinsert the device to allow the
kernel to detect the new partition layout.
c. Copy the contents of the image to the USB-ZIP mode device:
# mkdir /tmp/image
# mkdir /tmp/usbkey
# mount -o loop core-image-minimal-genericx86.hddimg /tmp/image
# mount /dev/sdb4 /tmp/usbkey
# cp -rf /tmp/image/* /tmp/usbkey
d. Install the syslinux boot loader:
# syslinux /dev/sdb4
e. Unmount everything:
# umount /tmp/image
# umount /tmp/usbkey
Install the boot device in the target board and configure the BIOS to boot
from it.
For more details on the USB-ZIP scenario, see the syslinux documentation:
http://git.kernel.org/?p=boot/syslinux/syslinux.git;a=blob_plain;f=doc/usbkey.txt;hb=HEAD
Texas Instruments Beaglebone (beaglebone)
=========================================
The Beaglebone is an ARM Cortex-A8 development board with USB, Ethernet, 2D/3D
accelerated graphics, audio, serial, JTAG, and SD/MMC. The Black adds a faster
CPU, more RAM, eMMC flash and a micro HDMI port. The beaglebone MACHINE is
tested on the following platforms:
o Beaglebone Black A6
o Beaglebone A6 (the original "White" model)
The Beaglebone Black has eMMC, while the White does not. Pressing the USER/BOOT
button when powering on will temporarily change the boot order. But for the sake
of simplicity, these instructions assume you have erased the eMMC on the Black,
so its boot behavior matches that of the White and boots off of SD card. To do
this, issue the following commands from the u-boot prompt:
# mmc dev 1
# mmc erase 0 512
To further tailor these instructions for your board, please refer to the
documentation at http://www.beagleboard.org/bone and http://www.beagleboard.org/black
From a Linux system with access to the image files perform the following steps
as root, replacing mmcblk0* with the SD card device on your machine (such as sdc
if used via a usb card reader):
1. Partition and format an SD card:
# fdisk -lu /dev/mmcblk0
Disk /dev/mmcblk0: 3951 MB, 3951034368 bytes
255 heads, 63 sectors/track, 480 cylinders, total 7716864 sectors
Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 * 63 144584 72261 c Win95 FAT32 (LBA)
/dev/mmcblk0p2 144585 465884 160650 83 Linux
# mkfs.vfat -F 16 -n "boot" /dev/mmcblk0p1
# mke2fs -j -L "root" /dev/mmcblk0p2
The following assumes the SD card partitions 1 and 2 are mounted at
/media/boot and /media/root respectively. Removing the card and reinserting
it will do just that on most modern Linux desktop environments.
The files referenced below are made available after the build in
build/tmp/deploy/images.
2. Install the boot loaders
# cp MLO-beaglebone /media/boot/MLO
# cp u-boot-beaglebone.img /media/boot/u-boot.img
3. Install the root filesystem
# tar x -C /media/root -f core-image-$IMAGE_TYPE-beaglebone.tar.bz2
4. If using core-image-base or core-image-sato images, the SD card is ready
and rootfs already contains the kernel, modules and device tree (DTB)
files necessary to be booted with U-boot's default configuration, so
skip directly to step 8.
For core-image-minimal, proceed through next steps.
5. If using core-image-minimal rootfs, install the modules
# tar x -C /media/root -f modules-beaglebone.tgz
6. If using core-image-minimal rootfs, install the kernel zImage into /boot
directory of rootfs
# cp zImage-beaglebone.bin /media/root/boot/zImage
7. If using core-image-minimal rootfs, also install device tree (DTB) files
into /boot directory of rootfs
# cp zImage-am335x-bone.dtb /media/root/boot/am335x-bone.dtb
# cp zImage-am335x-boneblack.dtb /media/root/boot/am335x-boneblack.dtb
8. Unmount the SD partitions, insert the SD card into the Beaglebone, and
boot the Beaglebone
Freescale MPC8315E-RDB (mpc8315e-rdb)
=====================================
The MPC8315 PowerPC reference platform (MPC8315E-RDB) is aimed at hardware and
software development of network attached storage (NAS) and digital media server
applications. The MPC8315E-RDB features the PowerQUICC II Pro processor, which
includes a built-in security accelerator.
(Note: you may find it easier to order MPC8315E-RDBA; this appears to be the
same board in an enclosure with accessories. In any case it is fully
compatible with the instructions given here.)
Setup instructions
------------------
You will need the following:
* NFS root setup on your workstation
* TFTP server installed on your workstation
* Straight-thru 9-conductor serial cable (DB9, M/F) connected from your
PC to UART1
* Ethernet connected to the first ethernet port on the board
--- Preparation ---
Note: if you have altered your board's ethernet MAC address(es) from the
defaults, or you need to do so because you want multiple boards on the same
network, then you will need to change the values in the dts file (patch
linux/arch/powerpc/boot/dts/mpc8315erdb.dts within the kernel source). If
you have left them at the factory default then you shouldn't need to do
anything here.
--- Booting from NFS root ---
Load the kernel and dtb (device tree blob), and boot the system as follows:
1. Get the kernel (uImage-mpc8315e-rdb.bin) and dtb (uImage-mpc8315e-rdb.dtb)
files from the tmp/deploy directory, and make them available on your TFTP
server.
2. Connect the board's first serial port to your workstation and then start up
your favourite serial terminal so that you will be able to interact with
the serial console. If you don't have a favourite, picocom is suggested:
$ picocom /dev/ttyUSB0 -b 115200
3. Power up or reset the board and press a key on the terminal when prompted
to get to the U-Boot command line
4. Set up the environment in U-Boot:
=> setenv ipaddr <board ip>
=> setenv serverip <tftp server ip>
=> setenv bootargs root=/dev/nfs rw nfsroot=<nfsroot ip>:<rootfs path> ip=<board ip>:<server ip>:<gateway ip>:255.255.255.0:mpc8315e:eth0:off console=ttyS0,115200
5. Download the kernel and dtb, and boot:
=> tftp 1000000 uImage-mpc8315e-rdb.bin
=> tftp 2000000 uImage-mpc8315e-rdb.dtb
=> bootm 1000000 - 2000000
--- Booting from JFFS2 root ---
1. First boot the board with NFS root.
2. Erase the MTD partition which will be used as root:
$ flash_eraseall /dev/mtd3
3. Copy the JFFS2 image to the MTD partition:
$ flashcp core-image-minimal-mpc8315e-rdb.jffs2 /dev/mtd3
4. Then reboot the board and set up the environment in U-Boot:
=> setenv bootargs root=/dev/mtdblock3 rootfstype=jffs2 console=ttyS0,115200
Ubiquiti Networks EdgeRouter Lite (edgerouter)
==============================================
The EdgeRouter Lite is part of the EdgeMax series. It is a MIPS64 router
(based on the Cavium Octeon processor) with 512MB of RAM, which uses an
internal USB pendrive for storage.
Setup instructions
------------------
You will need the following:
* RJ45 -> serial ("rollover") cable connected from your PC to the CONSOLE
port on the device
* Ethernet connected to the first ethernet port on the board
If using NFS as part of the setup process, you will also need:
* NFS root setup on your workstation
* TFTP server installed on your workstation (if fetching the kernel from
TFTP, see below).
--- Preparation ---
Build an image (e.g. core-image-minimal) using "edgerouter" as the MACHINE.
In the following instruction it is based on core-image-minimal. Another target
may be similiar with it.
--- Booting from NFS root / kernel via TFTP ---
Load the kernel, and boot the system as follows:
1. Get the kernel (vmlinux) file from the tmp/deploy/images/edgerouter
directory, and make them available on your TFTP server.
2. Connect the board's first serial port to your workstation and then start up
your favourite serial terminal so that you will be able to interact with
the serial console. If you don't have a favourite, picocom is suggested:
$ picocom /dev/ttyS0 -b 115200
3. Power up or reset the board and press a key on the terminal when prompted
to get to the U-Boot command line
4. Set up the environment in U-Boot:
=> setenv ipaddr <board ip>
=> setenv serverip <tftp server ip>
5. Download the kernel and boot:
=> tftp tftp $loadaddr vmlinux
=> bootoctlinux $loadaddr coremask=0x3 root=/dev/nfs rw nfsroot=<nfsroot ip>:<rootfs path> ip=<board ip>:<server ip>:<gateway ip>:<netmask>:edgerouter:eth0:off mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom)
--- Booting from USB root ---
To boot from the USB disk, you either need to remove it from the edgerouter
box and populate it from another computer, or use a previously booted NFS
image and populate from the edgerouter itself.
Type 1: Mounted USB disk
------------------------
To boot from the USB disk there are two available partitions on the factory
USB storage. The rest of this guide assumes that these partitions are left
intact. If you change the partition scheme, you must update your boot method
appropriately.
The standard partitions are:
- 1: vfat partition containing factory kernels
- 2: ext3 partition for the root filesystem.
You can place the kernel on either partition 1, or partition 2, but the roofs
must go on partition 2 (due to its size).
Note: If you place the kernel on the ext3 partition, you must re-create the
ext3 filesystem, since the factory u-boot can only handle 128 byte inodes and
cannot read the partition otherwise.
Steps:
1. Remove the USB disk from the edgerouter and insert it into a computer
that has access to your build artifacts.
2. Copy the kernel image to the USB storage (assuming discovered as 'sdb' on
the development machine):
2a) if booting from vfat
# mount /dev/sdb1 /mnt
# cp tmp/deploy/images/edgerouter/vmlinux /mnt
# umount /mnt
2b) if booting from ext3
# mkfs.ext3 -I 128 /dev/sdb2
# mount /dev/sdb2 /mnt
# mkdir /mnt/boot
# cp tmp/deploy/images/edgerouter/vmlinux /mnt/boot
# umount /mnt
3. Extract the rootfs to the USB storage ext3 partition
# mount /dev/sdb2 /mnt
# tar -xvjpf core-image-minimal-XXX.tar.bz2 -C /mnt
# umount /mnt
4. Reboot the board and press a key on the terminal when prompted to get to the U-Boot
command line:
5. Load the kernel and boot:
5a) vfat boot
=> fatload usb 0:1 $loadaddr vmlinux
5b) ext3 boot
=> ext2load usb 0:2 $loadaddr boot/vmlinux
=> bootoctlinux $loadaddr coremask=0x3 root=/dev/sda2 rw rootwait mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom)
Type 2: NFS
-----------
Note: If you place the kernel on the ext3 partition, you must re-create the
ext3 filesystem, since the factory u-boot can only handle 128 byte inodes and
cannot read the partition otherwise.
These boot instructions assume that you have recreated the ext3 filesystem with
128 byte inodes, you have an updated uboot or you are running and image capable
of making the filesystem on the board itself.
1. Boot from NFS root
2. Mount the USB disk partition 2 and then extract the contents of
tmp/deploy/core-image-XXXX.tar.bz2 into it.
Before starting, copy core-image-minimal-xxx.tar.bz2 and vmlinux into
rootfs path on your workstation.
and then,
# mount /dev/sda2 /media/sda2
# tar -xvjpf core-image-minimal-XXX.tar.bz2 -C /media/sda2
# cp vmlinux /media/sda2/boot/vmlinux
# umount /media/sda2
# reboot
3. Reboot the board and press a key on the terminal when prompted to get to the U-Boot
command line:
# reboot
4. Load the kernel and boot:
=> ext2load usb 0:2 $loadaddr boot/vmlinux
=> bootoctlinux $loadaddr coremask=0x3 root=/dev/sda2 rw rootwait mtdparts=phys_mapped_flash:512k(boot0),512k(boot1),64k@3072k(eeprom)

View File

@@ -1 +0,0 @@
meta-poky/README.poky

View File

@@ -1,15 +0,0 @@
QEMU Emulation Targets
======================
To simplify development, the build system supports building images to
work with the QEMU emulator in system emulation mode. Several architectures
are currently supported in 32 and 64 bit variants:
* ARM (qemuarm + qemuarm64)
* x86 (qemux86 + qemux86-64)
* PowerPC (qemuppc only)
* MIPS (qemumips + qemumips64)
Use of the QEMU images is covered in the Yocto Project Reference Manual.
The appropriate MACHINE variable value corresponding to the target is given
in brackets.

View File

@@ -5,15 +5,6 @@ The following external components are distributed with this software:
* The Toaster Simple UI application is based upon the Django project template, the files of which are covered by the BSD license and are copyright (c) Django Software
Foundation and individual contributors.
* Twitter Bootstrap (including Glyphicons), redistributed under the MIT license
* Twitter Bootstrap (including Glyphicons), redistributed under the Apache License 2.0.
* jQuery is redistributed under the MIT license.
* Twitter typeahead.js redistributed under the MIT license. Note that the JS source has one small modification, so the full unminified file is currently included to make it obvious where this is.
* jsrender is redistributed under the MIT license.
* QUnit is redistributed under the MIT license.
* Font Awesome fonts redistributed under the SIL Open Font License 1.1
* simplediff is distributed under the zlib license.

View File

@@ -1,35 +0,0 @@
Bitbake
=======
BitBake is a generic task execution engine that allows shell and Python tasks to be run
efficiently and in parallel while working within complex inter-task dependency constraints.
One of BitBake's main users, OpenEmbedded, takes this core and builds embedded Linux software
stacks using a task-oriented approach.
For information about Bitbake, see the OpenEmbedded website:
http://www.openembedded.org/
Bitbake plain documentation can be found under the doc directory or its integrated
html version at the Yocto Project website:
http://yoctoproject.org/documentation
Contributing
------------
Please refer to
http://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded
for guidelines on how to submit patches, just note that the latter documentation is intended
for OpenEmbedded (and its core) not bitbake patches (bitbake-devel@lists.openembedded.org)
but in general main guidelines apply. Once the commit(s) have been created, the way to send
the patch is through git-send-email. For example, to send the last commit (HEAD) on current
branch, type:
git send-email -M -1 --to bitbake-devel@lists.openembedded.org
Mailing list:
http://lists.openembedded.org/mailman/listinfo/bitbake-devel
Source code:
http://git.openembedded.org/bitbake/

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
@@ -33,24 +33,17 @@ except RuntimeError as exc:
sys.exit(str(exc))
from bb import cookerdata
from bb.main import bitbake_main, BitBakeConfigParameters, BBMainException
if sys.getfilesystemencoding() != "utf-8":
sys.exit("Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).\nPython can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.")
__version__ = "1.38.0"
from bb.main import bitbake_main, BitBakeConfigParameters
if __name__ == "__main__":
if __version__ != bb.__version__:
sys.exit("Bitbake core version and program version mismatch!")
try:
sys.exit(bitbake_main(BitBakeConfigParameters(sys.argv),
cookerdata.CookerConfiguration()))
except BBMainException as err:
sys.exit(err)
ret = bitbake_main(BitBakeConfigParameters(sys.argv),
cookerdata.CookerConfiguration())
except bb.BBHandledException:
sys.exit(1)
ret = 1
except Exception:
ret = 1
import traceback
traceback.print_exc()
sys.exit(1)
sys.exit(ret)

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# bitbake-diffsigs / bitbake-dumpsig
# BitBake task signature data dump and comparison utility
# bitbake-diffsigs
# BitBake task signature data comparison utility
#
# Copyright (C) 2012-2013, 2017 Intel Corporation
# Copyright (C) 2012-2013 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -21,188 +21,118 @@
import os
import sys
import warnings
import argparse
import fnmatch
import optparse
import logging
import pickle
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
import bb.tinfoil
import bb.siggen
import bb.msg
myname = os.path.basename(sys.argv[0])
logger = bb.msg.logger_create(myname)
def logger_create(name, output=sys.stderr):
logger = logging.getLogger(name)
console = logging.StreamHandler(output)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
if output.isatty():
format.enable_color()
console.setFormatter(format)
logger.addHandler(console)
logger.setLevel(logging.INFO)
return logger
is_dump = myname == 'bitbake-dumpsig'
logger = logger_create('bitbake-diffsigs')
def find_siginfo(tinfoil, pn, taskname, sigs=None):
result = None
tinfoil.set_event_mask(['bb.event.FindSigInfoResult',
'logging.LogRecord',
'bb.command.CommandCompleted',
'bb.command.CommandFailed'])
ret = tinfoil.run_command('findSigInfo', pn, taskname, sigs)
if ret:
while True:
event = tinfoil.wait_event(1)
if event:
if isinstance(event, bb.command.CommandCompleted):
break
elif isinstance(event, bb.command.CommandFailed):
logger.error(str(event))
sys.exit(2)
elif isinstance(event, bb.event.FindSigInfoResult):
result = event.result
elif isinstance(event, logging.LogRecord):
logger.handle(event)
else:
logger.error('No result returned from findSigInfo command')
sys.exit(2)
return result
def find_compare_task(bbhandler, pn, taskname):
""" Find the most recent signature files for the specified PN/task and compare them """
def find_siginfo_task(bbhandler, pn, taskname, sig1=None, sig2=None):
""" Find the most recent signature files for the specified PN/task """
def get_hashval(siginfo):
if siginfo.endswith('.siginfo'):
return siginfo.rpartition(':')[2].partition('_')[0]
else:
return siginfo.rpartition('.')[2]
if not hasattr(bb.siggen, 'find_siginfo'):
logger.error('Metadata does not support finding signature data files')
sys.exit(1)
if not taskname.startswith('do_'):
taskname = 'do_%s' % taskname
if sig1 and sig2:
sigfiles = find_siginfo(bbhandler, pn, taskname, [sig1, sig2])
if len(sigfiles) == 0:
logger.error('No sigdata files found matching %s %s matching either %s or %s' % (pn, taskname, sig1, sig2))
sys.exit(1)
elif not sig1 in sigfiles:
logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig1))
sys.exit(1)
elif not sig2 in sigfiles:
logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig2))
sys.exit(1)
latestfiles = [sigfiles[sig1], sigfiles[sig2]]
filedates = bb.siggen.find_siginfo(pn, taskname, None, bbhandler.config_data)
latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-3:]
if not latestfiles:
logger.error('No sigdata files found matching %s %s' % (pn, taskname))
sys.exit(1)
elif len(latestfiles) < 2:
logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (pn, taskname))
sys.exit(1)
else:
filedates = find_siginfo(bbhandler, pn, taskname)
latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:]
if not latestfiles:
logger.error('No sigdata files found matching %s %s' % (pn, taskname))
sys.exit(1)
# It's possible that latestfiles contain 3 elements and the first two have the same hash value.
# In this case, we delete the second element.
# The above case is actually the most common one. Because we may have sigdata file and siginfo
# file having the same hash value. Comparing such two files makes no sense.
if len(latestfiles) == 3:
hash0 = get_hashval(latestfiles[0])
hash1 = get_hashval(latestfiles[1])
if hash0 == hash1:
latestfiles.pop(1)
return latestfiles
# Define recursion callback
def recursecb(key, hash1, hash2):
hashes = [hash1, hash2]
hashfiles = bb.siggen.find_siginfo(key, None, hashes, bbhandler.config_data)
recout = []
if len(hashfiles) == 2:
out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb)
recout.extend(list(' ' + l for l in out2))
else:
recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
return recout
# Recurse into signature comparison
output = bb.siggen.compare_sigfiles(latestfiles[0], latestfiles[1], recursecb)
if output:
print '\n'.join(output)
sys.exit(0)
# Define recursion callback
def recursecb(key, hash1, hash2):
hashes = [hash1, hash2]
hashfiles = find_siginfo(tinfoil, key, None, hashes)
recout = []
if len(hashfiles) == 0:
recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
elif not hash1 in hashfiles:
recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash1))
elif not hash2 in hashfiles:
recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash2))
else:
out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color)
for change in out2:
for line in change.splitlines():
recout.append(' ' + line)
parser = optparse.OptionParser(
description = "Compares siginfo/sigdata files written out by BitBake",
usage = """
%prog -t recipename taskname
%prog sigdatafile1 sigdatafile2
%prog sigdatafile1""")
return recout
parser.add_option("-t", "--task",
help = "find the signature data files for last two runs of the specified task and compare them",
action="store", dest="taskargs", nargs=2, metavar='recipename taskname')
parser = argparse.ArgumentParser(
description=("Dumps" if is_dump else "Compares") + " siginfo/sigdata files written out by BitBake")
parser.add_argument('-D', '--debug',
help='Enable debug output',
action='store_true')
if is_dump:
parser.add_argument("-t", "--task",
help="find the signature data file for the last run of the specified task",
action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))
parser.add_argument("sigdatafile1",
help="Signature file to dump. Not used when using -t/--task.",
action="store", nargs='?', metavar="sigdatafile")
else:
parser.add_argument('-c', '--color',
help='Colorize the output (where %(metavar)s is %(choices)s)',
choices=['auto', 'always', 'never'], default='auto', metavar='color')
parser.add_argument('-d', '--dump',
help='Dump the last signature data instead of comparing (equivalent to using bitbake-dumpsig)',
action='store_true')
parser.add_argument("-t", "--task",
help="find the signature data files for the last two runs of the specified task and compare them",
action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))
parser.add_argument("-s", "--signature",
help="With -t/--task, specify the signatures to look for instead of taking the last two",
action="store", dest="sigargs", nargs=2, metavar=('fromsig', 'tosig'))
parser.add_argument("sigdatafile1",
help="First signature file to compare (or signature file to dump, if second not specified). Not used when using -t/--task.",
action="store", nargs='?')
parser.add_argument("sigdatafile2",
help="Second signature file to compare",
action="store", nargs='?')
options = parser.parse_args()
if is_dump:
options.color = 'never'
options.dump = True
options.sigdatafile2 = None
options.sigargs = None
if options.debug:
logger.setLevel(logging.DEBUG)
color = (options.color == 'always' or (options.color == 'auto' and sys.stdout.isatty()))
options, args = parser.parse_args(sys.argv)
if options.taskargs:
with bb.tinfoil.Tinfoil() as tinfoil:
tinfoil.prepare(config_only=True)
if not options.dump and options.sigargs:
files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1], options.sigargs[0], options.sigargs[1])
else:
files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1])
if options.dump:
logger.debug("Signature file: %s" % files[-1])
output = bb.siggen.dump_sigfile(files[-1])
else:
if len(files) < 2:
logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (options.taskargs[0], options.taskargs[1]))
sys.exit(1)
# Recurse into signature comparison
logger.debug("Signature file (previous): %s" % files[-2])
logger.debug("Signature file (latest): %s" % files[-1])
output = bb.siggen.compare_sigfiles(files[-2], files[-1], recursecb, color=color)
tinfoil = bb.tinfoil.Tinfoil()
tinfoil.prepare(config_only = True)
find_compare_task(tinfoil, options.taskargs[0], options.taskargs[1])
else:
if options.sigargs:
logger.error('-s/--signature can only be used together with -t/--task')
sys.exit(1)
try:
if not options.dump and options.sigdatafile1 and options.sigdatafile2:
with bb.tinfoil.Tinfoil() as tinfoil:
tinfoil.prepare(config_only=True)
output = bb.siggen.compare_sigfiles(options.sigdatafile1, options.sigdatafile2, recursecb, color=color)
elif options.sigdatafile1:
output = bb.siggen.dump_sigfile(options.sigdatafile1)
else:
logger.error('Must specify signature file(s) or -t/--task')
parser.print_help()
if len(args) == 1:
parser.print_help()
else:
import cPickle
try:
if len(args) == 2:
output = bb.siggen.dump_sigfile(sys.argv[1])
else:
output = bb.siggen.compare_sigfiles(sys.argv[1], sys.argv[2])
except IOError as e:
logger.error(str(e))
sys.exit(1)
except cPickle.UnpicklingError, EOFError:
logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files')
sys.exit(1)
except IOError as e:
logger.error(str(e))
sys.exit(1)
except (pickle.UnpicklingError, EOFError):
logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files')
sys.exit(1)
if output:
print('\n'.join(output))
if output:
print '\n'.join(output)

View File

@@ -1 +0,0 @@
bitbake-diffsigs

65
bitbake/bin/bitbake-dumpsig Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python
# bitbake-dumpsig
# BitBake task signature dump utility
#
# Copyright (C) 2013 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import warnings
import optparse
import logging
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
import bb.siggen
def logger_create(name, output=sys.stderr):
logger = logging.getLogger(name)
console = logging.StreamHandler(output)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
if output.isatty():
format.enable_color()
console.setFormatter(format)
logger.addHandler(console)
logger.setLevel(logging.INFO)
return logger
logger = logger_create('bitbake-dumpsig')
parser = optparse.OptionParser(
description = "Dumps siginfo/sigdata files written out by BitBake",
usage = """
%prog sigdatafile""")
options, args = parser.parse_args(sys.argv)
if len(args) == 1:
parser.print_help()
else:
import cPickle
try:
output = bb.siggen.dump_sigfile(args[1])
except IOError as e:
logger.error(str(e))
sys.exit(1)
except cPickle.UnpicklingError, EOFError:
logger.error('Invalid signature data - ensure you are specifying a sigdata/siginfo file')
sys.exit(1)
if output:
print '\n'.join(output)

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
import os
import sys,logging
import optparse
@@ -50,6 +50,6 @@ if __name__ == "__main__":
except Exception:
ret = 1
import traceback
traceback.print_exc()
traceback.print_exc(5)
sys.exit(ret)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
#
# Copyright (C) 2012 Richard Purdie
#
@@ -25,49 +25,25 @@ try:
except RuntimeError as exc:
sys.exit(str(exc))
tests = ["bb.tests.codeparser",
"bb.tests.cow",
"bb.tests.data",
"bb.tests.event",
"bb.tests.fetch",
"bb.tests.parse",
"bb.tests.utils"]
def usage():
print('usage: %s [testname1 [testname2]...]' % os.path.basename(sys.argv[0]))
if len(sys.argv) > 1:
if '--help' in sys.argv[1:]:
usage()
sys.exit(0)
tests = sys.argv[1:]
else:
tests = ["bb.tests.codeparser",
"bb.tests.cow",
"bb.tests.data",
"bb.tests.fetch",
"bb.tests.utils"]
for t in tests:
t = '.'.join(t.split('.')[:3])
__import__(t)
unittest.main(argv=["bitbake-selftest"] + tests)
# Set-up logging
class StdoutStreamHandler(logging.StreamHandler):
"""Special handler so that unittest is able to capture stdout"""
def __init__(self):
# Override __init__() because we don't want to set self.stream here
logging.Handler.__init__(self)
@property
def stream(self):
# We want to dynamically write wherever sys.stdout is pointing to
return sys.stdout
handler = StdoutStreamHandler()
bb.logger.addHandler(handler)
bb.logger.setLevel(logging.DEBUG)
ENV_HELP = """\
Environment variables:
BB_SKIP_NETTESTS set to 'yes' in order to skip tests using network
connection
BB_TMPDIR_NOCLEAN set to 'yes' to preserve test tmp directories
"""
class main(unittest.main):
def _print_help(self, *args, **kwargs):
super(main, self)._print_help(*args, **kwargs)
print(ENV_HELP)
if __name__ == '__main__':
main(defaultTest=tests, buffer=True)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
import os
import sys
@@ -10,14 +10,6 @@ import bb
import select
import errno
import signal
import pickle
import traceback
import queue
from multiprocessing import Lock
from threading import Thread
if sys.getfilesystemencoding() != "utf-8":
sys.exit("Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).\nPython can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.")
# Users shouldn't be running this code directly
if len(sys.argv) != 2 or not sys.argv[1].startswith("decafbad"):
@@ -25,33 +17,24 @@ if len(sys.argv) != 2 or not sys.argv[1].startswith("decafbad"):
sys.exit(1)
profiling = False
if sys.argv[1].startswith("decafbadbad"):
if sys.argv[1] == "decafbadbad":
profiling = True
try:
import cProfile as profile
except:
import profile
# Unbuffer stdout to avoid log truncation in the event
# of an unorderly exit as well as to provide timely
# updates to log files for use with tail
try:
if sys.stdout.name == '<stdout>':
import fcntl
fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
#sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
except:
pass
logger = logging.getLogger("BitBake")
try:
import cPickle as pickle
except ImportError:
import pickle
bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")
worker_pipe = sys.stdout.fileno()
bb.utils.nonblockingfd(worker_pipe)
# Need to guard against multiprocessing being used in child processes
# and multiple processes trying to write to the parent at the same time
worker_pipe_lock = None
handler = bb.event.LogHandler()
logger.addHandler(handler)
@@ -66,61 +49,36 @@ if 0:
consolelog.setFormatter(conlogformat)
logger.addHandler(consolelog)
worker_queue = queue.Queue()
worker_queue = ""
def worker_fire(event, d):
data = b"<event>" + pickle.dumps(event) + b"</event>"
data = "<event>" + pickle.dumps(event) + "</event>"
worker_fire_prepickled(data)
def worker_fire_prepickled(event):
global worker_queue
worker_queue.put(event)
worker_queue = worker_queue + event
worker_flush()
#
# We can end up with write contention with the cooker, it can be trying to send commands
# and we can be trying to send event data back. Therefore use a separate thread for writing
# back data to cooker.
#
worker_thread_exit = False
def worker_flush():
global worker_queue, worker_pipe
def worker_flush(worker_queue):
worker_queue_int = b""
global worker_pipe, worker_thread_exit
if not worker_queue:
return
while True:
try:
worker_queue_int = worker_queue_int + worker_queue.get(True, 1)
except queue.Empty:
pass
while (worker_queue_int or not worker_queue.empty()):
try:
(_, ready, _) = select.select([], [worker_pipe], [], 1)
if not worker_queue.empty():
worker_queue_int = worker_queue_int + worker_queue.get()
written = os.write(worker_pipe, worker_queue_int)
worker_queue_int = worker_queue_int[written:]
except (IOError, OSError) as e:
if e.errno != errno.EAGAIN and e.errno != errno.EPIPE:
raise
if worker_thread_exit and worker_queue.empty() and not worker_queue_int:
return
worker_thread = Thread(target=worker_flush, args=(worker_queue,))
worker_thread.start()
try:
written = os.write(worker_pipe, worker_queue)
worker_queue = worker_queue[written:]
except (IOError, OSError) as e:
if e.errno != errno.EAGAIN:
raise
def worker_child_fire(event, d):
global worker_pipe
global worker_pipe_lock
data = b"<event>" + pickle.dumps(event) + b"</event>"
try:
worker_pipe_lock.acquire()
worker_pipe.write(data)
worker_pipe_lock.release()
except IOError:
sigterm_handler(None, None)
raise
data = "<event>" + pickle.dumps(event) + "</event>"
worker_pipe.write(data)
bb.event.worker_fire = worker_fire
@@ -136,7 +94,7 @@ def sigterm_handler(signum, frame):
os.killpg(0, signal.SIGTERM)
sys.exit()
def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, appends, taskdepdata, extraconfigdata, quieterrors=False, dry_run_exec=False):
def fork_off_task(cfg, data, workerdata, fn, task, taskname, appends, taskdepdata, quieterrors=False):
# We need to setup the environment BEFORE the fork, since
# a fork() or exec*() activates PSEUDO...
@@ -152,10 +110,8 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, append
except TypeError:
umask = taskdep['umask'][taskname]
dry_run = cfg.dry_run or dry_run_exec
# We can't use the fakeroot environment in a dry run as it possibly hasn't been built
if 'fakeroot' in taskdep and taskname in taskdep['fakeroot'] and not dry_run:
if 'fakeroot' in taskdep and taskname in taskdep['fakeroot'] and not cfg.dry_run:
envvars = (workerdata["fakerootenv"][fn] or "").split()
for key, value in (var.split('=') for var in envvars):
envbackup[key] = os.environ.get(key)
@@ -183,34 +139,28 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, append
pipeout = os.fdopen(pipeout, 'wb', 0)
pid = os.fork()
except OSError as e:
logger.critical("fork failed: %d (%s)" % (e.errno, e.strerror))
sys.exit(1)
bb.msg.fatal("RunQueue", "fork failed: %d (%s)" % (e.errno, e.strerror))
if pid == 0:
def child():
global worker_pipe
global worker_pipe_lock
pipein.close()
bb.utils.signal_on_parent_exit("SIGTERM")
signal.signal(signal.SIGTERM, sigterm_handler)
# Let SIGHUP exit as SIGTERM
signal.signal(signal.SIGHUP, sigterm_handler)
# Save out the PID so that the event can include it the
# events
bb.event.worker_pid = os.getpid()
bb.event.worker_fire = worker_child_fire
worker_pipe = pipeout
worker_pipe_lock = Lock()
# Make the child the process group leader and ensure no
# child process will be controlled by the current terminal
# This ensures signals sent to the controlling terminal like Ctrl+C
# don't stop the child processes.
os.setsid()
signal.signal(signal.SIGTERM, sigterm_handler)
# Let SIGHUP exit as SIGTERM
signal.signal(signal.SIGHUP, sigterm_handler)
# No stdin
newsi = os.open(os.devnull, os.O_RDWR)
os.dup2(newsi, sys.stdin.fileno())
@@ -218,58 +168,37 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, append
if umask:
os.umask(umask)
data.setVar("BB_WORKERCONTEXT", "1")
data.setVar("BB_TASKDEPDATA", taskdepdata)
data.setVar("BUILDNAME", workerdata["buildname"])
data.setVar("DATE", workerdata["date"])
data.setVar("TIME", workerdata["time"])
bb.parse.siggen.set_taskdata(workerdata["sigdata"])
ret = 0
try:
bb_cache = bb.cache.NoCache(databuilder)
(realfn, virtual, mc) = bb.cache.virtualfn2realfn(fn)
the_data = databuilder.mcdata[mc]
the_data.setVar("BB_WORKERCONTEXT", "1")
the_data.setVar("BB_TASKDEPDATA", taskdepdata)
if cfg.limited_deps:
the_data.setVar("BB_LIMITEDDEPS", "1")
the_data.setVar("BUILDNAME", workerdata["buildname"])
the_data.setVar("DATE", workerdata["date"])
the_data.setVar("TIME", workerdata["time"])
for varname, value in extraconfigdata.items():
the_data.setVar(varname, value)
bb.parse.siggen.set_taskdata(workerdata["sigdata"])
ret = 0
the_data = bb_cache.loadDataFull(fn, appends)
the_data = bb.cache.Cache.loadDataFull(fn, appends, data)
the_data.setVar('BB_TASKHASH', workerdata["runq_hash"][task])
bb.utils.set_process_name("%s:%s" % (the_data.getVar("PN"), taskname.replace("do_", "")))
# exported_vars() returns a generator which *cannot* be passed to os.environ.update()
# successfully. We also need to unset anything from the environment which shouldn't be there
exports = bb.data.exported_vars(the_data)
bb.utils.empty_environment()
for e, v in exports:
os.environ[e] = v
for e in fakeenv:
os.environ[e] = fakeenv[e]
the_data.setVar(e, fakeenv[e])
the_data.setVarFlag(e, 'export', "1")
task_exports = the_data.getVarFlag(taskname, 'exports')
if task_exports:
for e in task_exports.split():
the_data.setVarFlag(e, 'export', '1')
v = the_data.getVar(e)
if v is not None:
os.environ[e] = v
if quieterrors:
the_data.setVarFlag(taskname, "quieterrors", "1")
except Exception:
except Exception as exc:
if not quieterrors:
logger.critical(traceback.format_exc())
logger.critical(str(exc))
os._exit(1)
try:
if dry_run:
if cfg.dry_run:
return 0
return bb.build.exec_task(fn, taskname, the_data, cfg.profile)
except:
@@ -286,7 +215,7 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, append
bb.utils.process_profilelog(profname)
os._exit(ret)
else:
for key, value in iter(envbackup.items()):
for key, value in envbackup.iteritems():
if value is None:
del os.environ[key]
else:
@@ -303,22 +232,22 @@ class runQueueWorkerPipe():
if pipeout:
pipeout.close()
bb.utils.nonblockingfd(self.input)
self.queue = b""
self.queue = ""
def read(self):
start = len(self.queue)
try:
self.queue = self.queue + (self.input.read(102400) or b"")
self.queue = self.queue + self.input.read(102400)
except (OSError, IOError) as e:
if e.errno != errno.EAGAIN:
raise
end = len(self.queue)
index = self.queue.find(b"</event>")
index = self.queue.find("</event>")
while index != -1:
worker_fire_prepickled(self.queue[:index+8])
self.queue = self.queue[index+8:]
index = self.queue.find(b"</event>")
index = self.queue.find("</event>")
return (end > start)
def close(self):
@@ -334,27 +263,22 @@ class BitbakeWorker(object):
def __init__(self, din):
self.input = din
bb.utils.nonblockingfd(self.input)
self.queue = b""
self.queue = ""
self.cookercfg = None
self.databuilder = None
self.data = None
self.extraconfigdata = None
self.build_pids = {}
self.build_pipes = {}
signal.signal(signal.SIGTERM, self.sigterm_exception)
# Let SIGHUP exit as SIGTERM
signal.signal(signal.SIGHUP, self.sigterm_exception)
if "beef" in sys.argv[1]:
bb.utils.set_process_name("Worker (Fakeroot)")
else:
bb.utils.set_process_name("Worker")
def sigterm_exception(self, signum, stackframe):
if signum == signal.SIGTERM:
bb.warn("Worker received SIGTERM, shutting down...")
bb.warn("Worker recieved SIGTERM, shutting down...")
elif signum == signal.SIGHUP:
bb.warn("Worker received SIGHUP, shutting down...")
bb.warn("Worker recieved SIGHUP, shutting down...")
self.handle_finishnow(None)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
os.kill(os.getpid(), signal.SIGTERM)
@@ -362,39 +286,34 @@ class BitbakeWorker(object):
def serve(self):
while True:
(ready, _, _) = select.select([self.input] + [i.input for i in self.build_pipes.values()], [] , [], 1)
if self.input in ready:
if self.input in ready or len(self.queue):
start = len(self.queue)
try:
r = self.input.read()
if len(r) == 0:
# EOF on pipe, server must have terminated
self.sigterm_exception(signal.SIGTERM, None)
self.queue = self.queue + r
self.queue = self.queue + self.input.read()
except (OSError, IOError):
pass
if len(self.queue):
self.handle_item(b"cookerconfig", self.handle_cookercfg)
self.handle_item(b"extraconfigdata", self.handle_extraconfigdata)
self.handle_item(b"workerdata", self.handle_workerdata)
self.handle_item(b"runtask", self.handle_runtask)
self.handle_item(b"finishnow", self.handle_finishnow)
self.handle_item(b"ping", self.handle_ping)
self.handle_item(b"quit", self.handle_quit)
end = len(self.queue)
self.handle_item("cookerconfig", self.handle_cookercfg)
self.handle_item("workerdata", self.handle_workerdata)
self.handle_item("runtask", self.handle_runtask)
self.handle_item("finishnow", self.handle_finishnow)
self.handle_item("ping", self.handle_ping)
self.handle_item("quit", self.handle_quit)
for pipe in self.build_pipes:
if self.build_pipes[pipe].input in ready:
self.build_pipes[pipe].read()
self.build_pipes[pipe].read()
if len(self.build_pids):
while self.process_waitpid():
continue
self.process_waitpid()
worker_flush()
def handle_item(self, item, func):
if self.queue.startswith(b"<" + item + b">"):
index = self.queue.find(b"</" + item + b">")
if self.queue.startswith("<" + item + ">"):
index = self.queue.find("</" + item + ">")
while index != -1:
func(self.queue[(len(item) + 2):index])
self.queue = self.queue[(index + len(item) + 3):]
index = self.queue.find(b"</" + item + b">")
index = self.queue.find("</" + item + ">")
def handle_cookercfg(self, data):
self.cookercfg = pickle.loads(data)
@@ -402,22 +321,18 @@ class BitbakeWorker(object):
self.databuilder.parseBaseConfiguration()
self.data = self.databuilder.data
def handle_extraconfigdata(self, data):
self.extraconfigdata = pickle.loads(data)
def handle_workerdata(self, data):
self.workerdata = pickle.loads(data)
bb.msg.loggerDefaultDebugLevel = self.workerdata["logdefaultdebug"]
bb.msg.loggerDefaultVerbose = self.workerdata["logdefaultverbose"]
bb.msg.loggerVerboseLogs = self.workerdata["logdefaultverboselogs"]
bb.msg.loggerDefaultDomains = self.workerdata["logdefaultdomain"]
for mc in self.databuilder.mcdata:
self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"])
self.data.setVar("PRSERV_HOST", self.workerdata["prhost"])
def handle_ping(self, _):
workerlog_write("Handling ping\n")
logger.warning("Pong from bitbake-worker!")
logger.warn("Pong from bitbake-worker!")
def handle_quit(self, data):
workerlog_write("Handling quit\n")
@@ -427,10 +342,10 @@ class BitbakeWorker(object):
sys.exit(0)
def handle_runtask(self, data):
fn, task, taskname, quieterrors, appends, taskdepdata, dry_run_exec = pickle.loads(data)
fn, task, taskname, quieterrors, appends, taskdepdata = pickle.loads(data)
workerlog_write("Handling runtask %s %s %s\n" % (task, fn, taskname))
pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.databuilder, self.workerdata, fn, task, taskname, appends, taskdepdata, self.extraconfigdata, quieterrors, dry_run_exec)
pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.workerdata, fn, task, taskname, appends, taskdepdata, quieterrors)
self.build_pids[pid] = task
self.build_pipes[pid] = runQueueWorkerPipe(pipein, pipeout)
@@ -443,9 +358,9 @@ class BitbakeWorker(object):
try:
pid, status = os.waitpid(-1, os.WNOHANG)
if pid == 0 or os.WIFSTOPPED(status):
return False
return None
except OSError:
return False
return None
workerlog_write("Exit code of %s for pid %s\n" % (status, pid))
@@ -462,14 +377,12 @@ class BitbakeWorker(object):
self.build_pipes[pid].close()
del self.build_pipes[pid]
worker_fire_prepickled(b"<exitcode>" + pickle.dumps((task, status)) + b"</exitcode>")
return True
worker_fire_prepickled("<exitcode>" + pickle.dumps((task, status)) + "</exitcode>")
def handle_finishnow(self, _):
if self.build_pids:
logger.info("Sending SIGTERM to remaining %s tasks", len(self.build_pids))
for k, v in iter(self.build_pids.items()):
for k, v in self.build_pids.iteritems():
try:
os.kill(-k, signal.SIGTERM)
os.waitpid(-1, 0)
@@ -479,7 +392,7 @@ class BitbakeWorker(object):
self.build_pipes[pipe].read()
try:
worker = BitbakeWorker(os.fdopen(sys.stdin.fileno(), 'rb'))
worker = BitbakeWorker(sys.stdin)
if not profiling:
worker.serve()
else:
@@ -495,9 +408,8 @@ except BaseException as e:
import traceback
sys.stderr.write(traceback.format_exc())
sys.stderr.write(str(e))
worker_thread_exit = True
worker_thread.join()
while len(worker_queue):
worker_flush()
workerlog_write("exitting")
sys.exit(0)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
@@ -462,7 +462,7 @@ def main():
state_group = 2
for key in bb.data.keys(documentation):
data = documentation.getVarFlag(key, "doc", False)
data = documentation.getVarFlag(key, "doc")
if not data:
continue

View File

@@ -1,165 +0,0 @@
#!/usr/bin/env python3
"""git-make-shallow: make the current git repository shallow
Remove the history of the specified revisions, then optionally filter the
available refs to those specified.
"""
import argparse
import collections
import errno
import itertools
import os
import subprocess
import sys
version = 1.0
def main():
if sys.version_info < (3, 4, 0):
sys.exit('Python 3.4 or greater is required')
git_dir = check_output(['git', 'rev-parse', '--git-dir']).rstrip()
shallow_file = os.path.join(git_dir, 'shallow')
if os.path.exists(shallow_file):
try:
check_output(['git', 'fetch', '--unshallow'])
except subprocess.CalledProcessError:
try:
os.unlink(shallow_file)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
args = process_args()
revs = check_output(['git', 'rev-list'] + args.revisions).splitlines()
make_shallow(shallow_file, args.revisions, args.refs)
ref_revs = check_output(['git', 'rev-list'] + args.refs).splitlines()
remaining_history = set(revs) & set(ref_revs)
for rev in remaining_history:
if check_output(['git', 'rev-parse', '{}^@'.format(rev)]):
sys.exit('Error: %s was not made shallow' % rev)
filter_refs(args.refs)
if args.shrink:
shrink_repo(git_dir)
subprocess.check_call(['git', 'fsck', '--unreachable'])
def process_args():
# TODO: add argument to automatically keep local-only refs, since they
# can't be easily restored with a git fetch.
parser = argparse.ArgumentParser(description='Remove the history of the specified revisions, then optionally filter the available refs to those specified.')
parser.add_argument('--ref', '-r', metavar='REF', action='append', dest='refs', help='remove all but the specified refs (cumulative)')
parser.add_argument('--shrink', '-s', action='store_true', help='shrink the git repository by repacking and pruning')
parser.add_argument('revisions', metavar='REVISION', nargs='+', help='a git revision/commit')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(2)
args = parser.parse_args()
if args.refs:
args.refs = check_output(['git', 'rev-parse', '--symbolic-full-name'] + args.refs).splitlines()
else:
args.refs = get_all_refs(lambda r, t, tt: t == 'commit' or tt == 'commit')
args.refs = list(filter(lambda r: not r.endswith('/HEAD'), args.refs))
args.revisions = check_output(['git', 'rev-parse'] + ['%s^{}' % i for i in args.revisions]).splitlines()
return args
def check_output(cmd, input=None):
return subprocess.check_output(cmd, universal_newlines=True, input=input)
def make_shallow(shallow_file, revisions, refs):
"""Remove the history of the specified revisions."""
for rev in follow_history_intersections(revisions, refs):
print("Processing %s" % rev)
with open(shallow_file, 'a') as f:
f.write(rev + '\n')
def get_all_refs(ref_filter=None):
"""Return all the existing refs in this repository, optionally filtering the refs."""
ref_output = check_output(['git', 'for-each-ref', '--format=%(refname)\t%(objecttype)\t%(*objecttype)'])
ref_split = [tuple(iter_extend(l.rsplit('\t'), 3)) for l in ref_output.splitlines()]
if ref_filter:
ref_split = (e for e in ref_split if ref_filter(*e))
refs = [r[0] for r in ref_split]
return refs
def iter_extend(iterable, length, obj=None):
"""Ensure that iterable is the specified length by extending with obj."""
return itertools.islice(itertools.chain(iterable, itertools.repeat(obj)), length)
def filter_refs(refs):
"""Remove all but the specified refs from the git repository."""
all_refs = get_all_refs()
to_remove = set(all_refs) - set(refs)
if to_remove:
check_output(['xargs', '-0', '-n', '1', 'git', 'update-ref', '-d', '--no-deref'],
input=''.join(l + '\0' for l in to_remove))
def follow_history_intersections(revisions, refs):
"""Determine all the points where the history of the specified revisions intersects the specified refs."""
queue = collections.deque(revisions)
seen = set()
for rev in iter_except(queue.popleft, IndexError):
if rev in seen:
continue
parents = check_output(['git', 'rev-parse', '%s^@' % rev]).splitlines()
yield rev
seen.add(rev)
if not parents:
continue
check_refs = check_output(['git', 'merge-base', '--independent'] + sorted(refs)).splitlines()
for parent in parents:
for ref in check_refs:
print("Checking %s vs %s" % (parent, ref))
try:
merge_base = check_output(['git', 'merge-base', parent, ref]).rstrip()
except subprocess.CalledProcessError:
continue
else:
queue.append(merge_base)
def iter_except(func, exception, start=None):
"""Yield a function repeatedly until it raises an exception."""
try:
if start is not None:
yield start()
while True:
yield func()
except exception:
pass
def shrink_repo(git_dir):
"""Shrink the newly shallow repository, removing the unreachable objects."""
subprocess.check_call(['git', 'reflog', 'expire', '--expire-unreachable=now', '--all'])
subprocess.check_call(['git', 'repack', '-ad'])
try:
os.unlink(os.path.join(git_dir, 'objects', 'info', 'alternates'))
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
subprocess.check_call(['git', 'prune', '--expire', 'now'])
if __name__ == '__main__':
main()

122
bitbake/bin/image-writer Executable file
View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python
# Copyright (c) 2012 Wind River Systems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname( \
os.path.abspath(__file__))), 'lib'))
try:
import bb
except RuntimeError as exc:
sys.exit(str(exc))
import gtk
import optparse
import pygtk
from bb.ui.crumbs.hobwidget import HobAltButton, HobButton
from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
from bb.ui.crumbs.hig.deployimagedialog import DeployImageDialog
from bb.ui.crumbs.hig.imageselectiondialog import ImageSelectionDialog
# I put all the fs bitbake supported here. Need more test.
DEPLOYABLE_IMAGE_TYPES = ["jffs2", "cramfs", "ext2", "ext3", "ext4", "btrfs", "squashfs", "ubi", "vmdk"]
Title = "USB Image Writer"
class DeployWindow(gtk.Window):
def __init__(self, image_path=''):
super(DeployWindow, self).__init__()
if len(image_path) > 0:
valid = True
if not os.path.exists(image_path):
valid = False
lbl = "<b>Invalid image file path: %s.</b>\nPress <b>Select Image</b> to select an image." % image_path
else:
image_path = os.path.abspath(image_path)
extend_name = os.path.splitext(image_path)[1][1:]
if extend_name not in DEPLOYABLE_IMAGE_TYPES:
valid = False
lbl = "<b>Undeployable imge type: %s</b>\nPress <b>Select Image</b> to select an image." % extend_name
if not valid:
image_path = ''
crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
HobButton.style_button(button)
crumbs_dialog.run()
crumbs_dialog.destroy()
self.deploy_dialog = DeployImageDialog(Title, image_path, self,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT
| gtk.DIALOG_NO_SEPARATOR, None, standalone=True)
close_button = self.deploy_dialog.add_button("Close", gtk.RESPONSE_NO)
HobAltButton.style_button(close_button)
close_button.connect('clicked', gtk.main_quit)
write_button = self.deploy_dialog.add_button("Write USB image", gtk.RESPONSE_YES)
HobAltButton.style_button(write_button)
self.deploy_dialog.connect('select_image_clicked', self.select_image_clicked_cb)
self.deploy_dialog.connect('destroy', gtk.main_quit)
response = self.deploy_dialog.show()
def select_image_clicked_cb(self, dialog):
cwd = os.getcwd()
dialog = ImageSelectionDialog(cwd, DEPLOYABLE_IMAGE_TYPES, Title, self, gtk.FILE_CHOOSER_ACTION_SAVE )
button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
HobAltButton.style_button(button)
button = dialog.add_button("Open", gtk.RESPONSE_YES)
HobAltButton.style_button(button)
response = dialog.run()
if response == gtk.RESPONSE_YES:
if not dialog.image_names:
lbl = "<b>No selections made</b>\nClicked the radio button to select a image."
crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
HobButton.style_button(button)
crumbs_dialog.run()
crumbs_dialog.destroy()
dialog.destroy()
return
# get the full path of image
image_path = os.path.join(dialog.image_folder, dialog.image_names[0])
self.deploy_dialog.set_image_text_buffer(image_path)
self.deploy_dialog.set_image_path(image_path)
dialog.destroy()
def main():
parser = optparse.OptionParser(
usage = """%prog [-h] [image_file]
%prog writes bootable images to USB devices. You can
provide the image file on the command line or select it using the GUI.""")
options, args = parser.parse_args(sys.argv)
image_file = args[1] if len(args) > 1 else ''
dw = DeployWindow(image_file)
if __name__ == '__main__':
try:
main()
gtk.main()
except Exception:
import traceback
traceback.print_exc(3)

View File

@@ -1,8 +1,5 @@
#!/bin/echo ERROR: This script needs to be sourced. Please run as .
# toaster - shell script to start Toaster
# Copyright (C) 2013-2015 Intel Corp.
#!/bin/bash
# (c) 2013 Intel Corp.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,307 +12,329 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
HELP="
Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir]
Optional arguments:
[nobuild] Setup the environment for capturing builds with toaster but disable managed builds
[noweb] Setup the environment for capturing builds with toaster but don't start the web server
[webport] Set the development server (default: localhost:8000)
[toasterdir] Set absolute path to be used as TOASTER_DIR (default: BUILDDIR/../)
"
custom_extention()
# This script can be run in two modes.
# When used with "source", from a build directory,
# it enables toaster event logging and starts the bitbake resident server.
# use as: source toaster [start|stop] [noweb] [noui]
# When it is called as a stand-alone script, it starts just the
# web server, and the building shall be done through the web interface.
# As script, it will not return to the command prompt. Stop with Ctrl-C.
# Helper function to kill a background toaster development server
function webserverKillAll()
{
custom_extension=$BBBASEDIR/lib/toaster/orm/fixtures/custom_toaster_append.sh
if [ -f $custom_extension ] ; then
$custom_extension $*
fi
local pidfile
for pidfile in ${BUILDDIR}/.toastermain.pid; do
if [ -f ${pidfile} ]; then
while kill -0 $(< ${pidfile}) 2>/dev/null; do
kill -SIGTERM -$(< ${pidfile}) 2>/dev/null
sleep 1;
# Kill processes if they are still running - may happen in interactive shells
ps fux | grep "python.*manage.py runserver" | awk '{print $2}' | xargs kill
done;
rm ${pidfile}
fi
done
}
databaseCheck()
function webserverStartAll()
{
retval=0
# you can always add a superuser later via
# ../bitbake/lib/toaster/manage.py createsuperuser --username=<ME>
$MANAGE migrate --noinput || retval=1
if [ $retval -eq 1 ]; then
echo "Failed migrations, aborting system start" 1>&2
return $retval
fi
# Make sure that checksettings can pick up any value for TEMPLATECONF
export TEMPLATECONF
$MANAGE checksettings --traceback || retval=1
if [ $retval -eq 1 ]; then
printf "\nError while checking settings; aborting\n"
return $retval
fi
return $retval
}
webserverKillAll()
{
local pidfile
if [ -f ${BUILDDIR}/.toastermain.pid ] ; then
custom_extention web_stop_postpend
else
custom_extention noweb_stop_postpend
fi
for pidfile in ${BUILDDIR}/.toastermain.pid ${BUILDDIR}/.runbuilds.pid; do
if [ -f ${pidfile} ]; then
pid=`cat ${pidfile}`
while kill -0 $pid 2>/dev/null; do
kill -SIGTERM $pid 2>/dev/null
sleep 1
done
rm ${pidfile}
# do not start if toastermain points to a valid process
if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then
retval=1
rm "${BUILDDIR}/.toastermain.pid"
fi
done
retval=0
python $BBBASEDIR/lib/toaster/manage.py syncdb || retval=1
python $BBBASEDIR/lib/toaster/manage.py migrate orm || retval=2
if [ $retval -eq 1 ]; then
echo "Failed db sync, stopping system start" 1>&2
elif [ $retval -eq 2 ]; then
echo -e "\nError on migration, trying to recover... \n"
python $BBBASEDIR/lib/toaster/manage.py migrate orm 0001_initial --fake
retval=0
python $BBBASEDIR/lib/toaster/manage.py migrate orm || retval=1
fi
if [ "x$TOASTER_MANAGED" == "x1" ]; then
python $BBBASEDIR/lib/toaster/manage.py migrate bldcontrol || retval=1
python $BBBASEDIR/lib/toaster/manage.py checksettings --traceback || retval=1
fi
if [ $retval -eq 0 ]; then
echo "Starting webserver..."
python $BBBASEDIR/lib/toaster/manage.py runserver "0.0.0.0:$WEB_PORT" </dev/null >>${BUILDDIR}/toaster_web.log 2>&1 & echo $! >${BUILDDIR}/.toastermain.pid
sleep 1
if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then
retval=1
rm "${BUILDDIR}/.toastermain.pid"
else
echo "Webserver address: http://0.0.0.0:$WEB_PORT/"
fi
fi
return $retval
}
webserverStartAll()
# Helper functions to add a special configuration file
function addtoConfiguration()
{
# do not start if toastermain points to a valid process
if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then
retval=1
rm "${BUILDDIR}/.toastermain.pid"
fi
retval=0
# check the database
databaseCheck || return 1
echo "Starting webserver..."
$MANAGE runserver --noreload "$ADDR_PORT" \
</dev/null >>${BUILDDIR}/toaster_web.log 2>&1 \
& echo $! >${BUILDDIR}/.toastermain.pid
sleep 1
if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then
retval=1
rm "${BUILDDIR}/.toastermain.pid"
else
echo "Toaster development webserver started at http://$ADDR_PORT"
echo -e "\nYou can now run 'bitbake <target>' on the command line and monitor your build in Toaster.\nYou can also use a Toaster project to configure and run a build.\n"
custom_extention web_start_postpend $ADDR_PORT
fi
return $retval
file=$1
shift
echo "#Created by toaster start script" > ${BUILDDIR}/conf/$file
for var in "$@"; do echo $var >> ${BUILDDIR}/conf/$file; done
}
INSTOPSYSTEM=0
# define the stop command
stop_system()
function stop_system()
{
# prevent reentry
if [ $INSTOPSYSTEM -eq 1 ]; then return; fi
if [ $INSTOPSYSTEM == 1 ]; then return; fi
INSTOPSYSTEM=1
if [ -f ${BUILDDIR}/.toasterui.pid ]; then
kill $(< ${BUILDDIR}/.toasterui.pid ) 2>/dev/null
rm ${BUILDDIR}/.toasterui.pid
fi
BBSERVER=0.0.0.0:-1 bitbake -m
unset BBSERVER
webserverKillAll
# unset exported variables
unset TOASTER_DIR
unset BITBAKE_UI
unset BBBASEDIR
# force stop any misbehaving bitbake server
lsof bitbake.lock | awk '{print $2}' | grep "[0-9]\+" | xargs -n1 -r kill
trap - SIGHUP
#trap - SIGCHLD
INSTOPSYSTEM=0
}
verify_prereq() {
# Verify Django version
reqfile=$(python3 -c "import os; print(os.path.realpath('$BBBASEDIR/toaster-requirements.txt'))")
exp='s/Django\([><=]\+\)\([^,]\+\),\([><=]\+\)\(.\+\)/'
# expand version parts to 2 digits to support 1.10.x > 1.8
# (note:helper functions hard to insert in-line)
exp=$exp'import sys,django;'
exp=$exp'version=["%02d" % int(n) for n in django.get_version().split(".")];'
exp=$exp'vmin=["%02d" % int(n) for n in "\2".split(".")];'
exp=$exp'vmax=["%02d" % int(n) for n in "\4".split(".")];'
exp=$exp'sys.exit(not (version \1 vmin and version \3 vmax))'
exp=$exp'/p'
if ! sed -n "$exp" $reqfile | python3 - ; then
req=`grep ^Django $reqfile`
echo "This program needs $req"
echo "Please install with pip3 install -r $reqfile"
function check_pidbyfile() {
[ -e $1 ] && kill -0 $(< $1) 2>/dev/null
}
function notify_chldexit() {
if [ $NOTOASTERUI == 0 ]; then
check_pidbyfile ${BUILDDIR}/.toasterui.pid && return
stop_system
fi
}
function verify_prereq() {
# Verify prerequisites
if ! echo "import django; print (1,) == django.VERSION[0:1] and django.VERSION[1:2][0] in (6,)" | python 2>/dev/null | grep True >/dev/null; then
echo -e "This program needs Django 1.6. Please install with\n\npip install django==1.6\n"
return 2
fi
if ! echo "import south; print reduce(lambda x, y: 2 if x==2 else 0 if x == 0 else y, map(lambda x: 1+cmp(x[1]-x[0],0), zip([0,8,4], map(int,south.__version__.split(\".\"))))) > 0" | python 2>/dev/null | grep True >/dev/null; then
echo -e "This program needs South 0.8.4. Please install with\n\npip install south==0.8.4\n"
return 2
fi
return 0
}
# read command line parameters
if [ -n "$BASH_SOURCE" ] ; then
TOASTER=${BASH_SOURCE}
elif [ -n "$ZSH_NAME" ] ; then
TOASTER=${(%):-%x}
else
TOASTER=$0
fi
export BBBASEDIR=`dirname $TOASTER`/..
MANAGE="python3 $BBBASEDIR/lib/toaster/manage.py"
if [ -z "$OE_ROOT" ]; then
OE_ROOT=`dirname $TOASTER`/../..
fi
# this is the configuraton file we are using for toaster
# we are using the same logic that oe-setup-builddir uses
# (based on TEMPLATECONF and .templateconf) to determine
# which toasterconf.json to use.
# note: There are a number of relative path assumptions
# in the local layers that currently make using an arbitrary
# toasterconf.json difficult.
. $OE_ROOT/.templateconf
if [ -n "$TEMPLATECONF" ]; then
if [ ! -d "$TEMPLATECONF" ]; then
# Allow TEMPLATECONF=meta-xyz/conf as a shortcut
if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then
TEMPLATECONF="$OE_ROOT/$TEMPLATECONF"
fi
fi
fi
unset OE_ROOT
BBBASEDIR=`dirname ${BASH_SOURCE}`/..
RUNNING=0
NOTOASTERUI=0
WEBSERVER=1
export TOASTER_BUILDSERVER=1
ADDR_PORT="localhost:8000"
TOASTERDIR=`dirname $BUILDDIR`
unset CMD
TOASTER_BRBE=""
WEB_PORT="8000"
for param in $*; do
case $param in
noui )
NOTOASTERUI=1
;;
noweb )
WEBSERVER=0
;;
nobuild )
TOASTER_BUILDSERVER=0
;;
start )
CMD=$param
;;
stop )
CMD=$param
brbe=* )
TOASTER_BRBE=$'\n'"TOASTER_BRBE=\""${param#*=}"\""
;;
webport=*)
ADDR_PORT="${param#*=}"
# Split the addr:port string
ADDR=`echo $ADDR_PORT | cut -f 1 -d ':'`
PORT=`echo $ADDR_PORT | cut -f 2 -d ':'`
# If only a port has been speified then set address to localhost.
if [ $ADDR = $PORT ] ; then
ADDR_PORT="localhost:$PORT"
fi
;;
toasterdir=*)
TOASTERDIR="${param#*=}"
;;
--help)
echo "$HELP"
return 0
;;
*)
echo "$HELP"
return 1
;;
WEB_PORT="${param#*=}"
esac
done
if [ `basename \"$0\"` = `basename \"${TOASTER}\"` ]; then
echo "Error: This script needs to be sourced. Please run as . $TOASTER"
return 1
if [ -z "$ZSH_NAME" ] && [ `basename \"$0\"` = `basename \"$BASH_SOURCE\"` ]; then
# We are called as standalone. We refuse to run in a build environment - we need the interactive mode for that.
# Start just the web server, point the web browser to the interface, and start any Django services.
if ! verify_prereq; then
echo -e "Error: Could not verify that the needed dependencies are installed. Please use virtualenv and pip to install dependencies listed in toaster-requirements.txt" 1>&2;
exit 1;
fi
if [ -n "$BUILDDIR" ]; then
echo -e "Error: It looks like you sourced oe-init-build-env. Toaster cannot start in build mode from an oe-core build environment.\n You should be starting Toaster from a new terminal window." 1>&2;
exit 1;
fi
if [ "x`which daemon`" == "x" ]; then
echo -e "Failed dependency; toaster needs the 'daemon' program in order to be able to start builds'. Please install the 'daemon' program from your distribution repositories or http://www.libslack.org/daemon/" 1>&2;
exit 1;
fi
# Define a fake builddir where only the pid files are actually created. No real builds will take place here.
BUILDDIR=/tmp/toaster_$$
if [ -d "$BUILDDIR" ]; then
echo -e "Previous toaster run directory $BUILDDIR found, cowardly refusing to start. Please remove the directory when that toaster instance is over" 2>&1
exit 1;
fi
mkdir -p "$BUILDDIR"
RUNNING=1
function trap_ctrlc() {
echo "** Stopping system"
webserverKillAll
RUNNING=0
}
function do_cleanup() {
find "$BUILDDIR" -type f | xargs rm
rmdir "$BUILDDIR"
}
function cleanup() {
if grep -ir error "$BUILDDIR" >/dev/null; then
if grep -irn "That port is already in use" "$BUILDDIR"; then
echo "You can use the \"webport=PORTNUMBER\" parameter to start Toaster on a different port (port $WEB_PORT is already in use)"
do_cleanup
else
echo -e "\nErrors found in the Toaster log files present in '$BUILDDIR'. Directory will not be cleaned.\n Please review the errors and notify toaster@yoctoproject.org or submit a bug https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Toaster"
fi
else
echo "No errors found, removing the run directory '$BUILDDIR'"
do_cleanup
fi;
}
TOASTER_MANAGED=1
export TOASTER_MANAGED=1
if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then
echo "Failed to start the web server, stopping" 1>&2;
cleanup
exit 1;
fi
if [ $WEBSERVER -gt 0 ]; then
echo "Starting browser..."
xdg-open http://127.0.0.1:$WEB_PORT/ >/dev/null 2>&1 &
fi
trap trap_ctrlc SIGINT
echo "Toaster is now running. You can stop it with Ctrl-C"
while [ $RUNNING -gt 0 ]; do
python $BBBASEDIR/lib/toaster/manage.py runbuilds 2>&1 | tee -a "$BUILDDIR/toaster.log"
sleep 1
done
cleanup
echo "**** Exit"
exit 0
fi
if ! verify_prereq; then
echo -e "Error: Could not verify that the needed dependencies are installed. Please use virtualenv and pip to install dependencies listed in toaster-requirements.txt" 1>&2;
return 1;
fi
verify_prereq || return 1
# We make sure we're running in the current shell and in a good environment
if [ -z "$BUILDDIR" ] || ! which bitbake >/dev/null 2>&1 ; then
echo "Error: Build environment is not setup or bitbake is not in path." 1>&2
if [ -z "$BUILDDIR" ] || [ -z `which bitbake` ]; then
echo "Error: Build environment is not setup or bitbake is not in path." 1>&2;
return 2
fi
# this defines the dir toaster will use for
# 1) clones of layers (in _toaster_clones )
# 2) the build dir (in build)
# 3) the sqlite db if that is being used.
# 4) pid's we need to clean up on exit/shutdown
export TOASTER_DIR=$TOASTERDIR
export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE TOASTER_DIR"
# Determine the action. If specified by arguments, fine, if not, toggle it
if [ "$CMD" = "start" ] ; then
if [ -n "$BBSERVER" ]; then
echo " Toaster is already running. Exiting..."
return 1
fi
elif [ "$CMD" = "" ]; then
echo "No command specified"
echo "$HELP"
return 1
if [ "x$1" == "xstart" ] || [ "x$1" == "xstop" ]; then
CMD="$1"
else
if [ -z "$BBSERVER" ]; then
CMD="start"
else
CMD="stop"
fi;
fi
echo "The system will $CMD."
# Make sure it's safe to run by checking bitbake lock
lock=1
if [ -e $BUILDDIR/bitbake.lock ]; then
(flock -n 200 ) 200<$BUILDDIR/bitbake.lock || lock=0
fi
if [ ${CMD} == "start" ] && [ $lock -eq 0 ]; then
echo "Error: bitbake lock state error. File locks show that the system is on." 1>&2
echo "Please wait for the current build to finish, stop and then start the system again." 1>&2
return 3
fi
if [ ${CMD} == "start" ] && [ -e $BUILDDIR/.toastermain.pid ] && kill -0 `cat $BUILDDIR/.toastermain.pid`; then
echo "Warning: bitbake appears to be dead, but the Toaster web server is running. Something fishy is going on." 1>&2
echo "Cleaning up the web server to start from a clean slate."
webserverKillAll
fi
# Execute the commands
custom_extention toaster_prepend $CMD $ADDR_PORT
case $CMD in
start )
# check if addr:port is not in use
if [ "$CMD" == 'start' ]; then
if [ $WEBSERVER -gt 0 ]; then
$MANAGE checksocket "$ADDR_PORT" || return 1
fi
fi
# Create configuration file
conf=${BUILDDIR}/conf/local.conf
line='INHERIT+="toaster buildhistory"'
grep -q "$line" $conf || echo $line >> $conf
if [ $WEBSERVER -eq 0 ] ; then
# Do not update the database for "noweb" unless
# it does not yet exist
if [ ! -f "$TOASTER_DIR/toaster.sqlite" ] ; then
if ! databaseCheck; then
echo "Failed ${CMD}."
return 4
fi
fi
custom_extention noweb_start_postpend $ADDR_PORT
fi
start_success=1
addtoConfiguration toaster.conf "INHERIT+=\"toaster buildhistory\"" $TOASTER_BRBE
if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then
echo "Failed ${CMD}."
return 4
fi
export BITBAKE_UI='toasterui'
if [ $TOASTER_BUILDSERVER -eq 1 ] ; then
$MANAGE runbuilds \
</dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \
& echo $! >${BUILDDIR}/.runbuilds.pid
else
echo "Toaster build server not started."
unset BBSERVER
PREREAD=""
if [ -e ${BUILDDIR}/conf/toaster-pre.conf ]; then
rm ${BUILDDIR}/conf/toaster-pre.conf
fi
# set fail safe stop system on terminal exit
bitbake $PREREAD --postread conf/toaster.conf --server-only -t xmlrpc -B 0.0.0.0:0
if [ $? -ne 0 ]; then
start_success=0
echo "Bitbake server start failed"
else
export BBSERVER=0.0.0.0:-1
if [ $NOTOASTERUI == 0 ]; then # we start the TOASTERUI only if not inhibited
bitbake --observe-only -u toasterui >>${BUILDDIR}/toaster_ui.log 2>&1 & echo $! >${BUILDDIR}/.toasterui.pid
fi
fi
if [ $start_success -eq 1 ]; then
# set fail safe stop system on terminal exit
trap stop_system SIGHUP
echo "Successful ${CMD}."
return 0
else
# failed start, do stop
stop_system
echo "Failed ${CMD}."
return 1
fi
# stop system on terminal exit
set -o monitor
trap stop_system SIGHUP
echo "Successful ${CMD}."
custom_extention toaster_postpend $CMD $ADDR_PORT
return 0
#trap notify_chldexit SIGCHLD
;;
stop )
stop_system
echo "Successful ${CMD}."
;;
esac
custom_extention toaster_postpend $CMD $ADDR_PORT

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
@@ -21,106 +21,159 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
This command takes a filename as a single parameter. The filename is read
as a build eventlog, and the ToasterUI is used to process events in the file
and log data in the database
"""
# This command takes a filename as a single parameter. The filename is read
# as a build eventlog, and the ToasterUI is used to process events in the file
# and log data in the database
import os
import sys
import json
import pickle
import codecs
from collections import namedtuple
import sys, logging
# mangle syspath to allow easy import of modules
from os.path import join, dirname, abspath
sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'lib'))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'lib'))
import bb.cooker
from bb.ui import toasterui
import sys
import logging
class EventPlayer:
"""Emulate a connection to a bitbake server."""
logger = logging.getLogger(__name__)
console = logging.StreamHandler(sys.stdout)
format_str = "%(levelname)s: %(message)s"
logging.basicConfig(format=format_str)
def __init__(self, eventfile, variables):
self.eventfile = eventfile
self.variables = variables
self.eventmask = []
def waitEvent(self, _timeout):
"""Read event from the file."""
line = self.eventfile.readline().strip()
if not line:
return
try:
event_str = json.loads(line)['vars'].encode('utf-8')
event = pickle.loads(codecs.decode(event_str, 'base64'))
event_name = "%s.%s" % (event.__module__, event.__class__.__name__)
if event_name not in self.eventmask:
return
return event
except ValueError as err:
print("Failed loading ", line)
raise err
import json, pickle
def runCommand(self, command_line):
"""Emulate running a command on the server."""
name = command_line[0]
if name == "getVariable":
var_name = command_line[1]
variable = self.variables.get(var_name)
if variable:
return variable['v'], None
return None, "Missing variable %s" % var_name
class FileReadEventsServerConnection():
""" Emulates a connection to a bitbake server that feeds
events coming actually read from a saved log file.
"""
elif name == "getAllKeysWithFlags":
dump = {}
flaglist = command_line[1]
for key, val in self.variables.items():
try:
if not key.startswith("__"):
dump[key] = {
'v': val['v'],
'history' : val['history'],
}
for flag in flaglist:
dump[key][flag] = val[flag]
except Exception as err:
print(err)
return (dump, None)
elif name == 'setEventMask':
self.eventmask = command_line[-1]
return True, None
else:
raise Exception("Command %s not implemented" % command_line[0])
def getEventHandle(self):
class MockConnection():
""" fill-in for the proxy to the server. we just return generic data
"""
This method is called by toasterui.
The return value is passed to self.runCommand but not used there.
"""
pass
def __init__(self, sc):
self._sc = sc
def main(argv):
with open(argv[-1]) as eventfile:
# load variables from the first line
variables = json.loads(eventfile.readline().strip())['allvariables']
def runCommand(self, commandArray):
""" emulates running a command on the server; only read-only commands are accepted """
command_name = commandArray[0]
params = namedtuple('ConfigParams', ['observe_only'])(True)
player = EventPlayer(eventfile, variables)
if command_name == "getVariable":
if commandArray[1] in self._sc._variables:
return (self._sc._variables[commandArray[1]]['v'], None)
return (None, "Missing variable")
elif command_name == "getAllKeysWithFlags":
dump = {}
flaglist = commandArray[1]
for k in self._sc._variables.keys():
try:
if not k.startswith("__"):
v = self._sc._variables[k]['v']
dump[k] = {
'v' : v ,
'history' : self._sc._variables[k]['history'],
}
for d in flaglist:
dump[k][d] = self._sc._variables[k][d]
except Exception as e:
print(e)
return (dump, None)
else:
raise Exception("Command %s not implemented" % commandArray[0])
def terminateServer(self):
""" do not do anything """
pass
class EventReader():
def __init__(self, sc):
self._sc = sc
self.firstraise = 0
def _create_event(self, line):
def _import_class(name):
assert len(name) > 0
assert "." in name, name
components = name.strip().split(".")
modulename = ".".join(components[:-1])
moduleklass = components[-1]
module = __import__(modulename, fromlist=[str(moduleklass)])
return getattr(module, moduleklass)
# we build a toaster event out of current event log line
try:
event_data = json.loads(line.strip())
event_class = _import_class(event_data['class'])
event_object = pickle.loads(json.loads(event_data['vars']))
except ValueError as e:
print("Failed loading ", line)
raise e
if not isinstance(event_object, event_class):
raise Exception("Error loading objects %s class %s ", event_object, event_class)
return event_object
def waitEvent(self, timeout):
nextline = self._sc._eventfile.readline()
if len(nextline) == 0:
# the build data ended, while toasterui still waits for events.
# this happens when the server was abruptly stopped, so we simulate this
self.firstraise += 1
if self.firstraise == 1:
raise KeyboardInterrupt()
else:
return None
else:
self._sc.lineno += 1
return self._create_event(nextline)
def _readVariables(self, variableline):
self._variables = json.loads(variableline.strip())['allvariables']
def __init__(self, file_name):
self.connection = FileReadEventsServerConnection.MockConnection(self)
self._eventfile = open(file_name, "r")
# we expect to have the variable dump at the start of the file
self.lineno = 1
self._readVariables(self._eventfile.readline())
self.events = FileReadEventsServerConnection.EventReader(self)
class MockConfigParameters():
""" stand-in for cookerdata.ConfigParameters; as we don't really config a cooker, this
serves just to supply needed interfaces for the toaster ui to work """
def __init__(self):
self.observe_only = True # we can only read files
return toasterui.main(player, player, params)
# run toaster ui on our mock bitbake class
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: %s <event file>" % os.path.basename(sys.argv[0]))
if len(sys.argv) < 2:
logger.error("Usage: %s event.log " % sys.argv[0])
sys.exit(1)
sys.exit(main(sys.argv))
file_name = sys.argv[-1]
mock_connection = FileReadEventsServerConnection(file_name)
configParams = MockConfigParameters()
# run the main program
toasterui.main(mock_connection.connection, mock_connection.events, configParams)

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2012, 2018 Wind River Systems, Inc.
# Copyright (C) 2012 Wind River Systems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -18,68 +18,51 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Used for dumping the bb_cache.dat
# This is used for dumping the bb_cache.dat, the output format is:
# recipe_path PN PV PACKAGES
#
import os
import sys
import argparse
import warnings
# For importing bb.cache
sys.path.insert(0, os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), '../lib'))
from bb.cache import CoreRecipeInfo
import pickle
import cPickle as pickle
class DumpCache(object):
def __init__(self):
parser = argparse.ArgumentParser(
description="bb_cache.dat's dumper",
epilog="Use %(prog)s --help to get help")
parser.add_argument("-r", "--recipe",
help="specify the recipe, default: all recipes", action="store")
parser.add_argument("-m", "--members",
help = "specify the member, use comma as separator for multiple ones, default: all members", action="store", default="")
parser.add_argument("-s", "--skip",
help = "skip skipped recipes", action="store_true")
parser.add_argument("cachefile",
help = "specify bb_cache.dat", nargs = 1, action="store", default="")
def main(argv=None):
"""
Get the mapping for the target recipe.
"""
if len(argv) != 1:
print >>sys.stderr, "Error, need one argument!"
return 2
self.args = parser.parse_args()
cachefile = argv[0]
def main(self):
with open(self.args.cachefile[0], "rb") as cachefile:
pickled = pickle.Unpickler(cachefile)
while True:
try:
key = pickled.load()
val = pickled.load()
except Exception:
break
if isinstance(val, CoreRecipeInfo):
pn = val.pn
with open(cachefile, "rb") as cachefile:
pickled = pickle.Unpickler(cachefile)
while cachefile:
try:
key = pickled.load()
val = pickled.load()
except Exception:
break
if isinstance(val, CoreRecipeInfo) and (not val.skipped):
pn = val.pn
# Filter out the native recipes.
if key.startswith('virtual:native:') or pn.endswith("-native"):
continue
if self.args.recipe and self.args.recipe != pn:
continue
# 1.0 is the default version for a no PV recipe.
if val.__dict__.has_key("pv"):
pv = val.pv
else:
pv = "1.0"
if self.args.skip and val.skipped:
continue
if self.args.members:
out = key
for member in self.args.members.split(','):
out += ": %s" % val.__dict__.get(member)
print("%s" % out)
else:
print("%s: %s" % (key, val.__dict__))
elif not self.args.recipe:
print("%s %s" % (key, val))
print("%s %s %s %s" % (key, pn, pv, ' '.join(val.packages)))
if __name__ == "__main__":
try:
dump = DumpCache()
ret = dump.main()
except Exception as esc:
ret = 1
import traceback
traceback.print_exc()
sys.exit(ret)
sys.exit(main(sys.argv[1:]))

View File

@@ -1,15 +1,7 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
<!--
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
<xsl:import href="http://docbook.sourceforge.net/release/xsl/1.76.1/xhtml/docbook.xsl" />
-->
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl" />
<xsl:include href="../template/permalinks.xsl"/>
<xsl:include href="../template/section.title.xsl"/>

View File

@@ -21,7 +21,7 @@
The execution process is launched using the following command
form:
<literallayout class='monospaced'>
$ bitbake <replaceable>target</replaceable>
$ bitbake &lt;target&gt;
</literallayout>
For information on the BitBake command and its options,
see
@@ -37,16 +37,14 @@
</para>
<para>
A common method to determine this value for your build host is to run
the following:
A common way to determine this value for your build host is to run:
<literallayout class='monospaced'>
$ grep processor /proc/cpuinfo
</literallayout>
This command returns the number of processors, which takes into
account hyper-threading.
Thus, a quad-core build host with hyper-threading most likely
shows eight processors, which is the value you would then assign to
<filename>BB_NUMBER_THREADS</filename>.
and count the number of processors displayed. Note that the number of
processors will take into account hyper-threading, so that a quad-core
build host with hyper-threading will most likely show eight processors,
which is the value you would then assign to that variable.
</para>
<para>
@@ -116,35 +114,16 @@
Prior to parsing configuration files, Bitbake looks
at certain variables, including:
<itemizedlist>
<listitem><para>
<link linkend='var-BB_ENV_WHITELIST'><filename>BB_ENV_WHITELIST</filename></link>
</para></listitem>
<listitem><para>
<link linkend='var-BB_ENV_EXTRAWHITE'><filename>BB_ENV_EXTRAWHITE</filename></link>
</para></listitem>
<listitem><para>
<link linkend='var-BB_PRESERVE_ENV'><filename>BB_PRESERVE_ENV</filename></link>
</para></listitem>
<listitem><para>
<link linkend='var-BB_ORIGENV'><filename>BB_ORIGENV</filename></link>
</para></listitem>
<listitem><para><link linkend='var-BB_ENV_WHITELIST'><filename>BB_ENV_WHITELIST</filename></link></para></listitem>
<listitem><para><link linkend='var-BB_PRESERVE_ENV'><filename>BB_PRESERVE_ENV</filename></link></para></listitem>
<listitem><para><link linkend='var-BB_ENV_EXTRAWHITE'><filename>BB_ENV_EXTRAWHITE</filename></link></para></listitem>
<listitem><para>
<link linkend='var-BITBAKE_UI'><filename>BITBAKE_UI</filename></link>
</para></listitem>
</itemizedlist>
The first four variables in this list relate to how BitBake treats shell
environment variables during task execution.
By default, BitBake cleans the environment variables and provides tight
control over the shell execution environment.
However, through the use of these first four variables, you can
apply your control regarding the
environment variables allowed to be used by BitBake in the shell
during execution of tasks.
See the
"<link linkend='passing-information-into-the-build-task-environment'>Passing Information Into the Build Task Environment</link>"
section and the information about these variables in the
variable glossary for more information on how they work and
on how to use them.
You can find information on how to pass environment variables into the BitBake
execution environment in the
"<link linkend='passing-information-into-the-build-task-environment'>Passing Information Into the Build Task Environment</link>" section.
</para>
<para>
@@ -306,8 +285,8 @@
<link linkend='var-PN'><filename>PN</filename></link> and
<link linkend='var-PV'><filename>PV</filename></link>:
<literallayout class='monospaced'>
PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
PV = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[1] or '1.0'}"
PN = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE'),d)[0] or 'defaultpkgname'}"
PV = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE'),d)[1] or '1.0'}"
</literallayout>
In this example, a recipe called "something_1.2.3.bb" would set
<filename>PN</filename> to "something" and
@@ -596,7 +575,7 @@
"<link linkend='checksums'>Checksums (Signatures)</link>"
section for information).
It is also possible to append extra metadata to the stamp using
the <filename>[stamp-extra-info]</filename> task flag.
the "stamp-extra-info" task flag.
For example, OpenEmbedded uses this flag to make some tasks machine-specific.
</para>
@@ -653,8 +632,7 @@
</itemizedlist>
It is possible to have functions run before and after a task's main
function.
This is done using the <filename>[prefuncs]</filename>
and <filename>[postfuncs]</filename> flags of the task
This is done using the "prefuncs" and "postfuncs" flags of the task
that lists the functions to run.
</para>
</section>
@@ -781,7 +759,7 @@
The code in <filename>meta/lib/oe/sstatesig.py</filename> shows two examples
of this and also illustrates how you can insert your own policy into the system
if so desired.
This file defines the two basic signature generators OpenEmbedded-Core
This file defines the two basic signature generators OpenEmbedded Core
uses: "OEBasic" and "OEBasicHash".
By default, there is a dummy "noop" signature handler enabled in BitBake.
This means that behavior is unchanged from previous versions.
@@ -804,13 +782,13 @@
make some dependency and hash information available to the build.
This information includes:
<itemizedlist>
<listitem><para><filename>BB_BASEHASH_task-</filename><replaceable>taskname</replaceable>:
<listitem><para><filename>BB_BASEHASH_task-&lt;taskname&gt;</filename>:
The base hashes for each task in the recipe.
</para></listitem>
<listitem><para><filename>BB_BASEHASH_</filename><replaceable>filename</replaceable><filename>:</filename><replaceable>taskname</replaceable>:
<listitem><para><filename>BB_BASEHASH_&lt;filename:taskname&gt;</filename>:
The base hashes for each dependent task.
</para></listitem>
<listitem><para><filename>BBHASHDEPS_</filename><replaceable>filename</replaceable><filename>:</filename><replaceable>taskname</replaceable>:
<listitem><para><filename>BBHASHDEPS_&lt;filename:taskname&gt;</filename>:
The task dependencies for each task.
</para></listitem>
<listitem><para><filename>BB_TASKHASH</filename>:
@@ -828,7 +806,7 @@
itself.
The simplest parameter to pass is "none", which causes a
set of signature information to be written out into
<filename>STAMPS_DIR</filename>
<filename>STAMP_DIR</filename>
corresponding to the targets specified.
The other currently available parameter is "printdiff",
which causes BitBake to try to establish the closest
@@ -916,7 +894,7 @@
<para>
Finally, after all the setscene tasks have executed, BitBake calls the
function listed in
<link linkend='var-BB_SETSCENE_VERIFY_FUNCTION2'><filename>BB_SETSCENE_VERIFY_FUNCTION2</filename></link>
<link linkend='var-BB_SETSCENE_VERIFY_FUNCTION'><filename>BB_SETSCENE_VERIFY_FUNCTION</filename></link>
with the list of tasks BitBake thinks has been "covered".
The metadata can then ensure that this list is correct and can
inform BitBake that it wants specific tasks to be run regardless

View File

@@ -38,7 +38,7 @@
The code to execute the first part of this process, a fetch,
looks something like the following:
<literallayout class='monospaced'>
src_uri = (d.getVar('SRC_URI') or "").split()
src_uri = (d.getVar('SRC_URI', True) or "").split()
fetcher = bb.fetch2.Fetch(src_uri, d)
fetcher.download()
</literallayout>
@@ -52,7 +52,7 @@
<para>
The instantiation of the fetch class is usually followed by:
<literallayout class='monospaced'>
rootdir = l.getVar('WORKDIR')
rootdir = l.getVar('WORKDIR', True)
fetcher.unpack(rootdir)
</literallayout>
This code unpacks the downloaded files to the
@@ -157,8 +157,8 @@
<filename>SRC_URI</filename> variable with the appropriate
varflags as follows:
<literallayout class='monospaced'>
SRC_URI[md5sum] = "<replaceable>value</replaceable>"
SRC_URI[sha256sum] = "<replaceable>value</replaceable>"
SRC_URI[md5sum] = "value"
SRC_URI[sha256sum] = "value"
</literallayout>
You can also specify the checksums as parameters on the
<filename>SRC_URI</filename> as shown below:
@@ -268,6 +268,15 @@
<link linkend='var-FILESPATH'><filename>FILESPATH</filename></link>
variable is used in the same way
<filename>PATH</filename> is used to find executables.
Failing that,
<link linkend='var-FILESDIR'><filename>FILESDIR</filename></link>
is used to find the appropriate relative file.
<note>
<filename>FILESDIR</filename> is deprecated and can
be replaced with <filename>FILESPATH</filename>.
Because <filename>FILESDIR</filename> is likely to be
removed, you should not use this variable in any new code.
</note>
If the file cannot be found, it is assumed that it is available in
<link linkend='var-DL_DIR'><filename>DL_DIR</filename></link>
by the time the <filename>download()</filename> method is called.
@@ -316,25 +325,6 @@
SRC_URI = "ftp://you@oe.handhelds.org/home/you/secret.plan"
</literallayout>
</para>
<note>
Because URL parameters are delimited by semi-colons, this can
introduce ambiguity when parsing URLs that also contain semi-colons,
for example:
<literallayout class='monospaced'>
SRC_URI = "http://abc123.org/git/?p=gcc/gcc.git;a=snapshot;h=a5dd47"
</literallayout>
Such URLs should should be modified by replacing semi-colons with '&amp;' characters:
<literallayout class='monospaced'>
SRC_URI = "http://abc123.org/git/?p=gcc/gcc.git&amp;a=snapshot&amp;h=a5dd47"
</literallayout>
In most cases this should work. Treating semi-colons and '&amp;' in queries
identically is recommended by the World Wide Web Consortium (W3C).
Note that due to the nature of the URL, you may have to specify the name
of the downloaded file as well:
<literallayout class='monospaced'>
SRC_URI = "http://abc123.org/git/?p=gcc/gcc.git&amp;a=snapshot&amp;h=a5dd47;downloadfilename=myfile.bz2"
</literallayout>
</note>
</section>
<section id='cvs-fetcher'>
@@ -376,8 +366,7 @@
The supported parameters are as follows:
<itemizedlist>
<listitem><para><emphasis>"method":</emphasis>
The protocol over which to communicate with the CVS
server.
The protocol over which to communicate with the CVS server.
By default, this protocol is "pserver".
If "method" is set to "ext", BitBake examines the
"rsh" parameter and sets <filename>CVS_RSH</filename>.
@@ -461,29 +450,25 @@
You can think of this parameter as the top-level
directory of the repository data you want.
</para></listitem>
<listitem><para><emphasis>"path_spec":</emphasis>
A specific directory in which to checkout the
specified svn module.
</para></listitem>
<listitem><para><emphasis>"protocol":</emphasis>
The protocol to use, which defaults to "svn".
If "protocol" is set to "svn+ssh", the "ssh"
parameter is also used.
Other options are "svn+ssh" and "rsh".
For "rsh", the "rsh" parameter is also used.
</para></listitem>
<listitem><para><emphasis>"rev":</emphasis>
The revision of the source code to checkout.
</para></listitem>
<listitem><para><emphasis>"date":</emphasis>
The date of the source code to checkout.
Specific revisions are generally much safer to checkout
rather than by date as they do not involve timezones
(e.g. they are much more deterministic).
</para></listitem>
<listitem><para><emphasis>"scmdata":</emphasis>
Causes the “.svn” directories to be available during
compile-time when set to "keep".
By default, these directories are removed.
</para></listitem>
<listitem><para><emphasis>"ssh":</emphasis>
An optional parameter used when "protocol" is set
to "svn+ssh".
You can use this parameter to specify the ssh
program used by svn.
</para></listitem>
<listitem><para><emphasis>"transportuser":</emphasis>
When required, sets the username for the transport.
By default, this parameter is empty.
@@ -492,11 +477,10 @@
command.
</para></listitem>
</itemizedlist>
Following are three examples using svn:
Following are two examples using svn:
<literallayout class='monospaced'>
SRC_URI = "svn://myrepos/proj1;module=vip;protocol=http;rev=667"
SRC_URI = "svn://myrepos/proj1;module=opie;protocol=svn+ssh"
SRC_URI = "svn://myrepos/proj1;module=trunk;protocol=http;path_spec=${MY_DIR}/proj1"
SRC_URI = "svn://svn.oe.handhelds.org/svn;module=vip;proto=http;rev=667"
SRC_URI = "svn://svn.oe.handhelds.org/svn/;module=opie;proto=svn+ssh;date=20060126"
</literallayout>
</para>
</section>
@@ -588,14 +572,6 @@
The name of the path in which to place the checkout.
By default, the path is <filename>git/</filename>.
</para></listitem>
<listitem><para><emphasis>"usehead":</emphasis>
Enables local <filename>git://</filename> URLs to use the
current branch HEAD as the revision for use with
<filename>AUTOREV</filename>.
The "usehead" parameter implies no branch and only works
when the transfer protocol is
<filename>file://</filename>.
</para></listitem>
</itemizedlist>
Here are some example URLs:
<literallayout class='monospaced'>
@@ -628,9 +604,7 @@
The Git Submodules fetcher is not a complete fetcher
implementation.
The fetcher has known issues where it does not use the
normal source mirroring infrastructure properly. Further,
the submodule sources it fetches are not visible to the
licensing and source archiving infrastructures.
normal source mirroring infrastructure properly.
</para>
</note>
</para>
@@ -654,7 +628,7 @@
<literallayout class='monospaced'>
SRC_URI = "ccrc://cc.example.org/ccrc;vob=/example_vob;module=/example_module"
SRCREV = "EXAMPLE_CLEARCASE_TAG"
PV = "${@d.getVar("SRCREV", False).replace("/", "+")}"
PV = "${@d.getVar("SRCREV").replace("/", "+")}"
</literallayout>
The fetcher uses the <filename>rcleartool</filename> or
<filename>cleartool</filename> remote client, depending on
@@ -672,19 +646,13 @@
</para></listitem>
<listitem><para><emphasis><filename>module</filename></emphasis>:
The module, which must include the
prepending "/" character, in the selected VOB.
<note>
The <filename>module</filename> and <filename>vob</filename>
options are combined to create the <filename>load</filename> rule in
the view config spec.
As an example, consider the <filename>vob</filename> and
<filename>module</filename> values from the
<filename>SRC_URI</filename> statement at the start of this section.
Combining those values results in the following:
<literallayout class='monospaced'>
load /example_vob/example_module
</literallayout>
</note>
prepending "/" character, in the selected VOB
The <filename>module</filename> and <filename>vob</filename>
options are combined to create the following load rule in
the view config spec:
<literallayout class='monospaced'>
load &lt;vob&gt;&lt;module&gt;
</literallayout>
</para></listitem>
<listitem><para><emphasis><filename>proto</filename></emphasis>:
The protocol, which can be either <filename>http</filename> or
@@ -723,105 +691,6 @@
</para>
</section>
<section id='perforce-fetcher'>
<title>Perforce Fetcher (<filename>p4://</filename>)</title>
<para>
This fetcher submodule fetches code from the
<ulink url='https://www.perforce.com/'>Perforce</ulink>
source control system.
The executable used is specified by
<filename>FETCHCMD_p4</filename>, which defaults
to "p4".
The fetcher's temporary working directory is set by
<link linkend='var-P4DIR'><filename>P4DIR</filename></link>,
which defaults to "DL_DIR/p4".
</para>
<para>
To use this fetcher, make sure your recipe has proper
<link linkend='var-SRC_URI'><filename>SRC_URI</filename></link>,
<link linkend='var-SRCREV'><filename>SRCREV</filename></link>, and
<link linkend='var-PV'><filename>PV</filename></link> values.
The p4 executable is able to use the config file defined by your
system's <filename>P4CONFIG</filename> environment variable in
order to define the Perforce server URL and port, username, and
password if you do not wish to keep those values in a recipe
itself.
If you choose not to use <filename>P4CONFIG</filename>,
or to explicitly set variables that <filename>P4CONFIG</filename>
can contain, you can specify the <filename>P4PORT</filename> value,
which is the server's URL and port number, and you can
specify a username and password directly in your recipe within
<filename>SRC_URI</filename>.
</para>
<para>
Here is an example that relies on <filename>P4CONFIG</filename>
to specify the server URL and port, username, and password, and
fetches the Head Revision:
<literallayout class='monospaced'>
SRC_URI = "p4://example-depot/main/source/..."
SRCREV = "${AUTOREV}"
PV = "p4-${SRCPV}"
S = "${WORKDIR}/p4"
</literallayout>
</para>
<para>
Here is an example that specifies the server URL and port,
username, and password, and fetches a Revision based on a Label:
<literallayout class='monospaced'>
P4PORT = "tcp:p4server.example.net:1666"
SRC_URI = "p4://user:passwd@example-depot/main/source/..."
SRCREV = "release-1.0"
PV = "p4-${SRCPV}"
S = "${WORKDIR}/p4"
</literallayout>
<note>
You should always set <filename>S</filename>
to <filename>"${WORKDIR}/p4"</filename> in your recipe.
</note>
</para>
</section>
<section id='repo-fetcher'>
<title>Repo Fetcher (<filename>repo://</filename>)</title>
<para>
This fetcher submodule fetches code from
<filename>google-repo</filename> source control system.
The fetcher works by initiating and syncing sources of the
repository into
<link linkend='var-REPODIR'><filename>REPODIR</filename></link>,
which is usually
<link linkend='var-DL_DIR'><filename>DL_DIR</filename></link><filename>/repo</filename>.
</para>
<para>
This fetcher supports the following parameters:
<itemizedlist>
<listitem><para>
<emphasis>"protocol":</emphasis>
Protocol to fetch the repository manifest (default: git).
</para></listitem>
<listitem><para>
<emphasis>"branch":</emphasis>
Branch or tag of repository to get (default: master).
</para></listitem>
<listitem><para>
<emphasis>"manifest":</emphasis>
Name of the manifest file (default: <filename>default.xml</filename>).
</para></listitem>
</itemizedlist>
Here are some example URLs:
<literallayout class='monospaced'>
SRC_URI = "repo://REPOROOT;protocol=git;branch=some_branch;manifest=my_manifest.xml"
SRC_URI = "repo://REPOROOT;protocol=file;branch=some_branch;manifest=my_manifest.xml"
</literallayout>
</para>
</section>
<section id='other-fetchers'>
<title>Other Fetchers</title>
@@ -831,6 +700,9 @@
<listitem><para>
Bazaar (<filename>bzr://</filename>)
</para></listitem>
<listitem><para>
Perforce (<filename>p4://</filename>)
</para></listitem>
<listitem><para>
Trees using Git Annex (<filename>gitannex://</filename>)
</para></listitem>
@@ -840,6 +712,9 @@
<listitem><para>
Secure Shell (<filename>ssh://</filename>)
</para></listitem>
<listitem><para>
Repo (<filename>repo://</filename>)
</para></listitem>
<listitem><para>
OSC (<filename>osc://</filename>)
</para></listitem>

View File

@@ -47,6 +47,7 @@
-rw-rw-r--. 1 wmat wmat 849 Nov 26 04:55 HEADER
drwxrwxr-x. 5 wmat wmat 4096 Jan 31 13:44 lib
-rw-rw-r--. 1 wmat wmat 195 Nov 26 04:55 MANIFEST.in
-rwxrwxr-x. 1 wmat wmat 3195 Jan 31 11:57 setup.py
-rw-rw-r--. 1 wmat wmat 2887 Nov 26 04:55 TODO
</literallayout>
</para>
@@ -128,8 +129,15 @@
</para>
<note>
This example was inspired by and drew heavily from
<ulink url="http://www.mail-archive.com/yocto@yoctoproject.org/msg09379.html">Mailing List post - The BitBake equivalent of "Hello, World!"</ulink>.
This example was inspired by and drew heavily from these sources:
<itemizedlist>
<listitem><para>
<ulink url="http://www.mail-archive.com/yocto@yoctoproject.org/msg09379.html">Mailing List post - The BitBake equivalent of "Hello, World!"</ulink>
</para></listitem>
<listitem><para>
<ulink url="https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/">Hambedded Linux blog post - From Bitbake Hello World to an Image</ulink>
</para></listitem>
</itemizedlist>
</note>
<para>
@@ -213,7 +221,7 @@
<para>From your shell, enter the following commands to set and
export the <filename>BBPATH</filename> variable:
<literallayout class='monospaced'>
$ BBPATH="<replaceable>projectdirectory</replaceable>"
$ BBPATH="&lt;projectdirectory&gt;"
$ export BBPATH
</literallayout>
Use your actual project directory in the command.
@@ -260,9 +268,9 @@
files.
For this example, you need to create the file in your project directory
and define some key BitBake variables.
For more information on the <filename>bitbake.conf</filename> file,
For more information on the <filename>bitbake.conf</filename>,
see
<ulink url='http://git.openembedded.org/bitbake/tree/conf/bitbake.conf'></ulink>.
<ulink url='https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/#an-overview-of-bitbakeconf'></ulink>
</para>
<para>Use the following commands to create the <filename>conf</filename>
directory in the project directory:
@@ -273,32 +281,14 @@
some editor to create the <filename>bitbake.conf</filename>
so that it contains the following:
<literallayout class='monospaced'>
<link linkend='var-PN'>PN</link> = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
</literallayout>
<literallayout class='monospaced'>
TMPDIR = "${<link linkend='var-TOPDIR'>TOPDIR</link>}/tmp"
<link linkend='var-CACHE'>CACHE</link> = "${TMPDIR}/cache"
<link linkend='var-STAMP'>STAMP</link> = "${TMPDIR}/${PN}/stamps"
<link linkend='var-T'>T</link> = "${TMPDIR}/${PN}/work"
<link linkend='var-B'>B</link> = "${TMPDIR}/${PN}"
<link linkend='var-STAMP'>STAMP</link> = "${TMPDIR}/stamps"
<link linkend='var-T'>T</link> = "${TMPDIR}/work"
<link linkend='var-B'>B</link> = "${TMPDIR}"
</literallayout>
<note>
Without a value for <filename>PN</filename>, the
variables <filename>STAMP</filename>,
<filename>T</filename>, and <filename>B</filename>,
prevent more than one recipe from working. You can fix
this by either setting <filename>PN</filename> to have
a value similar to what OpenEmbedded and BitBake use
in the default <filename>bitbake.conf</filename> file
(see previous example). Or, by manually updating each
recipe to set <filename>PN</filename>. You will also
need to include <filename>PN</filename> as part of the
<filename>STAMP</filename>, <filename>T</filename>, and
<filename>B</filename> variable definitions in the
<filename>local.conf</filename> file.
</note>
The <filename>TMPDIR</filename> variable establishes a directory
that BitBake uses for build output and intermediate files other
that BitBake uses for build output and intermediate files (other
than the cached information used by the
<link linkend='setscene'>Setscene</link> process.
Here, the <filename>TMPDIR</filename> directory is set to
@@ -318,19 +308,19 @@
file exists, you can run the <filename>bitbake</filename>
command again:
<literallayout class='monospaced'>
$ bitbake
ERROR: Traceback (most recent call last):
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
return func(fn, *args)
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit
bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit
include(fn, file, lineno, d, "inherit")
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
$ bitbake
ERROR: Traceback (most recent call last):
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
return func(fn, *args)
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit
bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit
include(fn, file, lineno, d, "inherit")
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
</literallayout>
In the sample output, BitBake could not find the
<filename>classes/base.bbclass</filename> file.
@@ -363,6 +353,9 @@
Of course, the <filename>base.bbclass</filename> can have much
more depending on which build environments BitBake is
supporting.
For more information on the <filename>base.bbclass</filename> file,
you can look at
<ulink url='https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/#tasks'></ulink>.
</para></listitem>
<listitem><para><emphasis>Run Bitbake:</emphasis>
After making sure that the <filename>classes/base.bbclass</filename>
@@ -383,10 +376,10 @@
code separate from the general metadata used by BitBake.
Thus, this example creates and uses a layer called "mylayer".
<note>
You can find additional information on layers in the
"<link linkend='layers'>Layers</link>" section.
</note></para>
You can find additional information on adding a layer at
<ulink url='https://web.archive.org/web/20150325165911/http://hambedded.org/blog/2012/11/24/from-bitbake-hello-world-to-an-image/#adding-an-example-layer'></ulink>.
</note>
</para>
<para>Minimally, you need a recipe file and a layer configuration
file in your layer.
The configuration file needs to be in the <filename>conf</filename>
@@ -407,7 +400,7 @@
<link linkend='var-BBFILES'>BBFILES</link> += "${LAYERDIR}/*.bb"
<link linkend='var-BBFILE_COLLECTIONS'>BBFILE_COLLECTIONS</link> += "mylayer"
<link linkend='var-BBFILE_PATTERN'>BBFILE_PATTERN_mylayer</link> := "^${LAYERDIR_RE}/"
<link linkend='var-BBFILE_PATTERN'>BBFILE_PATTERN_mylayer</link> := "^${LAYERDIR}/"
</literallayout>
For information on these variables, click the links
to go to the definitions in the glossary.</para>

View File

@@ -440,7 +440,7 @@
Build Checkout:</emphasis>
A final possibility for getting a copy of BitBake is that it
already comes with your checkout of a larger Bitbake-based build
system, such as Poky.
system, such as Poky or Yocto Project.
Rather than manually checking out individual layers and
gluing them together yourself, you can check
out an entire build system.
@@ -471,7 +471,7 @@
Following is the usage and syntax for BitBake:
<literallayout class='monospaced'>
$ bitbake -h
Usage: bitbake [options] [recipename/target recipe:do_task ...]
Usage: bitbake [options] [recipename/target ...]
Executes the specified task (default is 'build') for a given set of target recipes (.bb files).
It is assumed there is a conf/bblayers.conf available in cwd or in BBPATH which
@@ -488,6 +488,8 @@
target that failed and anything depending on it cannot
be built, as much as possible will be built before
stopping.
-a, --tryaltconfigs Continue with builds by trying to use alternative
providers where possible.
-f, --force Force the specified targets/task to run (invalidating
any existing stamp file).
-c CMD, --cmd=CMD Specify the task to execute. The exact options
@@ -502,20 +504,9 @@
Read the specified file before bitbake.conf.
-R POSTFILE, --postread=POSTFILE
Read the specified file after bitbake.conf.
-v, --verbose Enable tracing of shell tasks (with 'set -x'). Also
print bb.note(...) messages to stdout (in addition to
writing them to ${T}/log.do_&lt;task&gt;).
-v, --verbose Output more log message data to the terminal.
-D, --debug Increase the debug level. You can specify this more
than once. -D sets the debug level to 1, where only
bb.debug(1, ...) messages are printed to stdout; -DD
sets the debug level to 2, where both bb.debug(1, ...)
and bb.debug(2, ...) messages are printed; etc.
Without -D, no debug messages are printed. Note that
-D only affects output to stdout. All debug messages
are written to ${T}/log.do_taskname, regardless of the
debug level.
-q, --quiet Output less log message data to the terminal. You can
specify this more than once.
than once.
-n, --dry-run Don't execute, just go through the motions.
-S SIGNATURE_HANDLER, --dump-signatures=SIGNATURE_HANDLER
Dump out the signature construction information, with
@@ -538,38 +529,23 @@
-l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS
Show debug logging for the specified logging domains
-P, --profile Profile the command and save reports.
-u UI, --ui=UI The user interface to use (knotty, ncurses or taskexp
- default knotty).
-u UI, --ui=UI The user interface to use (e.g. knotty, hob, depexp).
-t SERVERTYPE, --servertype=SERVERTYPE
Choose which server to use, process or xmlrpc.
--token=XMLRPCTOKEN Specify the connection token to be used when
connecting to a remote server.
--revisions-changed Set the exit code depending on whether upstream
floating revisions have changed or not.
--server-only Run bitbake without a UI, only starting a server
(cooker) process.
-B BIND, --bind=BIND The name/address for the bitbake xmlrpc server to bind
to.
-T SERVER_TIMEOUT, --idle-timeout=SERVER_TIMEOUT
Set timeout to unload bitbake server due to
inactivity, set to -1 means no unload, default:
Environment variable BB_SERVER_TIMEOUT.
-B BIND, --bind=BIND The name/address for the bitbake server to bind to.
--no-setscene Do not run any setscene tasks. sstate will be ignored
and everything needed, built.
--setscene-only Only run setscene tasks, don't run any real tasks.
--remote-server=REMOTE_SERVER
Connect to the specified server.
-m, --kill-server Terminate any running bitbake server.
-m, --kill-server Terminate the remote server.
--observe-only Connect to a server as an observing-only client.
--status-only Check the status of the remote bitbake server.
-w WRITEEVENTLOG, --write-log=WRITEEVENTLOG
Writes the event log of the build to a bitbake event
json file. Use '' (empty string) to assign the name
automatically.
--runall=RUNALL Run the specified task for any recipe in the taskgraph
of the specified target (even if it wouldn't otherwise
have run).
--runonly=RUNONLY Run only the specified task within the taskgraph of
the specified targets (and any task dependencies those
tasks may have).
</literallayout>
</para>
</section>
@@ -652,25 +628,6 @@
</para>
</section>
<section id='executing-a-list-of-task-and-recipe-combinations'>
<title>Executing a List of Task and Recipe Combinations</title>
<para>
The BitBake command line supports specifying different
tasks for individual targets when you specify multiple
targets.
For example, suppose you had two targets (or recipes)
<filename>myfirstrecipe</filename> and
<filename>mysecondrecipe</filename> and you needed
BitBake to run <filename>taskA</filename> for the first
recipe and <filename>taskB</filename> for the second
recipe:
<literallayout class='monospaced'>
$ bitbake myfirstrecipe:do_taskA mysecondrecipe:do_taskB
</literallayout>
</para>
</section>
<section id='generating-dependency-graphs'>
<title>Generating Dependency Graphs</title>
@@ -683,21 +640,21 @@
</para>
<para>
When you generate a dependency graph, BitBake writes three files
When you generate a dependency graph, BitBake writes four files
to the current working directory:
<itemizedlist>
<listitem><para>
<emphasis><filename>recipe-depends.dot</filename>:</emphasis>
Shows dependencies between recipes (i.e. a collapsed version of
<filename>task-depends.dot</filename>).
<listitem><para><emphasis><filename>package-depends.dot</filename>:</emphasis>
Shows BitBake's knowledge of dependencies between
runtime targets.
</para></listitem>
<listitem><para>
<emphasis><filename>task-depends.dot</filename>:</emphasis>
<listitem><para><emphasis><filename>pn-depends.dot</filename>:</emphasis>
Shows dependencies between build-time targets
(i.e. recipes).
</para></listitem>
<listitem><para><emphasis><filename>task-depends.dot</filename>:</emphasis>
Shows dependencies between tasks.
These dependencies match BitBake's internal task execution list.
</para></listitem>
<listitem><para>
<emphasis><filename>pn-buildlist</filename>:</emphasis>
<listitem><para><emphasis><filename>pn-buildlist</filename>:</emphasis>
Shows a simple list of targets that are to be built.
</para></listitem>
</itemizedlist>

View File

@@ -52,7 +52,7 @@
<link linkend='var-MIRRORS'>M</link>
<!-- <link linkend='var-glossary-n'>N</link> -->
<link linkend='var-OVERRIDES'>O</link>
<link linkend='var-P4DIR'>P</link>
<link linkend='var-PACKAGES'>P</link>
<!-- <link linkend='var-QMAKE_PROFILES'>Q</link> -->
<link linkend='var-RDEPENDS'>R</link>
<link linkend='var-SECTION'>S</link>
@@ -78,7 +78,7 @@
</para>
<para>
In OpenEmbedded-Core, <filename>ASSUME_PROVIDED</filename>
In OpenEmbedded Core, <filename>ASSUME_PROVIDED</filename>
mostly specifies native tools that should not be built.
An example is <filename>git-native</filename>, which
when specified allows for the Git binary from the host to
@@ -102,56 +102,6 @@
</glossdef>
</glossentry>
<glossentry id='var-BB_ALLOWED_NETWORKS'><glossterm>BB_ALLOWED_NETWORKS</glossterm>
<glossdef>
<para>
Specifies a space-delimited list of hosts that the fetcher
is allowed to use to obtain the required source code.
Following are considerations surrounding this variable:
<itemizedlist>
<listitem><para>
This host list is only used if
<link linkend='var-BB_NO_NETWORK'><filename>BB_NO_NETWORK</filename></link>
is either not set or set to "0".
</para></listitem>
<listitem><para>
Limited support for wildcard matching against the
beginning of host names exists.
For example, the following setting matches
<filename>git.gnu.org</filename>,
<filename>ftp.gnu.org</filename>, and
<filename>foo.git.gnu.org</filename>.
<literallayout class='monospaced'>
BB_ALLOWED_NETWORKS = "*.gnu.org"
</literallayout>
</para></listitem>
<listitem><para>
Mirrors not in the host list are skipped and
logged in debug.
</para></listitem>
<listitem><para>
Attempts to access networks not in the host list
cause a failure.
</para></listitem>
</itemizedlist>
Using <filename>BB_ALLOWED_NETWORKS</filename> in
conjunction with
<link linkend='var-PREMIRRORS'><filename>PREMIRRORS</filename></link>
is very useful.
Adding the host you want to use to
<filename>PREMIRRORS</filename> results in the source code
being fetched from an allowed location and avoids raising
an error when a host that is not allowed is in a
<link linkend='var-SRC_URI'><filename>SRC_URI</filename></link>
statement.
This is because the fetcher does not attempt to use the
host listed in <filename>SRC_URI</filename> after a
successful fetch from the
<filename>PREMIRRORS</filename> occurs.
</para>
</glossdef>
</glossentry>
<glossentry id='var-BB_CONSOLELOG'><glossterm>BB_CONSOLELOG</glossterm>
<glossdef>
<para>
@@ -716,7 +666,7 @@
</glossdef>
</glossentry>
<glossentry id='var-BB_SETSCENE_VERIFY_FUNCTION2'><glossterm>BB_SETSCENE_VERIFY_FUNCTION2</glossterm>
<glossentry id='var-BB_SETSCENE_VERIFY_FUNCTION'><glossterm>BB_SETSCENE_VERIFY_FUNCTION</glossterm>
<glossdef>
<para>
Specifies a function to call that verifies the list of
@@ -856,56 +806,6 @@
</glossdef>
</glossentry>
<glossentry id='var-BB_TASK_IONICE_LEVEL'><glossterm>BB_TASK_IONICE_LEVEL</glossterm>
<glossdef>
<para>
Allows adjustment of a task's Input/Output priority.
During Autobuilder testing, random failures can occur
for tasks due to I/O starvation.
These failures occur during various QEMU runtime timeouts.
You can use the <filename>BB_TASK_IONICE_LEVEL</filename>
variable to adjust the I/O priority of these tasks.
<note>
This variable works similarly to the
<link linkend='var-BB_TASK_NICE_LEVEL'><filename>BB_TASK_NICE_LEVEL</filename></link>
variable except with a task's I/O priorities.
</note>
</para>
<para>
Set the variable as follows:
<literallayout class='monospaced'>
BB_TASK_IONICE_LEVEL = "<replaceable>class</replaceable>.<replaceable>prio</replaceable>"
</literallayout>
For <replaceable>class</replaceable>, the default value is
"2", which is a best effort.
You can use "1" for realtime and "3" for idle.
If you want to use realtime, you must have superuser
privileges.
</para>
<para>
For <replaceable>prio</replaceable>, you can use any
value from "0", which is the highest priority, to "7",
which is the lowest.
The default value is "4".
You do not need any special privileges to use this range
of priority values.
<note>
In order for your I/O priority settings to take effect,
you need the Completely Fair Queuing (CFQ) Scheduler
selected for the backing block device.
To select the scheduler, use the following command form
where <replaceable>device</replaceable> is the device
(e.g. sda, sdb, and so forth):
<literallayout class='monospaced'>
$ sudo sh -c “echo cfq > /sys/block/<replaceable>device</replaceable>/queu/scheduler
</literallayout>
</note>
</para>
</glossdef>
</glossentry>
<glossentry id='var-BB_TASK_NICE_LEVEL'><glossterm>BB_TASK_NICE_LEVEL</glossterm>
<glossdef>
<para>
@@ -964,7 +864,7 @@
Allows you to extend a recipe so that it builds variants
of the software.
Some examples of these variants for recipes from the
OpenEmbedded-Core metadata are "natives" such as
OpenEmbedded Core metadata are "natives" such as
<filename>quilt-native</filename>, which is a copy of
Quilt built to run on the build system; "crosses" such
as <filename>gcc-cross</filename>, which is a compiler
@@ -972,7 +872,7 @@
that run on the target <filename>MACHINE</filename>;
"nativesdk", which targets the SDK machine instead of
<filename>MACHINE</filename>; and "mulitlibs" in the form
"<filename>multilib:</filename><replaceable>multilib_name</replaceable>".
"<filename>multilib:&lt;multilib_name&gt;</filename>".
</para>
<para>
@@ -980,35 +880,12 @@
amount of code, it usually is as simple as adding the
variable to your recipe.
Here are two examples.
The "native" variants are from the OpenEmbedded-Core
The "native" variants are from the OpenEmbedded Core
metadata:
<literallayout class='monospaced'>
BBCLASSEXTEND =+ "native nativesdk"
BBCLASSEXTEND =+ "multilib:<replaceable>multilib_name</replaceable>"
BBCLASSEXTEND =+ "multilib:&lt;multilib_name&gt;"
</literallayout>
<note>
<para>
Internally, the <filename>BBCLASSEXTEND</filename>
mechanism generates recipe variants by rewriting
variable values and applying overrides such as
<filename>_class-native</filename>.
For example, to generate a native version of a recipe,
a
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
on "foo" is rewritten to a <filename>DEPENDS</filename>
on "foo-native".
</para>
<para>
Even when using <filename>BBCLASSEXTEND</filename>, the
recipe is only parsed once.
Parsing once adds some limitations.
For example, it is not possible to
include a different file depending on the variant,
since <filename>include</filename> statements are
processed when the recipe is parsed.
</para>
</note>
</para>
</glossdef>
</glossentry>
@@ -1017,7 +894,7 @@
<glossdef>
<para>
Sets the BitBake debug output level to a specific value
as incremented by the <filename>-D</filename> command line
as incremented by the <filename>-d</filename> command line
option.
<note>
You must set this variable in the external environment
@@ -1139,18 +1016,6 @@
</glossdef>
</glossentry>
<glossentry id='var-BBLAYERS_FETCH_DIR'><glossterm>BBLAYERS_FETCH_DIR</glossterm>
<glossdef>
<para>
Sets the base location where layers are stored.
This setting is used in conjunction with
<filename>bitbake-layers layerindex-fetch</filename> and
tells <filename>bitbake-layers</filename> where to place
the fetched layers.
</para>
</glossdef>
</glossentry>
<glossentry id='var-BBMASK'><glossterm>BBMASK</glossterm>
<glossdef>
<para>
@@ -1163,14 +1028,14 @@
to "hide" these <filename>.bb</filename> and
<filename>.bbappend</filename> files.
BitBake ignores any recipe or recipe append files that
match any of the expressions.
match the expression.
It is as if BitBake does not see them at all.
Consequently, matching files are not parsed or otherwise
used by BitBake.</para>
<para>
The values you provide are passed to Python's regular
The value you provide is passed to Python's regular
expression compiler.
The expressions are compared against the full paths to
The expression is compared against the full paths to
the files.
For complete syntax information, see Python's
documentation at
@@ -1186,16 +1051,18 @@
BBMASK = "meta-ti/recipes-misc/"
</literallayout>
If you want to mask out multiple directories or recipes,
you can specify multiple regular expression fragments.
use the vertical bar to separate the regular expression
fragments.
This next example masks out multiple directories and
individual recipes:
<literallayout class='monospaced'>
BBMASK += "/meta-ti/recipes-misc/ meta-ti/recipes-ti/packagegroup/"
BBMASK += "/meta-oe/recipes-support/"
BBMASK += "/meta-foo/.*/openldap"
BBMASK += "opencv.*\.bbappend"
BBMASK += "lzma"
BBMASK = "meta-ti/recipes-misc/|meta-ti/recipes-ti/packagegroup/"
BBMASK .= "|.*meta-oe/recipes-support/"
BBMASK .= "|.*openldap"
BBMASK .= "|.*opencv"
BBMASK .= "|.*lzma"
</literallayout>
Notice how the vertical bar is used to append the fragments.
<note>
When specifying a directory name, use the trailing
slash character to ensure you match just that directory
@@ -1224,9 +1091,9 @@
Set the variable as you would any environment variable
and then run BitBake:
<literallayout class='monospaced'>
$ BBPATH="<replaceable>build_directory</replaceable>"
$ BBPATH="&lt;build_directory&gt;"
$ export BBPATH
$ bitbake <replaceable>target</replaceable>
$ bitbake &lt;target&gt;
</literallayout>
</para>
</glossdef>
@@ -1242,15 +1109,6 @@
</glossdef>
</glossentry>
<glossentry id='var-BBTARGETS'><glossterm>BBTARGETS</glossterm>
<glossdef>
<para>
Allows you to use a configuration file to add to the list
of command-line target recipes you want to build.
</para>
</glossdef>
</glossentry>
<glossentry id='var-BBVERSIONS'><glossterm>BBVERSIONS</glossterm>
<glossdef>
<para>
@@ -1537,6 +1395,24 @@
</glossdef>
</glossentry>
<glossentry id='var-FILESDIR'><glossterm>FILESDIR</glossterm>
<glossdef>
<para>
Specifies directories BitBake uses when searching for
patches and files.
The "local" fetcher module uses these directories when
handling <filename>file://</filename> URLs if the file
was not found using
<link linkend='var-FILESPATH'><filename>FILESPATH</filename></link>.
<note>
The <filename>FILESDIR</filename> variable is
deprecated and you should use
<filename>FILESPATH</filename> in all new code.
</note>
</para>
</glossdef>
</glossentry>
<glossentry id='var-FILESPATH'><glossterm>FILESPATH</glossterm>
<glossdef>
<para>
@@ -1594,19 +1470,9 @@
<glossentry id='var-INHERIT'><glossterm>INHERIT</glossterm>
<glossdef>
<para>
Causes the named class or classes to be inherited globally.
Anonymous functions in the class or classes
are not executed for the
base configuration and in each individual recipe.
The OpenEmbedded build system ignores changes to
<filename>INHERIT</filename> in individual recipes.
</para>
<para>
For more information on <filename>INHERIT</filename>, see
the
"<link linkend="inherit-configuration-directive"><filename>INHERIT</filename> Configuration Directive</link>"
section.
Causes the named class to be inherited at
this point during parsing.
The variable is only valid in configuration files.
</para>
</glossdef>
</glossentry>
@@ -1649,17 +1515,6 @@
</glossdef>
</glossentry>
<glossentry id='var-LAYERDIR_RE'><glossterm>LAYERDIR_RE</glossterm>
<glossdef>
<para>When used inside the <filename>layer.conf</filename> configuration
file, this variable provides the path of the current layer,
escaped for use in a regular expression
(<link linkend='var-BBFILE_PATTERN'><filename>BBFILE_PATTERN</filename></link>).
This variable is not available outside of <filename>layer.conf</filename>
and references are expanded immediately when parsing of the file completes.</para>
</glossdef>
</glossentry>
<glossentry id='var-LAYERVERSION'><glossterm>LAYERVERSION</glossterm>
<glossdef>
<para>Optionally specifies the version of a layer as a single number.
@@ -1761,15 +1616,6 @@
<glossdiv id='var-glossary-p'><title>P</title>
<glossentry id='var-P4DIR'><glossterm>P4DIR</glossterm>
<glossdef>
<para>
The directory in which a local copy of a Perforce depot
is stored when it is fetched.
</para>
</glossdef>
</glossentry>
<glossentry id='var-PACKAGES'><glossterm>PACKAGES</glossterm>
<glossdef>
<para>The list of packages the recipe creates.
@@ -1901,7 +1747,7 @@
Here are two examples:
<literallayout class='monospaced'>
PREFERRED_VERSION_python = "2.7.3"
PREFERRED_VERSION_linux-yocto = "4.12%"
PREFERRED_VERSION_linux-yocto = "3.10%"
</literallayout>
</para>
</glossdef>
@@ -1966,27 +1812,6 @@
The <filename>PROVIDES</filename> statement results in
the "libav" recipe also being known as "libpostproc".
</para>
<para>
In addition to providing recipes under alternate names,
the <filename>PROVIDES</filename> mechanism is also used
to implement virtual targets.
A virtual target is a name that corresponds to some
particular functionality (e.g. a Linux kernel).
Recipes that provide the functionality in question list the
virtual target in <filename>PROVIDES</filename>.
Recipes that depend on the functionality in question can
include the virtual target in
<link linkend='var-DEPENDS'><filename>DEPENDS</filename></link>
to leave the choice of provider open.
</para>
<para>
Conventionally, virtual targets have names on the form
"virtual/function" (e.g. "virtual/kernel").
The slash is simply part of the name and has no
syntactical significance.
</para>
</glossdef>
</glossentry>
@@ -2063,7 +1888,7 @@
Here is the general syntax to specify versions with
the <filename>RDEPENDS</filename> variable:
<literallayout class='monospaced'>
RDEPENDS_${PN} = "<replaceable>package</replaceable> (<replaceable>operator</replaceable> <replaceable>version</replaceable>)"
RDEPENDS_${PN} = "&lt;package&gt; (&lt;operator&gt; &lt;version&gt;)"
</literallayout>
For <filename>operator</filename>, you can specify the
following:
@@ -2089,16 +1914,6 @@
</glossdef>
</glossentry>
<glossentry id='var-REPODIR'><glossterm>REPODIR</glossterm>
<glossdef>
<para>
The directory in which a local copy of a
<filename>google-repo</filename> directory is stored
when it is synced.
</para>
</glossdef>
</glossentry>
<glossentry id='var-RPROVIDES'><glossterm>RPROVIDES</glossterm>
<glossdef>
<para>
@@ -2139,7 +1954,7 @@
Here is the general syntax to specify versions with
the <filename>RRECOMMENDS</filename> variable:
<literallayout class='monospaced'>
RRECOMMENDS_${PN} = "<replaceable>package</replaceable> (<replaceable>operator</replaceable> <replaceable>version</replaceable>)"
RRECOMMENDS_${PN} = "&lt;package&gt; (&lt;operator&gt; &lt;version&gt;)"
</literallayout>
For <filename>operator</filename>, you can specify the
following:

View File

@@ -56,7 +56,7 @@
-->
<copyright>
<year>2004-2018</year>
<year>2004-2015</year>
<holder>Richard Purdie</holder>
<holder>Chris Larson</holder>
<holder>and Phil Blundell</holder>

View File

@@ -105,7 +105,7 @@ Show debug logging for the specified logging domains
profile the command and print a report
.TP
.B \-uUI, \-\-ui=UI
User interface to use. Currently, knotty, taskexp or ncurses can be specified as UI.
User interface to use. Currently, hob, depexp, goggle or ncurses can be specified as UI.
.TP
.B \-tSERVERTYPE, \-\-servertype=SERVERTYPE
Choose which server to use, none, process or xmlrpc.

View File

@@ -3,7 +3,7 @@
#
# This is a copy on write dictionary and set which abuses classes to try and be nice and fast.
#
# Copyright (C) 2006 Tim Ansell
# Copyright (C) 2006 Tim Amsell
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -23,17 +23,19 @@
# Assign a file to __warn__ to get warnings about slow operations.
#
from __future__ import print_function
import copy
import types
ImmutableTypes = (
types.NoneType,
bool,
complex,
float,
int,
long,
tuple,
frozenset,
str
basestring
)
MUTABLE = "__mutable__"
@@ -59,7 +61,7 @@ class COWDictMeta(COWMeta):
__call__ = cow
def __setitem__(cls, key, value):
if value is not None and not isinstance(value, ImmutableTypes):
if not isinstance(value, ImmutableTypes):
if not isinstance(value, COWMeta):
cls.__hasmutable__ = True
key += MUTABLE
@@ -114,7 +116,7 @@ class COWDictMeta(COWMeta):
cls.__setitem__(key, cls.__marker__)
def __revertitem__(cls, key):
if key not in cls.__dict__:
if not cls.__dict__.has_key(key):
key += MUTABLE
delattr(cls, key)
@@ -150,7 +152,7 @@ class COWDictMeta(COWMeta):
yield value
if type == "items":
yield (key, value)
return
raise StopIteration()
def iterkeys(cls):
return cls.iter("keys")
@@ -181,7 +183,7 @@ class COWSetMeta(COWDictMeta):
COWDictMeta.__delitem__(cls, repr(hash(value)))
def __in__(cls, value):
return repr(hash(value)) in COWDictMeta
return COWDictMeta.has_key(repr(hash(value)))
def iterkeys(cls):
raise TypeError("sets don't have keys")
@@ -190,10 +192,12 @@ class COWSetMeta(COWDictMeta):
raise TypeError("sets don't have 'items'")
# These are the actual classes you use!
class COWDictBase(object, metaclass = COWDictMeta):
class COWDictBase(object):
__metaclass__ = COWDictMeta
__count__ = 0
class COWSetBase(object, metaclass = COWSetMeta):
class COWSetBase(object):
__metaclass__ = COWSetMeta
__count__ = 0
if __name__ == "__main__":
@@ -283,7 +287,7 @@ if __name__ == "__main__":
except KeyError:
print("Yay! deleted key raises error")
if 'b' in b:
if b.has_key('b'):
print("Boo!")
else:
print("Yay - has_key with delete works!")

View File

@@ -21,11 +21,11 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
__version__ = "1.38.0"
__version__ = "1.26.0"
import sys
if sys.version_info < (3, 4, 0):
raise RuntimeError("Sorry, python 3.4.0 or later is required for this version of bitbake")
if sys.version_info < (2, 7, 3):
raise RuntimeError("Sorry, python 2.7.3 or later is required for this version of bitbake")
class BBHandledException(Exception):
@@ -70,8 +70,6 @@ logger = logging.getLogger("BitBake")
logger.addHandler(NullHandler())
logger.setLevel(logging.DEBUG - 2)
mainlogger = logging.getLogger("BitBake.Main")
# This has to be imported after the setLoggerClass, as the import of bb.msg
# can result in construction of the various loggers.
import bb.msg
@@ -81,26 +79,26 @@ sys.modules['bb.fetch'] = sys.modules['bb.fetch2']
# Messaging convenience functions
def plain(*args):
mainlogger.plain(''.join(args))
logger.plain(''.join(args))
def debug(lvl, *args):
if isinstance(lvl, str):
mainlogger.warning("Passed invalid debug level '%s' to bb.debug", lvl)
if isinstance(lvl, basestring):
logger.warn("Passed invalid debug level '%s' to bb.debug", lvl)
args = (lvl,) + args
lvl = 1
mainlogger.debug(lvl, ''.join(args))
logger.debug(lvl, ''.join(args))
def note(*args):
mainlogger.info(''.join(args))
logger.info(''.join(args))
def warn(*args):
mainlogger.warning(''.join(args))
logger.warn(''.join(args))
def error(*args, **kwargs):
mainlogger.error(''.join(args), extra=kwargs)
def error(*args):
logger.error(''.join(args))
def fatal(*args, **kwargs):
mainlogger.critical(''.join(args), extra=kwargs)
def fatal(*args):
logger.critical(''.join(args))
raise BBHandledException()
def deprecated(func, name=None, advice=""):

View File

@@ -31,43 +31,23 @@ import logging
import shlex
import glob
import time
import stat
import bb
import bb.msg
import bb.process
import bb.progress
from bb import data, event, utils
from contextlib import nested
from bb import event, utils
bblogger = logging.getLogger('BitBake')
logger = logging.getLogger('BitBake.Build')
NULL = open(os.devnull, 'r+')
__mtime_cache = {}
def cached_mtime_noerror(f):
if f not in __mtime_cache:
try:
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
except OSError:
return 0
return __mtime_cache[f]
def reset_cache():
global __mtime_cache
__mtime_cache = {}
# When we execute a Python function, we'd like certain things
# in all namespaces, hence we add them to __builtins__.
# If we do not do this and use the exec globals, they will
# not be available to subfunctions.
if hasattr(__builtins__, '__setitem__'):
builtins = __builtins__
else:
builtins = __builtins__.__dict__
builtins['bb'] = bb
builtins['os'] = os
__builtins__['bb'] = bb
__builtins__['os'] = os
class FuncFailed(Exception):
def __init__(self, name = None, logfile = None):
@@ -91,14 +71,13 @@ class TaskBase(event.Event):
def __init__(self, t, logfile, d):
self._task = t
self._package = d.getVar("PF")
self._mc = d.getVar("BB_CURRENT_MC")
self.taskfile = d.getVar("FILE")
self._package = d.getVar("PF", True)
self.taskfile = d.getVar("FILE", True)
self.taskname = self._task
self.logfile = logfile
self.time = time.time()
event.Event.__init__(self)
self._message = "recipe %s: task %s: %s" % (d.getVar("PF"), t, self.getDisplayName())
self._message = "recipe %s: task %s: %s" % (d.getVar("PF", True), t, self.getDisplayName())
def getTask(self):
return self._task
@@ -139,25 +118,6 @@ class TaskInvalid(TaskBase):
super(TaskInvalid, self).__init__(task, None, metadata)
self._message = "No such task '%s'" % task
class TaskProgress(event.Event):
"""
Task made some progress that could be reported to the user, usually in
the form of a progress bar or similar.
NOTE: this class does not inherit from TaskBase since it doesn't need
to - it's fired within the task context itself, so we don't have any of
the context information that you do in the case of the other events.
The event PID can be used to determine which task it came from.
The progress value is normally 0-100, but can also be negative
indicating that progress has been made but we aren't able to determine
how much.
The rate is optional, this is simply an extra string to display to the
user if specified.
"""
def __init__(self, progress, rate=None):
self.progress = progress
self.rate = rate
event.Event.__init__(self)
class LogTee(object):
def __init__(self, logger, outfile):
@@ -181,27 +141,23 @@ class LogTee(object):
def flush(self):
self.outfile.flush()
#
# pythonexception allows the python exceptions generated to be raised
# as the real exceptions (not FuncFailed) and without a backtrace at the
# origin of the failure.
#
def exec_func(func, d, dirs = None, pythonexception=False):
def exec_func(func, d, dirs = None):
"""Execute a BB 'function'"""
try:
oldcwd = os.getcwd()
except:
oldcwd = None
body = d.getVar(func)
if not body:
if body is None:
logger.warn("Function %s doesn't exist", func)
return
flags = d.getVarFlags(func)
cleandirs = flags.get('cleandirs') if flags else None
cleandirs = flags.get('cleandirs')
if cleandirs:
for cdir in d.expand(cleandirs).split():
bb.utils.remove(cdir, True)
bb.utils.mkdirhier(cdir)
if flags and dirs is None:
if dirs is None:
dirs = flags.get('dirs')
if dirs:
dirs = d.expand(dirs).split()
@@ -211,13 +167,8 @@ def exec_func(func, d, dirs = None, pythonexception=False):
bb.utils.mkdirhier(adir)
adir = dirs[-1]
else:
adir = None
body = d.getVar(func, False)
if not body:
if body is None:
logger.warning("Function %s doesn't exist", func)
return
adir = d.getVar('B', True)
bb.utils.mkdirhier(adir)
ispython = flags.get('python')
@@ -227,17 +178,17 @@ def exec_func(func, d, dirs = None, pythonexception=False):
else:
lockfiles = None
tempdir = d.getVar('T')
tempdir = d.getVar('T', True)
# or func allows items to be executed outside of the normal
# task set, such as buildhistory
task = d.getVar('BB_RUNTASK') or func
task = d.getVar('BB_RUNTASK', True) or func
if task == func:
taskfunc = task
else:
taskfunc = "%s.%s" % (task, func)
runfmt = d.getVar('BB_RUNFMT') or "run.{func}.{pid}"
runfmt = d.getVar('BB_RUNFMT', True) or "run.{func}.{pid}"
runfn = runfmt.format(taskfunc=taskfunc, task=task, func=func, pid=os.getpid())
runfile = os.path.join(tempdir, runfn)
bb.utils.mkdirhier(os.path.dirname(runfile))
@@ -258,30 +209,22 @@ def exec_func(func, d, dirs = None, pythonexception=False):
with bb.utils.fileslocked(lockfiles):
if ispython:
exec_func_python(func, d, runfile, cwd=adir, pythonexception=pythonexception)
exec_func_python(func, d, runfile, cwd=adir)
else:
exec_func_shell(func, d, runfile, cwd=adir)
try:
curcwd = os.getcwd()
except:
curcwd = None
if oldcwd and curcwd != oldcwd:
try:
bb.warn("Task %s changed cwd to %s" % (func, curcwd))
os.chdir(oldcwd)
except:
pass
_functionfmt = """
def {function}(d):
{body}
{function}(d)
"""
logformatter = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
def exec_func_python(func, d, runfile, cwd=None, pythonexception=False):
def exec_func_python(func, d, runfile, cwd=None):
"""Execute a python BB 'function'"""
code = _functionfmt.format(function=func)
bbfile = d.getVar('FILE', True)
code = _functionfmt.format(function=func, body=d.getVar(func, True))
bb.utils.mkdirhier(os.path.dirname(runfile))
with open(runfile, 'w') as script:
bb.data.emit_func_python(func, script, d)
@@ -289,26 +232,18 @@ def exec_func_python(func, d, runfile, cwd=None, pythonexception=False):
if cwd:
try:
olddir = os.getcwd()
except OSError as e:
bb.warn("%s: Cannot get cwd: %s" % (func, e))
except OSError:
olddir = None
os.chdir(cwd)
bb.debug(2, "Executing python function %s" % func)
try:
text = "def %s(d):\n%s" % (func, d.getVar(func, False))
fn = d.getVarFlag(func, "filename", False)
lineno = int(d.getVarFlag(func, "lineno", False))
bb.methodpool.insert_method(func, text, fn, lineno - 1)
comp = utils.better_compile(code, func, "exec_python_func() autogenerated")
utils.better_exec(comp, {"d": d}, code, "exec_python_func() autogenerated", pythonexception=pythonexception)
comp = utils.better_compile(code, func, bbfile)
utils.better_exec(comp, {"d": d}, code, bbfile)
except (bb.parse.SkipRecipe, bb.build.FuncFailed):
raise
except:
if pythonexception:
raise
raise FuncFailed(func, None)
finally:
bb.debug(2, "Python function %s finished" % func)
@@ -316,8 +251,8 @@ def exec_func_python(func, d, runfile, cwd=None, pythonexception=False):
if cwd and olddir:
try:
os.chdir(olddir)
except OSError as e:
bb.warn("%s: Cannot restore cwd %s: %s" % (func, olddir, e))
except OSError:
pass
def shell_trap_code():
return '''#!/bin/sh\n
@@ -327,8 +262,9 @@ bb_exit_handler() {
case $ret in
0) ;;
*) case $BASH_VERSION in
"") echo "WARNING: exit code $ret from a shell command.";;
*) echo "WARNING: ${BASH_SOURCE[0]}:${BASH_LINENO[0]} exit $ret from '$BASH_COMMAND'";;
"") echo "WARNING: exit code $ret from a shell command.";;
*) echo "WARNING: ${BASH_SOURCE[0]}:${BASH_LINENO[0]} exit $ret from
\"$BASH_COMMAND\"";;
esac
exit $ret
esac
@@ -362,14 +298,14 @@ def exec_func_shell(func, d, runfile, cwd=None):
# cleanup
ret=$?
trap '' 0
exit $ret
exit $?
''')
os.chmod(runfile, 0o775)
os.chmod(runfile, 0775)
cmd = runfile
if d.getVarFlag(func, 'fakeroot', False):
fakerootcmd = d.getVar('FAKEROOT')
if d.getVarFlag(func, 'fakeroot'):
fakerootcmd = d.getVar('FAKEROOT', True)
if fakerootcmd:
cmd = [fakerootcmd, runfile]
@@ -378,75 +314,14 @@ exit $ret
else:
logfile = sys.stdout
progress = d.getVarFlag(func, 'progress')
if progress:
if progress == 'percent':
# Use default regex
logfile = bb.progress.BasicProgressHandler(d, outfile=logfile)
elif progress.startswith('percent:'):
# Use specified regex
logfile = bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
elif progress.startswith('outof:'):
# Use specified regex
logfile = bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
else:
bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress))
bb.debug(2, "Executing shell function %s" % func)
fifobuffer = bytearray()
def readfifo(data):
nonlocal fifobuffer
fifobuffer.extend(data)
while fifobuffer:
message, token, nextmsg = fifobuffer.partition(b"\00")
if token:
splitval = message.split(b' ', 1)
cmd = splitval[0].decode("utf-8")
if len(splitval) > 1:
value = splitval[1].decode("utf-8")
else:
value = ''
if cmd == 'bbplain':
bb.plain(value)
elif cmd == 'bbnote':
bb.note(value)
elif cmd == 'bbwarn':
bb.warn(value)
elif cmd == 'bberror':
bb.error(value)
elif cmd == 'bbfatal':
# The caller will call exit themselves, so bb.error() is
# what we want here rather than bb.fatal()
bb.error(value)
elif cmd == 'bbfatal_log':
bb.error(value, forcelog=True)
elif cmd == 'bbdebug':
splitval = value.split(' ', 1)
level = int(splitval[0])
value = splitval[1]
bb.debug(level, value)
else:
bb.warn("Unrecognised command '%s' on FIFO" % cmd)
fifobuffer = nextmsg
else:
break
tempdir = d.getVar('T')
fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid())
if os.path.exists(fifopath):
os.unlink(fifopath)
os.mkfifo(fifopath)
with open(fifopath, 'r+b', buffering=0) as fifo:
try:
bb.debug(2, "Executing shell function %s" % func)
try:
with open(os.devnull, 'r+') as stdin:
bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)])
except bb.process.CmdError:
logfn = d.getVar('BB_LOGFILE')
raise FuncFailed(func, logfn)
finally:
os.unlink(fifopath)
try:
with open(os.devnull, 'r+') as stdin:
bb.process.run(cmd, shell=False, stdin=stdin, log=logfile)
except bb.process.CmdError:
logfn = d.getVar('BB_LOGFILE', True)
raise FuncFailed(func, logfn)
bb.debug(2, "Shell function %s finished" % func)
@@ -466,7 +341,7 @@ def _exec_task(fn, task, d, quieterr):
Execution of a task involves a bit more setup than executing a function,
running it with its own local metadata, and with some useful variables set.
"""
if not d.getVarFlag(task, 'task', False):
if not d.getVarFlag(task, 'task'):
event.fire(TaskInvalid(task, d), d)
logger.error("No such task: %s" % task)
return 1
@@ -474,29 +349,22 @@ def _exec_task(fn, task, d, quieterr):
logger.debug(1, "Executing task %s", task)
localdata = _task_data(fn, task, d)
tempdir = localdata.getVar('T')
tempdir = localdata.getVar('T', True)
if not tempdir:
bb.fatal("T variable not set, unable to build")
# Change nice level if we're asked to
nice = localdata.getVar("BB_TASK_NICE_LEVEL")
nice = localdata.getVar("BB_TASK_NICE_LEVEL", True)
if nice:
curnice = os.nice(0)
nice = int(nice) - curnice
newnice = os.nice(nice)
logger.debug(1, "Renice to %s " % newnice)
ionice = localdata.getVar("BB_TASK_IONICE_LEVEL")
if ionice:
try:
cls, prio = ionice.split(".", 1)
bb.utils.ioprio_set(os.getpid(), int(cls), int(prio))
except:
bb.warn("Invalid ionice level %s" % ionice)
bb.utils.mkdirhier(tempdir)
# Determine the logfile to generate
logfmt = localdata.getVar('BB_LOGFMT') or 'log.{task}.{pid}'
logfmt = localdata.getVar('BB_LOGFMT', True) or 'log.{task}.{pid}'
logbase = logfmt.format(task=task, pid=os.getpid())
# Document the order of the tasks...
@@ -527,10 +395,7 @@ def _exec_task(fn, task, d, quieterr):
self.triggered = False
logging.Handler.__init__(self, logging.ERROR)
def emit(self, record):
if getattr(record, 'forcelog', False):
self.triggered = False
else:
self.triggered = True
self.triggered = True
# Handle logfiles
si = open('/dev/null', 'r')
@@ -563,36 +428,24 @@ def _exec_task(fn, task, d, quieterr):
localdata.setVar('BB_LOGFILE', logfn)
localdata.setVar('BB_RUNTASK', task)
localdata.setVar('BB_TASK_LOGGER', bblogger)
flags = localdata.getVarFlags(task)
event.fire(TaskStarted(task, logfn, flags, localdata), localdata)
try:
try:
event.fire(TaskStarted(task, logfn, flags, localdata), localdata)
except (bb.BBHandledException, SystemExit):
return 1
except FuncFailed as exc:
for func in (prefuncs or '').split():
exec_func(func, localdata)
exec_func(task, localdata)
for func in (postfuncs or '').split():
exec_func(func, localdata)
except FuncFailed as exc:
if quieterr:
event.fire(TaskFailedSilent(task, logfn, localdata), localdata)
else:
errprinted = errchk.triggered
logger.error(str(exc))
return 1
try:
for func in (prefuncs or '').split():
exec_func(func, localdata)
exec_func(task, localdata)
for func in (postfuncs or '').split():
exec_func(func, localdata)
except FuncFailed as exc:
if quieterr:
event.fire(TaskFailedSilent(task, logfn, localdata), localdata)
else:
errprinted = errchk.triggered
logger.error(str(exc))
event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata)
return 1
except bb.BBHandledException:
event.fire(TaskFailed(task, logfn, localdata, True), localdata)
return 1
event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata)
return 1
finally:
sys.stdout.flush()
sys.stderr.flush()
@@ -617,7 +470,7 @@ def _exec_task(fn, task, d, quieterr):
bb.utils.remove(loglink)
event.fire(TaskSucceeded(task, logfn, localdata), localdata)
if not localdata.getVarFlag(task, 'nostamp', False) and not localdata.getVarFlag(task, 'selfstamp', False):
if not localdata.getVarFlag(task, 'nostamp') and not localdata.getVarFlag(task, 'selfstamp'):
make_stamp(task, localdata)
return 0
@@ -625,11 +478,11 @@ def _exec_task(fn, task, d, quieterr):
def exec_task(fn, task, d, profile = False):
try:
quieterr = False
if d.getVarFlag(task, "quieterrors", False) is not None:
if d.getVarFlag(task, "quieterrors") is not None:
quieterr = True
if profile:
profname = "profile-%s.log" % (d.getVar("PN") + "-" + task)
profname = "profile-%s.log" % (d.getVar("PN", True) + "-" + task)
try:
import cProfile as profile
except:
@@ -652,7 +505,7 @@ def exec_task(fn, task, d, profile = False):
event.fire(failedevent, d)
return 1
def stamp_internal(taskname, d, file_name, baseonly=False, noextra=False):
def stamp_internal(taskname, d, file_name, baseonly=False):
"""
Internal stamp helper function
Makes sure the stamp directory exists
@@ -666,17 +519,15 @@ def stamp_internal(taskname, d, file_name, baseonly=False, noextra=False):
taskflagname = taskname.replace("_setscene", "")
if file_name:
stamp = d.stamp[file_name]
stamp = d.stamp_base[file_name].get(taskflagname) or d.stamp[file_name]
extrainfo = d.stamp_extrainfo[file_name].get(taskflagname) or ""
else:
stamp = d.getVar('STAMP')
file_name = d.getVar('BB_FILENAME')
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info') or ""
stamp = d.getVarFlag(taskflagname, 'stamp-base', True) or d.getVar('STAMP', True)
file_name = d.getVar('BB_FILENAME', True)
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info', True) or ""
if baseonly:
return stamp
if noextra:
extrainfo = ""
if not stamp:
return
@@ -684,7 +535,7 @@ def stamp_internal(taskname, d, file_name, baseonly=False, noextra=False):
stamp = bb.parse.siggen.stampfile(stamp, file_name, taskname, extrainfo)
stampdir = os.path.dirname(stamp)
if cached_mtime_noerror(stampdir) == 0:
if bb.parse.cached_mtime_noerror(stampdir) == 0:
bb.utils.mkdirhier(stampdir)
return stamp
@@ -702,12 +553,12 @@ def stamp_cleanmask_internal(taskname, d, file_name):
taskflagname = taskname.replace("_setscene", "")
if file_name:
stamp = d.stampclean[file_name]
stamp = d.stamp_base_clean[file_name].get(taskflagname) or d.stampclean[file_name]
extrainfo = d.stamp_extrainfo[file_name].get(taskflagname) or ""
else:
stamp = d.getVar('STAMPCLEAN')
file_name = d.getVar('BB_FILENAME')
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info') or ""
stamp = d.getVarFlag(taskflagname, 'stamp-base-clean', True) or d.getVar('STAMPCLEAN', True)
file_name = d.getVar('BB_FILENAME', True)
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info', True) or ""
if not stamp:
return []
@@ -725,7 +576,7 @@ def make_stamp(task, d, file_name = None):
for mask in cleanmask:
for name in glob.glob(mask):
# Preserve sigdata files in the stamps directory
if "sigdata" in name or "sigbasedata" in name:
if "sigdata" in name:
continue
# Preserve taint files in the stamps directory
if name.endswith('.taint'):
@@ -743,7 +594,7 @@ def make_stamp(task, d, file_name = None):
# as it completes
if not task.endswith("_setscene") and task != "do_setscene" and not file_name:
stampbase = stamp_internal(task, d, None, True)
file_name = d.getVar('BB_FILENAME')
file_name = d.getVar('BB_FILENAME', True)
bb.parse.siggen.dump_sigtask(file_name, task, stampbase, True)
def del_stamp(task, d, file_name = None):
@@ -765,22 +616,22 @@ def write_taint(task, d, file_name = None):
if file_name:
taintfn = d.stamp[file_name] + '.' + task + '.taint'
else:
taintfn = d.getVar('STAMP') + '.' + task + '.taint'
taintfn = d.getVar('STAMP', True) + '.' + task + '.taint'
bb.utils.mkdirhier(os.path.dirname(taintfn))
# The specific content of the taint file is not really important,
# we just need it to be random, so a random UUID is used
with open(taintfn, 'w') as taintf:
taintf.write(str(uuid.uuid4()))
def stampfile(taskname, d, file_name = None, noextra=False):
def stampfile(taskname, d, file_name = None):
"""
Return the stamp for a given task
(d can be a data dict or dataCache)
"""
return stamp_internal(taskname, d, file_name, noextra=noextra)
return stamp_internal(taskname, d, file_name)
def add_tasks(tasklist, d):
task_deps = d.getVar('_task_deps', False)
def add_tasks(tasklist, deltasklist, d):
task_deps = d.getVar('_task_deps')
if not task_deps:
task_deps = {}
if not 'tasks' in task_deps:
@@ -791,6 +642,9 @@ def add_tasks(tasklist, d):
for task in tasklist:
task = d.expand(task)
if task in deltasklist:
continue
d.setVarFlag(task, 'task', 1)
if not task in task_deps['tasks']:
@@ -827,12 +681,12 @@ def addtask(task, before, after, d):
task = "do_" + task
d.setVarFlag(task, "task", 1)
bbtasks = d.getVar('__BBTASKS', False) or []
if task not in bbtasks:
bbtasks = d.getVar('__BBTASKS') or []
if not task in bbtasks:
bbtasks.append(task)
d.setVar('__BBTASKS', bbtasks)
existing = d.getVarFlag(task, "deps", False) or []
existing = d.getVarFlag(task, "deps") or []
if after is not None:
# set up deps for function
for entry in after.split():
@@ -842,7 +696,7 @@ def addtask(task, before, after, d):
if before is not None:
# set up things that depend on this func
for entry in before.split():
existing = d.getVarFlag(entry, "deps", False) or []
existing = d.getVarFlag(entry, "deps") or []
if task not in existing:
d.setVarFlag(entry, "deps", [task] + existing)
@@ -850,64 +704,8 @@ def deltask(task, d):
if task[:3] != "do_":
task = "do_" + task
bbtasks = d.getVar('__BBTASKS', False) or []
if task in bbtasks:
bbtasks.remove(task)
d.delVarFlag(task, 'task')
d.setVar('__BBTASKS', bbtasks)
bbtasks = d.getVar('__BBDELTASKS') or []
if not task in bbtasks:
bbtasks.append(task)
d.setVar('__BBDELTASKS', bbtasks)
d.delVarFlag(task, 'deps')
for bbtask in d.getVar('__BBTASKS', False) or []:
deps = d.getVarFlag(bbtask, 'deps', False) or []
if task in deps:
deps.remove(task)
d.setVarFlag(bbtask, 'deps', deps)
def preceedtask(task, with_recrdeptasks, d):
"""
Returns a set of tasks in the current recipe which were specified as
precondition by the task itself ("after") or which listed themselves
as precondition ("before"). Preceeding tasks specified via the
"recrdeptask" are included in the result only if requested. Beware
that this may lead to the task itself being listed.
"""
preceed = set()
# Ignore tasks which don't exist
tasks = d.getVar('__BBTASKS', False)
if task not in tasks:
return preceed
preceed.update(d.getVarFlag(task, 'deps') or [])
if with_recrdeptasks:
recrdeptask = d.getVarFlag(task, 'recrdeptask')
if recrdeptask:
preceed.update(recrdeptask.split())
return preceed
def tasksbetween(task_start, task_end, d):
"""
Return the list of tasks between two tasks in the current recipe,
where task_start is to start at and task_end is the task to end at
(and task_end has a dependency chain back to task_start).
"""
outtasks = []
tasks = list(filter(lambda k: d.getVarFlag(k, "task"), d.keys()))
def follow_chain(task, endtask, chain=None):
if not chain:
chain = []
chain.append(task)
for othertask in tasks:
if othertask == task:
continue
if task == endtask:
for ctask in chain:
if ctask not in outtasks:
outtasks.append(ctask)
else:
deps = d.getVarFlag(othertask, 'deps', False)
if task in deps:
follow_chain(othertask, endtask, chain)
chain.pop()
follow_chain(task_start, task_end)
return outtasks

View File

@@ -28,16 +28,22 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import logging
import pickle
from collections import defaultdict
import bb.utils
logger = logging.getLogger("BitBake.Cache")
__cache_version__ = "151"
try:
import cPickle as pickle
except ImportError:
import pickle
logger.info("Importing cPickle failed. "
"Falling back to a very slow implementation.")
__cache_version__ = "148"
def getCacheFile(path, filename, data_hash):
return os.path.join(path, filename + "." + data_hash)
@@ -71,29 +77,29 @@ class RecipeInfoCommon(object):
@classmethod
def flaglist(cls, flag, varlist, metadata, squash=False):
out_dict = dict((var, metadata.getVarFlag(var, flag))
out_dict = dict((var, metadata.getVarFlag(var, flag, True))
for var in varlist)
if squash:
return dict((k,v) for (k,v) in out_dict.items() if v)
return dict((k,v) for (k,v) in out_dict.iteritems() if v)
else:
return out_dict
@classmethod
def getvar(cls, var, metadata, expand = True):
return metadata.getVar(var, expand) or ''
def getvar(cls, var, metadata):
return metadata.getVar(var, True) or ''
class CoreRecipeInfo(RecipeInfoCommon):
__slots__ = ()
cachefile = "bb_cache.dat"
cachefile = "bb_cache.dat"
def __init__(self, filename, metadata):
def __init__(self, filename, metadata):
self.file_depends = metadata.getVar('__depends', False)
self.timestamp = bb.parse.cached_mtime(filename)
self.variants = self.listvar('__VARIANTS', metadata) + ['']
self.appends = self.listvar('__BBAPPEND', metadata)
self.nocache = self.getvar('BB_DONT_CACHE', metadata)
self.nocache = self.getvar('__BB_DONT_CACHE', metadata)
self.skipreason = self.getvar('__SKIPPED', metadata)
if self.skipreason:
@@ -107,7 +113,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
self.pn = self.getvar('PN', metadata)
self.packages = self.listvar('PACKAGES', metadata)
if not self.packages:
if not self.pn in self.packages:
self.packages.append(self.pn)
self.basetaskhashes = self.taskvar('BB_BASEHASH', self.tasks, metadata)
@@ -122,7 +128,9 @@ class CoreRecipeInfo(RecipeInfoCommon):
self.defaultpref = self.intvar('DEFAULT_PREFERENCE', metadata)
self.not_world = self.getvar('EXCLUDE_FROM_WORLD', metadata)
self.stamp = self.getvar('STAMP', metadata)
self.stampclean = self.getvar('STAMPCLEAN', metadata)
self.stampclean = self.getvar('STAMPCLEAN', metadata)
self.stamp_base = self.flaglist('stamp-base', self.tasks, metadata)
self.stamp_base_clean = self.flaglist('stamp-base-clean', self.tasks, metadata)
self.stamp_extrainfo = self.flaglist('stamp-extra-info', self.tasks, metadata)
self.file_checksums = self.flaglist('file-checksums', self.tasks, metadata, True)
self.packages_dynamic = self.listvar('PACKAGES_DYNAMIC', metadata)
@@ -134,11 +142,10 @@ class CoreRecipeInfo(RecipeInfoCommon):
self.rprovides_pkg = self.pkgvar('RPROVIDES', self.packages, metadata)
self.rdepends_pkg = self.pkgvar('RDEPENDS', self.packages, metadata)
self.rrecommends_pkg = self.pkgvar('RRECOMMENDS', self.packages, metadata)
self.inherits = self.getvar('__inherit_cache', metadata, expand=False)
self.inherits = self.getvar('__inherit_cache', metadata)
self.fakerootenv = self.getvar('FAKEROOTENV', metadata)
self.fakerootdirs = self.getvar('FAKEROOTDIRS', metadata)
self.fakerootnoenv = self.getvar('FAKEROOTNOENV', metadata)
self.extradepsfunc = self.getvar('calculate_extra_depends', metadata)
@classmethod
def init_cacheData(cls, cachedata):
@@ -151,6 +158,8 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.stamp = {}
cachedata.stampclean = {}
cachedata.stamp_base = {}
cachedata.stamp_base_clean = {}
cachedata.stamp_extrainfo = {}
cachedata.file_checksums = {}
cachedata.fn_provides = {}
@@ -174,7 +183,6 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.fakerootenv = {}
cachedata.fakerootnoenv = {}
cachedata.fakerootdirs = {}
cachedata.extradepsfunc = {}
def add_cacheData(self, cachedata, fn):
cachedata.task_deps[fn] = self.task_deps
@@ -184,6 +192,8 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.pkg_dp[fn] = self.defaultpref
cachedata.stamp[fn] = self.stamp
cachedata.stampclean[fn] = self.stampclean
cachedata.stamp_base[fn] = self.stamp_base
cachedata.stamp_base_clean[fn] = self.stamp_base_clean
cachedata.stamp_extrainfo[fn] = self.stamp_extrainfo
cachedata.file_checksums[fn] = self.file_checksums
@@ -210,14 +220,13 @@ class CoreRecipeInfo(RecipeInfoCommon):
rprovides += self.rprovides_pkg[package]
for rprovide in rprovides:
if fn not in cachedata.rproviders[rprovide]:
cachedata.rproviders[rprovide].append(fn)
cachedata.rproviders[rprovide].append(fn)
for package in self.packages_dynamic:
cachedata.packages_dynamic[package].append(fn)
# Build hash of runtime depends and recommends
for package in self.packages:
for package in self.packages + [self.pn]:
cachedata.rundeps[fn][package] = list(self.rdepends) + self.rdepends_pkg[package]
cachedata.runrecs[fn][package] = list(self.rrecommends) + self.rrecommends_pkg[package]
@@ -234,7 +243,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.universe_target.append(self.pn)
cachedata.hashfn[fn] = self.hashfilename
for task, taskhash in self.basetaskhashes.items():
for task, taskhash in self.basetaskhashes.iteritems():
identifier = '%s.%s' % (fn, task)
cachedata.basetaskhash[identifier] = taskhash
@@ -242,146 +251,24 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.fakerootenv[fn] = self.fakerootenv
cachedata.fakerootnoenv[fn] = self.fakerootnoenv
cachedata.fakerootdirs[fn] = self.fakerootdirs
cachedata.extradepsfunc[fn] = self.extradepsfunc
def virtualfn2realfn(virtualfn):
"""
Convert a virtual file name to a real one + the associated subclass keyword
"""
mc = ""
if virtualfn.startswith('multiconfig:'):
elems = virtualfn.split(':')
mc = elems[1]
virtualfn = ":".join(elems[2:])
fn = virtualfn
cls = ""
if virtualfn.startswith('virtual:'):
elems = virtualfn.split(':')
cls = ":".join(elems[1:-1])
fn = elems[-1]
return (fn, cls, mc)
def realfn2virtual(realfn, cls, mc):
"""
Convert a real filename + the associated subclass keyword to a virtual filename
"""
if cls:
realfn = "virtual:" + cls + ":" + realfn
if mc:
realfn = "multiconfig:" + mc + ":" + realfn
return realfn
def variant2virtual(realfn, variant):
"""
Convert a real filename + the associated subclass keyword to a virtual filename
"""
if variant == "":
return realfn
if variant.startswith("multiconfig:"):
elems = variant.split(":")
if elems[2]:
return "multiconfig:" + elems[1] + ":virtual:" + ":".join(elems[2:]) + ":" + realfn
return "multiconfig:" + elems[1] + ":" + realfn
return "virtual:" + variant + ":" + realfn
def parse_recipe(bb_data, bbfile, appends, mc=''):
"""
Parse a recipe
"""
chdir_back = False
bb_data.setVar("__BBMULTICONFIG", mc)
# expand tmpdir to include this topdir
bb_data.setVar('TMPDIR', bb_data.getVar('TMPDIR') or "")
bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
oldpath = os.path.abspath(os.getcwd())
bb.parse.cached_mtime_noerror(bbfile_loc)
# The ConfHandler first looks if there is a TOPDIR and if not
# then it would call getcwd().
# Previously, we chdir()ed to bbfile_loc, called the handler
# and finally chdir()ed back, a couple of thousand times. We now
# just fill in TOPDIR to point to bbfile_loc if there is no TOPDIR yet.
if not bb_data.getVar('TOPDIR', False):
chdir_back = True
bb_data.setVar('TOPDIR', bbfile_loc)
try:
if appends:
bb_data.setVar('__BBAPPEND', " ".join(appends))
bb_data = bb.parse.handle(bbfile, bb_data)
if chdir_back:
os.chdir(oldpath)
return bb_data
except:
if chdir_back:
os.chdir(oldpath)
raise
class NoCache(object):
def __init__(self, databuilder):
self.databuilder = databuilder
self.data = databuilder.data
def loadDataFull(self, virtualfn, appends):
"""
Return a complete set of data for fn.
To do this, we need to parse the file.
"""
logger.debug(1, "Parsing %s (full)" % virtualfn)
(fn, virtual, mc) = virtualfn2realfn(virtualfn)
bb_data = self.load_bbfile(virtualfn, appends, virtonly=True)
return bb_data[virtual]
def load_bbfile(self, bbfile, appends, virtonly = False):
"""
Load and parse one .bb build file
Return the data and whether parsing resulted in the file being skipped
"""
if virtonly:
(bbfile, virtual, mc) = virtualfn2realfn(bbfile)
bb_data = self.databuilder.mcdata[mc].createCopy()
bb_data.setVar("__ONLYFINALISE", virtual or "default")
datastores = parse_recipe(bb_data, bbfile, appends, mc)
return datastores
bb_data = self.data.createCopy()
datastores = parse_recipe(bb_data, bbfile, appends)
for mc in self.databuilder.mcdata:
if not mc:
continue
bb_data = self.databuilder.mcdata[mc].createCopy()
newstores = parse_recipe(bb_data, bbfile, appends, mc)
for ns in newstores:
datastores["multiconfig:%s:%s" % (mc, ns)] = newstores[ns]
return datastores
class Cache(NoCache):
class Cache(object):
"""
BitBake Cache implementation
"""
def __init__(self, databuilder, data_hash, caches_array):
super().__init__(databuilder)
data = databuilder.data
def __init__(self, data, data_hash, caches_array):
# Pass caches_array information into Cache Constructor
# It will be used later for deciding whether we
# need extra cache file dump/load support
# It will be used later for deciding whether we
# need extra cache file dump/load support
self.caches_array = caches_array
self.cachedir = data.getVar("CACHE")
self.cachedir = data.getVar("CACHE", True)
self.clean = set()
self.checked = set()
self.depends_cache = {}
self.data = None
self.data_fn = None
self.cacheclean = True
self.data_hash = data_hash
@@ -395,87 +282,78 @@ class Cache(NoCache):
self.has_cache = True
self.cachefile = getCacheFile(self.cachedir, "bb_cache.dat", self.data_hash)
logger.debug(1, "Cache dir: %s", self.cachedir)
logger.debug(1, "Using cache in '%s'", self.cachedir)
bb.utils.mkdirhier(self.cachedir)
cache_ok = True
if self.caches_array:
for cache_class in self.caches_array:
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
cache_ok = cache_ok and os.path.exists(cachefile)
cache_class.init_cacheData(self)
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
cache_ok = cache_ok and os.path.exists(cachefile)
cache_class.init_cacheData(self)
if cache_ok:
self.load_cachefile()
elif os.path.isfile(self.cachefile):
logger.info("Out of date cache found, rebuilding...")
else:
logger.debug(1, "Cache file %s not found, building..." % self.cachefile)
def load_cachefile(self):
# Firstly, using core cache file information for
# valid checking
with open(self.cachefile, "rb") as cachefile:
pickled = pickle.Unpickler(cachefile)
try:
cache_ver = pickled.load()
bitbake_ver = pickled.load()
except Exception:
logger.info('Invalid cache, rebuilding...')
return
if cache_ver != __cache_version__:
logger.info('Cache version mismatch, rebuilding...')
return
elif bitbake_ver != bb.__version__:
logger.info('Bitbake version mismatch, rebuilding...')
return
cachesize = 0
previous_progress = 0
previous_percent = 0
# Calculate the correct cachesize of all those cache files
for cache_class in self.caches_array:
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
with open(cachefile, "rb") as cachefile:
cachesize += os.fstat(cachefile.fileno()).st_size
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
with open(cachefile, "rb") as cachefile:
cachesize += os.fstat(cachefile.fileno()).st_size
bb.event.fire(bb.event.CacheLoadStarted(cachesize), self.data)
for cache_class in self.caches_array:
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
logger.debug(1, 'Loading cache file: %s' % cachefile)
with open(cachefile, "rb") as cachefile:
pickled = pickle.Unpickler(cachefile)
# Check cache version information
try:
cache_ver = pickled.load()
bitbake_ver = pickled.load()
except Exception:
logger.info('Invalid cache, rebuilding...')
return
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
with open(cachefile, "rb") as cachefile:
pickled = pickle.Unpickler(cachefile)
while cachefile:
try:
key = pickled.load()
value = pickled.load()
except Exception:
break
if self.depends_cache.has_key(key):
self.depends_cache[key].append(value)
else:
self.depends_cache[key] = [value]
# only fire events on even percentage boundaries
current_progress = cachefile.tell() + previous_progress
current_percent = 100 * current_progress / cachesize
if current_percent > previous_percent:
previous_percent = current_percent
bb.event.fire(bb.event.CacheLoadProgress(current_progress, cachesize),
self.data)
if cache_ver != __cache_version__:
logger.info('Cache version mismatch, rebuilding...')
return
elif bitbake_ver != bb.__version__:
logger.info('Bitbake version mismatch, rebuilding...')
return
# Load the rest of the cache file
current_progress = 0
while cachefile:
try:
key = pickled.load()
value = pickled.load()
except Exception:
break
if not isinstance(key, str):
bb.warn("%s from extras cache is not a string?" % key)
break
if not isinstance(value, RecipeInfoCommon):
bb.warn("%s from extras cache is not a RecipeInfoCommon class?" % value)
break
if key in self.depends_cache:
self.depends_cache[key].append(value)
else:
self.depends_cache[key] = [value]
# only fire events on even percentage boundaries
current_progress = cachefile.tell() + previous_progress
if current_progress > cachesize:
# we might have calculated incorrect total size because a file
# might've been written out just after we checked its size
cachesize = current_progress
current_percent = 100 * current_progress / cachesize
if current_percent > previous_percent:
previous_percent = current_percent
bb.event.fire(bb.event.CacheLoadProgress(current_progress, cachesize),
self.data)
previous_progress += current_progress
previous_progress += current_progress
# Note: depends cache number is corresponding to the parsing file numbers.
# The same file has several caches, still regarded as one item in the cache
@@ -483,33 +361,69 @@ class Cache(NoCache):
len(self.depends_cache)),
self.data)
def parse(self, filename, appends):
@staticmethod
def virtualfn2realfn(virtualfn):
"""
Convert a virtual file name to a real one + the associated subclass keyword
"""
fn = virtualfn
cls = ""
if virtualfn.startswith('virtual:'):
elems = virtualfn.split(':')
cls = ":".join(elems[1:-1])
fn = elems[-1]
return (fn, cls)
@staticmethod
def realfn2virtual(realfn, cls):
"""
Convert a real filename + the associated subclass keyword to a virtual filename
"""
if cls == "":
return realfn
return "virtual:" + cls + ":" + realfn
@classmethod
def loadDataFull(cls, virtualfn, appends, cfgData):
"""
Return a complete set of data for fn.
To do this, we need to parse the file.
"""
(fn, virtual) = cls.virtualfn2realfn(virtualfn)
logger.debug(1, "Parsing %s (full)", fn)
cfgData.setVar("__ONLYFINALISE", virtual or "default")
bb_data = cls.load_bbfile(fn, appends, cfgData)
return bb_data[virtual]
@classmethod
def parse(cls, filename, appends, configdata, caches_array):
"""Parse the specified filename, returning the recipe information"""
logger.debug(1, "Parsing %s", filename)
infos = []
datastores = self.load_bbfile(filename, appends)
datastores = cls.load_bbfile(filename, appends, configdata)
depends = []
variants = []
# Process the "real" fn last so we can store variants list
for variant, data in sorted(datastores.items(),
for variant, data in sorted(datastores.iteritems(),
key=lambda i: i[0],
reverse=True):
virtualfn = variant2virtual(filename, variant)
variants.append(variant)
virtualfn = cls.realfn2virtual(filename, variant)
depends = depends + (data.getVar("__depends", False) or [])
if depends and not variant:
data.setVar("__depends", depends)
if virtualfn == filename:
data.setVar("__VARIANTS", " ".join(variants))
info_array = []
for cache_class in self.caches_array:
info = cache_class(filename, data)
info_array.append(info)
for cache_class in caches_array:
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
info = cache_class(filename, data)
info_array.append(info)
infos.append((virtualfn, info_array))
return infos
def load(self, filename, appends):
def load(self, filename, appends, configdata):
"""Obtain the recipe information for the specified filename,
using cached values if available, otherwise parsing.
@@ -523,20 +437,21 @@ class Cache(NoCache):
# info_array item is a list of [CoreRecipeInfo, XXXRecipeInfo]
info_array = self.depends_cache[filename]
for variant in info_array[0].variants:
virtualfn = variant2virtual(filename, variant)
virtualfn = self.realfn2virtual(filename, variant)
infos.append((virtualfn, self.depends_cache[virtualfn]))
else:
logger.debug(1, "Parsing %s", filename)
return self.parse(filename, appends, configdata, self.caches_array)
return cached, infos
def loadData(self, fn, appends, cacheData):
def loadData(self, fn, appends, cfgData, cacheData):
"""Load the recipe info for the specified filename,
parsing and adding to the cache if necessary, and adding
the recipe information to the supplied CacheData instance."""
skipped, virtuals = 0, 0
cached, infos = self.load(fn, appends)
cached, infos = self.load(fn, appends, cfgData)
for virtualfn, info_array in infos:
if info_array[0].skipped:
logger.debug(1, "Skipping %s: %s", virtualfn, info_array[0].skipreason)
@@ -613,20 +528,7 @@ class Cache(NoCache):
if hasattr(info_array[0], 'file_checksums'):
for _, fl in info_array[0].file_checksums.items():
fl = fl.strip()
while fl:
# A .split() would be simpler but means spaces or colons in filenames would break
a = fl.find(":True")
b = fl.find(":False")
if ((a < 0) and b) or ((b > 0) and (b < a)):
f = fl[:b+6]
fl = fl[b+7:]
elif ((b < 0) and a) or ((a > 0) and (a < b)):
f = fl[:a+5]
fl = fl[a+6:]
else:
break
fl = fl.strip()
for f in fl.split():
if "*" in f:
continue
f, exist = f.split(":")
@@ -644,19 +546,16 @@ class Cache(NoCache):
invalid = False
for cls in info_array[0].variants:
virtualfn = variant2virtual(fn, cls)
virtualfn = self.realfn2virtual(fn, cls)
self.clean.add(virtualfn)
if virtualfn not in self.depends_cache:
logger.debug(2, "Cache: %s is not cached", virtualfn)
invalid = True
elif len(self.depends_cache[virtualfn]) != len(self.caches_array):
logger.debug(2, "Cache: Extra caches missing for %s?" % virtualfn)
invalid = True
# If any one of the variants is not present, mark as invalid for all
if invalid:
for cls in info_array[0].variants:
virtualfn = variant2virtual(fn, cls)
virtualfn = self.realfn2virtual(fn, cls)
if virtualfn in self.clean:
logger.debug(2, "Cache: Removing %s from cache", virtualfn)
self.clean.remove(virtualfn)
@@ -693,19 +592,30 @@ class Cache(NoCache):
logger.debug(2, "Cache is clean, not saving.")
return
file_dict = {}
pickler_dict = {}
for cache_class in self.caches_array:
cache_class_name = cache_class.__name__
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
with open(cachefile, "wb") as f:
p = pickle.Pickler(f, pickle.HIGHEST_PROTOCOL)
p.dump(__cache_version__)
p.dump(bb.__version__)
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cache_class_name = cache_class.__name__
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
file_dict[cache_class_name] = open(cachefile, "wb")
pickler_dict[cache_class_name] = pickle.Pickler(file_dict[cache_class_name], pickle.HIGHEST_PROTOCOL)
pickler_dict['CoreRecipeInfo'].dump(__cache_version__)
pickler_dict['CoreRecipeInfo'].dump(bb.__version__)
for key, info_array in self.depends_cache.items():
for info in info_array:
if isinstance(info, RecipeInfoCommon) and info.__class__.__name__ == cache_class_name:
p.dump(key)
p.dump(info)
try:
for key, info_array in self.depends_cache.iteritems():
for info in info_array:
if isinstance(info, RecipeInfoCommon):
cache_class_name = info.__class__.__name__
pickler_dict[cache_class_name].dump(key)
pickler_dict[cache_class_name].dump(info)
finally:
for cache_class in self.caches_array:
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cache_class_name = cache_class.__name__
file_dict[cache_class_name].close()
del self.depends_cache
@@ -733,13 +643,50 @@ class Cache(NoCache):
Save data we need into the cache
"""
realfn = virtualfn2realfn(file_name)[0]
realfn = self.virtualfn2realfn(file_name)[0]
info_array = []
for cache_class in self.caches_array:
info_array.append(cache_class(realfn, data))
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
info_array.append(cache_class(realfn, data))
self.add_info(file_name, info_array, cacheData, parsed)
@staticmethod
def load_bbfile(bbfile, appends, config):
"""
Load and parse one .bb build file
Return the data and whether parsing resulted in the file being skipped
"""
chdir_back = False
from bb import data, parse
# expand tmpdir to include this topdir
data.setVar('TMPDIR', data.getVar('TMPDIR', config, 1) or "", config)
bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
oldpath = os.path.abspath(os.getcwd())
parse.cached_mtime_noerror(bbfile_loc)
bb_data = data.init_db(config)
# The ConfHandler first looks if there is a TOPDIR and if not
# then it would call getcwd().
# Previously, we chdir()ed to bbfile_loc, called the handler
# and finally chdir()ed back, a couple of thousand times. We now
# just fill in TOPDIR to point to bbfile_loc if there is no TOPDIR yet.
if not data.getVar('TOPDIR', bb_data):
chdir_back = True
data.setVar('TOPDIR', bbfile_loc, bb_data)
try:
if appends:
data.setVar('__BBAPPEND', " ".join(appends), bb_data)
bb_data = parse.handle(bbfile, bb_data)
if chdir_back:
os.chdir(oldpath)
return bb_data
except:
if chdir_back:
os.chdir(oldpath)
raise
def init(cooker):
"""
@@ -769,9 +716,8 @@ class CacheData(object):
def __init__(self, caches_array):
self.caches_array = caches_array
for cache_class in self.caches_array:
if not issubclass(cache_class, RecipeInfoCommon):
bb.error("Extra cache data class %s should subclass RecipeInfoCommon class" % cache_class)
cache_class.init_cacheData(self)
if type(cache_class) is type and issubclass(cache_class, RecipeInfoCommon):
cache_class.init_cacheData(self)
# Direct cache variables
self.task_queues = {}
@@ -798,14 +744,13 @@ class MultiProcessCache(object):
self.cachedata = self.create_cachedata()
self.cachedata_extras = self.create_cachedata()
def init_cache(self, d, cache_file_name=None):
cachedir = (d.getVar("PERSISTENT_DIR") or
d.getVar("CACHE"))
def init_cache(self, d):
cachedir = (d.getVar("PERSISTENT_DIR", True) or
d.getVar("CACHE", True))
if cachedir in [None, '']:
return
bb.utils.mkdirhier(cachedir)
self.cachefile = os.path.join(cachedir,
cache_file_name or self.__class__.cache_file_name)
self.cachefile = os.path.join(cachedir, self.__class__.cache_file_name)
logger.debug(1, "Using cache in '%s'", self.cachefile)
glf = bb.utils.lockfile(self.cachefile + ".lock")
@@ -829,7 +774,7 @@ class MultiProcessCache(object):
data = [{}]
return data
def save_extras(self):
def save_extras(self, d):
if not self.cachefile:
return
@@ -859,7 +804,7 @@ class MultiProcessCache(object):
if h not in dest[j]:
dest[j][h] = source[j][h]
def save_merge(self):
def save_merge(self, d):
if not self.cachefile:
return
@@ -889,3 +834,4 @@ class MultiProcessCache(object):
p.dump([data, self.__class__.CACHE_VERSION])
bb.utils.unlockfile(glf)

View File

@@ -15,17 +15,22 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import glob
import operator
import os
import stat
import pickle
import bb.utils
import logging
from bb.cache import MultiProcessCache
logger = logging.getLogger("BitBake.Cache")
try:
import cPickle as pickle
except ImportError:
import pickle
logger.info("Importing cPickle failed. "
"Falling back to a very slow implementation.")
# mtime cache (non-persistent)
# based upon the assumption that files do not change during bitbake run
class FileMtimeCache(object):
@@ -83,54 +88,3 @@ class FileChecksumCache(MultiProcessCache):
dest[0][h] = source[0][h]
else:
dest[0][h] = source[0][h]
def get_checksums(self, filelist, pn):
"""Get checksums for a list of files"""
def checksum_file(f):
try:
checksum = self.get_checksum(f)
except OSError as e:
bb.warn("Unable to get checksum for %s SRC_URI entry %s: %s" % (pn, os.path.basename(f), e))
return None
return checksum
def checksum_dir(pth):
# Handle directories recursively
if pth == "/":
bb.fatal("Refusing to checksum /")
dirchecksums = []
for root, dirs, files in os.walk(pth):
for name in files:
fullpth = os.path.join(root, name)
checksum = checksum_file(fullpth)
if checksum:
dirchecksums.append((fullpth, checksum))
return dirchecksums
checksums = []
for pth in filelist.split():
exist = pth.split(":")[1]
if exist == "False":
continue
pth = pth.split(":")[0]
if '*' in pth:
# Handle globs
for f in glob.glob(pth):
if os.path.isdir(f):
if not os.path.islink(f):
checksums.extend(checksum_dir(f))
else:
checksum = checksum_file(f)
if checksum:
checksums.append((f, checksum))
elif os.path.isdir(pth):
if not os.path.islink(pth):
checksums.extend(checksum_dir(pth))
else:
checksum = checksum_file(pth)
if checksum:
checksums.append((pth, checksum))
checksums.sort(key=operator.itemgetter(1))
return checksums

View File

@@ -1,39 +1,21 @@
"""
BitBake code parser
Parses actual code (i.e. python and shell) for functions and in-line
expressions. Used mainly to determine dependencies on other functions
and variables within the BitBake metadata. Also provides a cache for
this information in order to speed up processing.
(Not to be confused with the code that parses the metadata itself,
see lib/bb/parse/ for that).
NOTE: if you change how the parsers gather information you will almost
certainly need to increment CodeParserCache.CACHE_VERSION below so that
any existing codeparser cache gets invalidated. Additionally you'll need
to increment __cache_version__ in cache.py in order to ensure that old
recipe caches don't trigger "Taskhash mismatch" errors.
"""
import ast
import sys
import codegen
import logging
import pickle
import bb.pysh as pysh
import os.path
import bb.utils, bb.data
import hashlib
from itertools import chain
from bb.pysh import pyshyacc, pyshlex, sherrors
from pysh import pyshyacc, pyshlex, sherrors
from bb.cache import MultiProcessCache
logger = logging.getLogger('BitBake.CodeParser')
def bbhash(s):
return hashlib.md5(s.encode("utf-8")).hexdigest()
try:
import cPickle as pickle
except ImportError:
import pickle
logger.info('Importing cPickle failed. Falling back to a very slow implementation.')
def check_indent(codestr):
"""If the code is indented, add a top level piece of code to 'remove' the indentation"""
@@ -46,10 +28,6 @@ def check_indent(codestr):
return codestr
if codestr[i-1] == "\t" or codestr[i-1] == " ":
if codestr[0] == "\n":
# Since we're adding a line, we need to remove one line of any empty padding
# to ensure line numbers are correct
codestr = codestr[1:]
return "if 1:\n" + codestr
return codestr
@@ -86,12 +64,11 @@ class SetCache(object):
new = []
for i in items:
new.append(sys.intern(i))
new.append(intern(i))
s = frozenset(new)
h = hash(s)
if h in self.setcache:
return self.setcache[h]
self.setcache[h] = s
if hash(s) in self.setcache:
return self.setcache[hash(s)]
self.setcache[hash(s)] = s
return s
codecache = SetCache()
@@ -115,9 +92,6 @@ class pythonCacheLine(object):
for c in sorted(self.contains.keys()):
l = l + (c, hash(self.contains[c]))
return hash(l)
def __repr__(self):
return " ".join([str(self.refs), str(self.execs), str(self.contains)])
class shellCacheLine(object):
def __init__(self, execs):
@@ -131,16 +105,10 @@ class shellCacheLine(object):
self.__init__(execs)
def __hash__(self):
return hash(self.execs)
def __repr__(self):
return str(self.execs)
class CodeParserCache(MultiProcessCache):
cache_file_name = "bb_codeparser.dat"
# NOTE: you must increment this if you change how the parsers gather information,
# so that an existing cache gets invalidated. Additionally you'll need
# to increment __cache_version__ in cache.py in order to ensure that old
# recipe caches don't trigger "Taskhash mismatch" errors.
CACHE_VERSION = 9
CACHE_VERSION = 7
def __init__(self):
MultiProcessCache.__init__(self)
@@ -171,10 +139,6 @@ class CodeParserCache(MultiProcessCache):
return cacheline
def init_cache(self, d):
# Check if we already have the caches
if self.pythoncache:
return
MultiProcessCache.init_cache(self, d)
# cachedata gets re-assigned in the parent
@@ -190,11 +154,11 @@ codeparsercache = CodeParserCache()
def parser_cache_init(d):
codeparsercache.init_cache(d)
def parser_cache_save():
codeparsercache.save_extras()
def parser_cache_save(d):
codeparsercache.save_extras(d)
def parser_cache_savemerge():
codeparsercache.save_merge()
def parser_cache_savemerge(d):
codeparsercache.save_merge(d)
Logger = logging.getLoggerClass()
class BufferedLogger(Logger):
@@ -209,15 +173,12 @@ class BufferedLogger(Logger):
def flush(self):
for record in self.buffer:
if self.target.isEnabledFor(record.levelno):
self.target.handle(record)
self.target.handle(record)
self.buffer = []
class PythonParser():
getvars = (".getVar", ".appendVar", ".prependVar")
getvarflags = (".getVarFlag", ".appendVarFlag", ".prependVarFlag")
containsfuncs = ("bb.utils.contains", "base_contains")
containsanyfuncs = ("bb.utils.contains_any", "bb.utils.filter")
containsfuncs = ("bb.utils.contains", "base_contains", "bb.utils.contains_any")
execfuncs = ("bb.build.exec_func", "bb.build.exec_task")
def warn(self, func, arg):
@@ -236,37 +197,17 @@ class PythonParser():
def visit_Call(self, node):
name = self.called_node_name(node.func)
if name and (name.endswith(self.getvars) or name.endswith(self.getvarflags) or name in self.containsfuncs or name in self.containsanyfuncs):
if name and name.endswith(self.getvars) or name in self.containsfuncs:
if isinstance(node.args[0], ast.Str):
varname = node.args[0].s
if name in self.containsfuncs and isinstance(node.args[1], ast.Str):
if varname not in self.contains:
self.contains[varname] = set()
self.contains[varname].add(node.args[1].s)
elif name in self.containsanyfuncs and isinstance(node.args[1], ast.Str):
if varname not in self.contains:
self.contains[varname] = set()
self.contains[varname].update(node.args[1].s.split())
elif name.endswith(self.getvarflags):
if isinstance(node.args[1], ast.Str):
self.references.add('%s[%s]' % (varname, node.args[1].s))
else:
self.warn(node.func, node.args[1])
else:
self.references.add(varname)
else:
self.references.add(node.args[0].s)
else:
self.warn(node.func, node.args[0])
elif name and name.endswith(".expand"):
if isinstance(node.args[0], ast.Str):
value = node.args[0].s
d = bb.data.init()
parser = d.expandWithRefs(value, self.name)
self.references |= parser.references
self.execs |= parser.execs
for varname in parser.contains:
if varname not in self.contains:
self.contains[varname] = set()
self.contains[varname] |= parser.contains[varname]
elif name in self.execfuncs:
if isinstance(node.args[0], ast.Str):
self.var_execs.add(node.args[0].s)
@@ -289,7 +230,6 @@ class PythonParser():
break
def __init__(self, name, log):
self.name = name
self.var_execs = set()
self.contains = {}
self.execs = set()
@@ -299,11 +239,8 @@ class PythonParser():
self.unhandled_message = "in call of %s, argument '%s' is not a string literal"
self.unhandled_message = "while parsing %s, %s" % (name, self.unhandled_message)
def parse_python(self, node, lineno=0, filename="<string>"):
if not node or not node.strip():
return
h = bbhash(str(node))
def parse_python(self, node):
h = hash(str(node))
if h in codeparsercache.pythoncache:
self.references = set(codeparsercache.pythoncache[h].refs)
@@ -321,9 +258,7 @@ class PythonParser():
self.contains[i] = set(codeparsercache.pythoncacheextras[h].contains[i])
return
# We can't add to the linenumbers for compile, we can pad to the correct number of blank lines though
node = "\n" * int(lineno) + node
code = compile(check_indent(str(node)), filename, "exec",
code = compile(check_indent(str(node)), "<string>", "exec",
ast.PyCF_ONLY_AST)
for n in ast.walk(code):
@@ -348,7 +283,7 @@ class ShellParser():
commands it executes.
"""
h = bbhash(str(value))
h = hash(str(value))
if h in codeparsercache.shellcache:
self.execs = set(codeparsercache.shellcache[h].execs)
@@ -371,7 +306,8 @@ class ShellParser():
except pyshlex.NeedMore:
raise sherrors.ShellSyntaxError("Unexpected EOF")
self.process_tokens(tokens)
for token in tokens:
self.process_tokens(token)
def process_tokens(self, tokens):
"""Process a supplied portion of the syntax tree as returned by
@@ -417,24 +353,18 @@ class ShellParser():
"case_clause": case_clause,
}
def process_token_list(tokens):
for token in tokens:
if isinstance(token, list):
process_token_list(token)
continue
name, value = token
try:
more_tokens, words = token_handlers[name](value)
except KeyError:
raise NotImplementedError("Unsupported token type " + name)
for token in tokens:
name, value = token
try:
more_tokens, words = token_handlers[name](value)
except KeyError:
raise NotImplementedError("Unsupported token type " + name)
if more_tokens:
self.process_tokens(more_tokens)
if more_tokens:
self.process_tokens(more_tokens)
if words:
self.process_words(words)
process_token_list(tokens)
if words:
self.process_words(words)
def process_words(self, words):
"""Process a set of 'words' in pyshyacc parlance, which includes

View File

@@ -28,15 +28,8 @@ and must not trigger events, directly or indirectly.
Commands are queued in a CommandQueue
"""
from collections import OrderedDict, defaultdict
import bb.event
import bb.cooker
import bb.remotedata
class DataStoreConnectionHandle(object):
def __init__(self, dsindex=0):
self.dsindex = dsindex
class CommandCompleted(bb.event.Event):
pass
@@ -50,8 +43,6 @@ class CommandFailed(CommandExit):
def __init__(self, message):
self.error = message
CommandExit.__init__(self, 1)
def __str__(self):
return "Command execution failed: %s" % self.error
class CommandError(Exception):
pass
@@ -64,7 +55,6 @@ class Command:
self.cooker = cooker
self.cmds_sync = CommandsSync()
self.cmds_async = CommandsAsync()
self.remotedatastores = bb.remotedata.RemoteDatastores(cooker)
# FIXME Add lock for this
self.currentAsyncCommand = None
@@ -78,13 +68,10 @@ class Command:
if not hasattr(command_method, 'readonly') or False == getattr(command_method, 'readonly'):
return None, "Not able to execute not readonly commands in readonly mode"
try:
self.cooker.process_inotify_updates()
if getattr(command_method, 'needconfig', True):
self.cooker.updateCacheSync()
result = command_method(self, commandline)
except CommandError as exc:
return None, exc.args[0]
except (Exception, SystemExit):
except Exception:
import traceback
return None, traceback.format_exc()
else:
@@ -99,7 +86,6 @@ class Command:
def runAsyncCommand(self):
try:
self.cooker.process_inotify_updates()
if self.cooker.state in (bb.cooker.state.error, bb.cooker.state.shutdown, bb.cooker.state.forceshutdown):
# updateCache will trigger a shutdown of the parser
# and then raise BBHandledException triggering an exit
@@ -122,7 +108,7 @@ class Command:
return False
except SystemExit as exc:
arg = exc.args[0]
if isinstance(arg, str):
if isinstance(arg, basestring):
self.finishAsyncCommand(arg)
else:
self.finishAsyncCommand("Exited with %s" % arg)
@@ -137,23 +123,14 @@ class Command:
def finishAsyncCommand(self, msg=None, code=None):
if msg or msg == "":
bb.event.fire(CommandFailed(msg), self.cooker.data)
bb.event.fire(CommandFailed(msg), self.cooker.expanded_data)
elif code:
bb.event.fire(CommandExit(code), self.cooker.data)
bb.event.fire(CommandExit(code), self.cooker.expanded_data)
else:
bb.event.fire(CommandCompleted(), self.cooker.data)
bb.event.fire(CommandCompleted(), self.cooker.expanded_data)
self.currentAsyncCommand = None
self.cooker.finishcommand()
def reset(self):
self.remotedatastores = bb.remotedata.RemoteDatastores(self.cooker)
def split_mc_pn(pn):
if pn.startswith("multiconfig:"):
_, mc, pn = pn.split(":", 2)
return (mc, pn)
return ('', pn)
class CommandsSync:
"""
A class of synchronous commands
@@ -200,19 +177,8 @@ class CommandsSync:
"""
varname = params[0]
value = str(params[1])
command.cooker.extraconfigdata[varname] = value
command.cooker.data.setVar(varname, value)
def getSetVariable(self, command, params):
"""
Read the value of a variable from data and set it into the datastore
which effectively expands and locks the value.
"""
varname = params[0]
result = self.getVariable(command, params)
command.cooker.data.setVar(varname, result)
return result
def setConfig(self, command, params):
"""
Set the value of variable in configuration
@@ -238,17 +204,54 @@ class CommandsSync:
postfiles = params[1].split()
command.cooker.configuration.prefile = prefiles
command.cooker.configuration.postfile = postfiles
setPrePostConfFiles.needconfig = False
def getCpuCount(self, command, params):
"""
Get the CPU count on the bitbake server
"""
return bb.utils.cpu_count()
getCpuCount.readonly = True
def matchFile(self, command, params):
fMatch = params[0]
return command.cooker.matchFile(fMatch)
matchFile.needconfig = False
def getUIHandlerNum(self, command, params):
return bb.event.get_uihandler()
getUIHandlerNum.needconfig = False
getUIHandlerNum.readonly = True
def generateNewImage(self, command, params):
image = params[0]
base_image = params[1]
package_queue = params[2]
timestamp = params[3]
description = params[4]
return command.cooker.generateNewImage(image, base_image,
package_queue, timestamp, description)
def ensureDir(self, command, params):
directory = params[0]
bb.utils.mkdirhier(directory)
def setVarFile(self, command, params):
"""
Save a variable in a file; used for saving in a configuration file
"""
var = params[0]
val = params[1]
default_file = params[2]
op = params[3]
command.cooker.modifyConfigurationVar(var, val, default_file, op)
def removeVarFile(self, command, params):
"""
Remove a variable declaration from a file
"""
var = params[0]
command.cooker.removeConfigurationVar(var)
def createConfigFile(self, command, params):
"""
Create an extra configuration file
"""
name = params[0]
command.cooker.createConfigFile(name)
def setEventMask(self, command, params):
handlerNum = params[0]
@@ -256,8 +259,6 @@ class CommandsSync:
debug_domains = params[2]
mask = params[3]
return bb.event.set_UIHmask(handlerNum, llevel, debug_domains, mask)
setEventMask.needconfig = False
setEventMask.readonly = True
def setFeatures(self, command, params):
"""
@@ -265,7 +266,7 @@ class CommandsSync:
"""
features = params[0]
command.cooker.setFeatures(features)
setFeatures.needconfig = False
# although we change the internal state of the cooker, this is transparent since
# we always take and leave the cooker in state.initial
setFeatures.readonly = True
@@ -273,306 +274,7 @@ class CommandsSync:
def updateConfig(self, command, params):
options = params[0]
environment = params[1]
cmdline = params[2]
command.cooker.updateConfigOpts(options, environment, cmdline)
updateConfig.needconfig = False
def parseConfiguration(self, command, params):
"""Instruct bitbake to parse its configuration
NOTE: it is only necessary to call this if you aren't calling any normal action
(otherwise parsing is taken care of automatically)
"""
command.cooker.parseConfiguration()
parseConfiguration.needconfig = False
def getLayerPriorities(self, command, params):
command.cooker.parseConfiguration()
ret = []
# regex objects cannot be marshalled by xmlrpc
for collection, pattern, regex, pri in command.cooker.bbfile_config_priorities:
ret.append((collection, pattern, regex.pattern, pri))
return ret
getLayerPriorities.readonly = True
def getRecipes(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return list(command.cooker.recipecaches[mc].pkg_pn.items())
getRecipes.readonly = True
def getRecipeDepends(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return list(command.cooker.recipecaches[mc].deps.items())
getRecipeDepends.readonly = True
def getRecipeVersions(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].pkg_pepvpr
getRecipeVersions.readonly = True
def getRecipeProvides(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].fn_provides
getRecipeProvides.readonly = True
def getRecipePackages(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].packages
getRecipePackages.readonly = True
def getRecipePackagesDynamic(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].packages_dynamic
getRecipePackagesDynamic.readonly = True
def getRProviders(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].rproviders
getRProviders.readonly = True
def getRuntimeDepends(self, command, params):
ret = []
try:
mc = params[0]
except IndexError:
mc = ''
rundeps = command.cooker.recipecaches[mc].rundeps
for key, value in rundeps.items():
if isinstance(value, defaultdict):
value = dict(value)
ret.append((key, value))
return ret
getRuntimeDepends.readonly = True
def getRuntimeRecommends(self, command, params):
ret = []
try:
mc = params[0]
except IndexError:
mc = ''
runrecs = command.cooker.recipecaches[mc].runrecs
for key, value in runrecs.items():
if isinstance(value, defaultdict):
value = dict(value)
ret.append((key, value))
return ret
getRuntimeRecommends.readonly = True
def getRecipeInherits(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].inherits
getRecipeInherits.readonly = True
def getBbFilePriority(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].bbfile_priority
getBbFilePriority.readonly = True
def getDefaultPreference(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return command.cooker.recipecaches[mc].pkg_dp
getDefaultPreference.readonly = True
def getSkippedRecipes(self, command, params):
# Return list sorted by reverse priority order
import bb.cache
skipdict = OrderedDict(sorted(command.cooker.skiplist.items(),
key=lambda x: (-command.cooker.collection.calc_bbfile_priority(bb.cache.virtualfn2realfn(x[0])[0]), x[0])))
return list(skipdict.items())
getSkippedRecipes.readonly = True
def getOverlayedRecipes(self, command, params):
return list(command.cooker.collection.overlayed.items())
getOverlayedRecipes.readonly = True
def getFileAppends(self, command, params):
fn = params[0]
return command.cooker.collection.get_file_appends(fn)
getFileAppends.readonly = True
def getAllAppends(self, command, params):
return command.cooker.collection.bbappends
getAllAppends.readonly = True
def findProviders(self, command, params):
return command.cooker.findProviders()
findProviders.readonly = True
def findBestProvider(self, command, params):
(mc, pn) = split_mc_pn(params[0])
return command.cooker.findBestProvider(pn, mc)
findBestProvider.readonly = True
def allProviders(self, command, params):
try:
mc = params[0]
except IndexError:
mc = ''
return list(bb.providers.allProviders(command.cooker.recipecaches[mc]).items())
allProviders.readonly = True
def getRuntimeProviders(self, command, params):
rprovide = params[0]
try:
mc = params[1]
except IndexError:
mc = ''
all_p = bb.providers.getRuntimeProviders(command.cooker.recipecaches[mc], rprovide)
if all_p:
best = bb.providers.filterProvidersRunTime(all_p, rprovide,
command.cooker.data,
command.cooker.recipecaches[mc])[0][0]
else:
best = None
return all_p, best
getRuntimeProviders.readonly = True
def dataStoreConnectorFindVar(self, command, params):
dsindex = params[0]
name = params[1]
datastore = command.remotedatastores[dsindex]
value, overridedata = datastore._findVar(name)
if value:
content = value.get('_content', None)
if isinstance(content, bb.data_smart.DataSmart):
# Value is a datastore (e.g. BB_ORIGENV) - need to handle this carefully
idx = command.remotedatastores.check_store(content, True)
return {'_content': DataStoreConnectionHandle(idx),
'_connector_origtype': 'DataStoreConnectionHandle',
'_connector_overrides': overridedata}
elif isinstance(content, set):
return {'_content': list(content),
'_connector_origtype': 'set',
'_connector_overrides': overridedata}
else:
value['_connector_overrides'] = overridedata
else:
value = {}
value['_connector_overrides'] = overridedata
return value
dataStoreConnectorFindVar.readonly = True
def dataStoreConnectorGetKeys(self, command, params):
dsindex = params[0]
datastore = command.remotedatastores[dsindex]
return list(datastore.keys())
dataStoreConnectorGetKeys.readonly = True
def dataStoreConnectorGetVarHistory(self, command, params):
dsindex = params[0]
name = params[1]
datastore = command.remotedatastores[dsindex]
return datastore.varhistory.variable(name)
dataStoreConnectorGetVarHistory.readonly = True
def dataStoreConnectorExpandPythonRef(self, command, params):
config_data_dict = params[0]
varname = params[1]
expr = params[2]
config_data = command.remotedatastores.receive_datastore(config_data_dict)
varparse = bb.data_smart.VariableParse(varname, config_data)
return varparse.python_sub(expr)
def dataStoreConnectorRelease(self, command, params):
dsindex = params[0]
if dsindex <= 0:
raise CommandError('dataStoreConnectorRelease: invalid index %d' % dsindex)
command.remotedatastores.release(dsindex)
def dataStoreConnectorSetVarFlag(self, command, params):
dsindex = params[0]
name = params[1]
flag = params[2]
value = params[3]
datastore = command.remotedatastores[dsindex]
datastore.setVarFlag(name, flag, value)
def dataStoreConnectorDelVar(self, command, params):
dsindex = params[0]
name = params[1]
datastore = command.remotedatastores[dsindex]
if len(params) > 2:
flag = params[2]
datastore.delVarFlag(name, flag)
else:
datastore.delVar(name)
def dataStoreConnectorRenameVar(self, command, params):
dsindex = params[0]
name = params[1]
newname = params[2]
datastore = command.remotedatastores[dsindex]
datastore.renameVar(name, newname)
def parseRecipeFile(self, command, params):
"""
Parse the specified recipe file (with or without bbappends)
and return a datastore object representing the environment
for the recipe.
"""
fn = params[0]
appends = params[1]
appendlist = params[2]
if len(params) > 3:
config_data_dict = params[3]
config_data = command.remotedatastores.receive_datastore(config_data_dict)
else:
config_data = None
if appends:
if appendlist is not None:
appendfiles = appendlist
else:
appendfiles = command.cooker.collection.get_file_appends(fn)
else:
appendfiles = []
# We are calling bb.cache locally here rather than on the server,
# but that's OK because it doesn't actually need anything from
# the server barring the global datastore (which we have a remote
# version of)
if config_data:
# We have to use a different function here if we're passing in a datastore
# NOTE: we took a copy above, so we don't do it here again
envdata = bb.cache.parse_recipe(config_data, fn, appendfiles)['']
else:
# Use the standard path
parser = bb.cache.NoCache(command.cooker.databuilder)
envdata = parser.loadDataFull(fn, appendfiles)
idx = command.remotedatastores.store(envdata)
return DataStoreConnectionHandle(idx)
parseRecipeFile.readonly = True
command.cooker.updateConfigOpts(options, environment)
class CommandsAsync:
"""
@@ -587,15 +289,8 @@ class CommandsAsync:
"""
bfile = params[0]
task = params[1]
if len(params) > 2:
internal = params[2]
else:
internal = False
if internal:
command.cooker.buildFileInternal(bfile, task, fireevents=False, quietlog=True)
else:
command.cooker.buildFile(bfile, task)
command.cooker.buildFile(bfile, task)
buildFile.needcache = False
def buildTargets(self, command, params):
@@ -645,6 +340,17 @@ class CommandsAsync:
command.finishAsyncCommand()
generateTargetsTree.needcache = True
def findCoreBaseFiles(self, command, params):
"""
Find certain files in COREBASE directory. i.e. Layers
"""
subdir = params[0]
filename = params[1]
command.cooker.findCoreBaseFiles(subdir, filename)
command.finishAsyncCommand()
findCoreBaseFiles.needcache = False
def findConfigFiles(self, command, params):
"""
Find config files which provide appropriate values
@@ -744,22 +450,3 @@ class CommandsAsync:
command.finishAsyncCommand()
resetCooker.needcache = False
def clientComplete(self, command, params):
"""
Do the right thing when the controlling client exits
"""
command.cooker.clientComplete()
command.finishAsyncCommand()
clientComplete.needcache = False
def findSigInfo(self, command, params):
"""
Find signature info files via the signature generator
"""
pn = params[0]
taskname = params[1]
sigs = params[2]
res = bb.siggen.find_siginfo(pn, taskname, sigs, command.cooker.data)
bb.event.fire(bb.event.FindSigInfoResult(res), command.cooker.data)
command.finishAsyncCommand()
findSigInfo.needcache = False

File diff suppressed because it is too large Load Diff

View File

@@ -22,11 +22,9 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import logging
import os
import re
import sys
import os, sys
from functools import wraps
import logging
import bb
from bb import data
import bb.parse
@@ -41,6 +39,10 @@ class ConfigParameters(object):
self.options.pkgs_to_build = targets or []
self.options.tracking = False
if hasattr(self.options, "show_environment") and self.options.show_environment:
self.options.tracking = True
for key, val in self.options.__dict__.items():
setattr(self, key, val)
@@ -61,23 +63,22 @@ class ConfigParameters(object):
raise Exception("Unable to set configuration option 'cmd' on the server: %s" % error)
if not self.options.pkgs_to_build:
bbpkgs, error = server.runCommand(["getVariable", "BBTARGETS"])
bbpkgs, error = server.runCommand(["getVariable", "BBPKGS"])
if error:
raise Exception("Unable to get the value of BBTARGETS from the server: %s" % error)
raise Exception("Unable to get the value of BBPKGS from the server: %s" % error)
if bbpkgs:
self.options.pkgs_to_build.extend(bbpkgs.split())
def updateToServer(self, server, environment):
options = {}
for o in ["abort", "force", "invalidate_stamp",
"verbose", "debug", "dry_run", "dump_signatures",
"debug_domains", "extra_assume_provided", "profile",
"prefile", "postfile", "server_timeout"]:
for o in ["abort", "tryaltconfigs", "force", "invalidate_stamp",
"verbose", "debug", "dry_run", "dump_signatures",
"debug_domains", "extra_assume_provided", "profile"]:
options[o] = getattr(self.options, o)
ret, error = server.runCommand(["updateConfig", options, environment, sys.argv])
ret, error = server.runCommand(["updateConfig", options, environment])
if error:
raise Exception("Unable to update the server configuration with local parameters: %s" % error)
raise Exception("Unable to update the server configuration with local parameters: %s" % error)
def parseActions(self):
# Parse any commandline into actions
@@ -133,18 +134,12 @@ class CookerConfiguration(object):
self.force = False
self.profile = False
self.nosetscene = False
self.setsceneonly = False
self.invalidate_stamp = False
self.dump_signatures = []
self.dry_run = False
self.tracking = False
self.xmlrpcinterface = []
self.server_timeout = None
self.interface = []
self.writeeventlog = False
self.server_only = False
self.limited_deps = False
self.runall = []
self.runonly = []
self.env = {}
@@ -153,6 +148,7 @@ class CookerConfiguration(object):
if key in parameters.options.__dict__:
setattr(self, key, parameters.options.__dict__[key])
self.env = parameters.environment.copy()
self.tracking = parameters.tracking
def setServerRegIdleCallback(self, srcb):
self.server_register_idlecallback = srcb
@@ -168,7 +164,7 @@ class CookerConfiguration(object):
def __setstate__(self,state):
for k in state:
setattr(self, k, state[k])
setattr(self, k, state[k])
def catch_parse_error(func):
@@ -177,26 +173,11 @@ def catch_parse_error(func):
def wrapped(fn, *args):
try:
return func(fn, *args)
except IOError as exc:
except (IOError, bb.parse.ParseError, bb.data_smart.ExpansionError) as exc:
import traceback
parselog.critical(traceback.format_exc())
parselog.critical( traceback.format_exc())
parselog.critical("Unable to parse %s: %s" % (fn, exc))
sys.exit(1)
except bb.data_smart.ExpansionError as exc:
import traceback
bbdir = os.path.dirname(__file__) + os.sep
exc_class, exc, tb = sys.exc_info()
for tb in iter(lambda: tb.tb_next, None):
# Skip frames in bitbake itself, we only want the metadata
fn, _, _, _ = traceback.extract_tb(tb, 1)[0]
if not fn.startswith(bbdir):
break
parselog.critical("Unable to parse %s" % fn, exc_info=(exc_class, exc, tb))
sys.exit(1)
except bb.parse.ParseError as exc:
parselog.critical(str(exc))
sys.exit(1)
return wrapped
@catch_parse_error
@@ -210,7 +191,7 @@ def _inherit(bbclass, data):
def findConfigFile(configfile, data):
search = []
bbpath = data.getVar("BBPATH")
bbpath = data.getVar("BBPATH", True)
if bbpath:
for i in bbpath.split(":"):
search.append(os.path.join(i, "conf", configfile))
@@ -225,27 +206,6 @@ def findConfigFile(configfile, data):
return None
#
# We search for a conf/bblayers.conf under an entry in BBPATH or in cwd working
# up to /. If that fails, we search for a conf/bitbake.conf in BBPATH.
#
def findTopdir():
d = bb.data.init()
bbpath = None
if 'BBPATH' in os.environ:
bbpath = os.environ['BBPATH']
d.setVar('BBPATH', bbpath)
layerconf = findConfigFile("bblayers.conf", d)
if layerconf:
return os.path.dirname(os.path.dirname(layerconf))
if bbpath:
bitbakeconf = bb.utils.which(bbpath, "conf/bitbake.conf")
if bitbakeconf:
return os.path.dirname(os.path.dirname(bitbakeconf))
return None
class CookerDataBuilder(object):
def __init__(self, cookercfg, worker = False):
@@ -256,9 +216,9 @@ class CookerDataBuilder(object):
bb.utils.set_context(bb.utils.clean_context())
bb.event.set_class_handlers(bb.event.clean_class_handlers())
self.basedata = bb.data.init()
self.data = bb.data.init()
if self.tracking:
self.basedata.enableTracking()
self.data.enableTracking()
# Keep a datastore of the initial environment variables and their
# values from when BitBake was launched to enable child processes
@@ -269,51 +229,16 @@ class CookerDataBuilder(object):
self.savedenv.setVar(k, cookercfg.env[k])
filtered_keys = bb.utils.approved_variables()
bb.data.inheritFromOS(self.basedata, self.savedenv, filtered_keys)
self.basedata.setVar("BB_ORIGENV", self.savedenv)
bb.data.inheritFromOS(self.data, self.savedenv, filtered_keys)
self.data.setVar("BB_ORIGENV", self.savedenv)
if worker:
self.basedata.setVar("BB_WORKERCONTEXT", "1")
self.data = self.basedata
self.mcdata = {}
self.data.setVar("BB_WORKERCONTEXT", "1")
def parseBaseConfiguration(self):
try:
bb.parse.init_parser(self.basedata)
self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles)
if self.data.getVar("BB_WORKERCONTEXT", False) is None:
bb.fetch.fetcher_init(self.data)
bb.codeparser.parser_cache_init(self.data)
bb.event.fire(bb.event.ConfigParsed(), self.data)
reparse_cnt = 0
while self.data.getVar("BB_INVALIDCONF", False) is True:
if reparse_cnt > 20:
logger.error("Configuration has been re-parsed over 20 times, "
"breaking out of the loop...")
raise Exception("Too deep config re-parse loop. Check locations where "
"BB_INVALIDCONF is being set (ConfigParsed event handlers)")
self.data.setVar("BB_INVALIDCONF", False)
self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles)
reparse_cnt += 1
bb.event.fire(bb.event.ConfigParsed(), self.data)
bb.parse.init_parser(self.data)
self.data_hash = self.data.get_hash()
self.mcdata[''] = self.data
multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split()
for config in multiconfig:
mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config)
bb.event.fire(bb.event.ConfigParsed(), mcdata)
self.mcdata[config] = mcdata
if multiconfig:
bb.event.fire(bb.event.MultiConfigParsed(self.mcdata), self.data)
except (SyntaxError, bb.BBHandledException):
self.parseConfigurationFiles(self.prefiles, self.postfiles)
except SyntaxError:
raise bb.BBHandledException
except bb.data_smart.ExpansionError as e:
logger.error(str(e))
@@ -322,24 +247,12 @@ class CookerDataBuilder(object):
logger.exception("Error parsing configuration files")
raise bb.BBHandledException
# Create a copy so we can reset at a later date when UIs disconnect
self.origdata = self.data
self.data = bb.data.createCopy(self.origdata)
self.mcdata[''] = self.data
def reset(self):
# We may not have run parseBaseConfiguration() yet
if not hasattr(self, 'origdata'):
return
self.data = bb.data.createCopy(self.origdata)
self.mcdata[''] = self.data
def _findLayerConf(self, data):
return findConfigFile("bblayers.conf", data)
def parseConfigurationFiles(self, prefiles, postfiles, mc = "default"):
data = bb.data.createCopy(self.basedata)
data.setVar("BB_CURRENT_MC", mc)
def parseConfigurationFiles(self, prefiles, postfiles):
data = self.data
bb.parse.init_parser(data)
# Parse files for loading *before* bitbake.conf and any includes
for f in prefiles:
@@ -353,53 +266,18 @@ class CookerDataBuilder(object):
data.setVar("TOPDIR", os.path.dirname(os.path.dirname(layerconf)))
data = parse_config_file(layerconf, data)
layers = (data.getVar('BBLAYERS') or "").split()
layers = (data.getVar('BBLAYERS', True) or "").split()
data = bb.data.createCopy(data)
approved = bb.utils.approved_variables()
for layer in layers:
if not os.path.isdir(layer):
parselog.critical("Layer directory '%s' does not exist! "
"Please check BBLAYERS in %s" % (layer, layerconf))
sys.exit(1)
parselog.debug(2, "Adding layer %s", layer)
if 'HOME' in approved and '~' in layer:
layer = os.path.expanduser(layer)
if layer.endswith('/'):
layer = layer.rstrip('/')
data.setVar('LAYERDIR', layer)
data.setVar('LAYERDIR_RE', re.escape(layer))
data = parse_config_file(os.path.join(layer, "conf", "layer.conf"), data)
data.expandVarref('LAYERDIR')
data.expandVarref('LAYERDIR_RE')
data.delVar('LAYERDIR_RE')
data.delVar('LAYERDIR')
bbfiles_dynamic = (data.getVar('BBFILES_DYNAMIC') or "").split()
collections = (data.getVar('BBFILE_COLLECTIONS') or "").split()
invalid = []
for entry in bbfiles_dynamic:
parts = entry.split(":", 1)
if len(parts) != 2:
invalid.append(entry)
continue
l, f = parts
if l in collections:
data.appendVar("BBFILES", " " + f)
if invalid:
bb.fatal("BBFILES_DYNAMIC entries must be of the form <collection name>:<filename pattern>, not:\n %s" % "\n ".join(invalid))
layerseries = set((data.getVar("LAYERSERIES_CORENAMES") or "").split())
for c in collections:
compat = set((data.getVar("LAYERSERIES_COMPAT_%s" % c) or "").split())
if compat and not (compat & layerseries):
bb.fatal("Layer %s is not compatible with the core layer which only supports these series: %s (layer is compatible with %s)"
% (c, " ".join(layerseries), " ".join(compat)))
elif not compat and not data.getVar("BB_WORKERCONTEXT"):
bb.warn("Layer %s should set LAYERSERIES_COMPAT_%s in its conf/layer.conf file to list the core layer names it is compatible with." % (c, c))
if not data.getVar("BBPATH"):
if not data.getVar("BBPATH", True):
msg = "The BBPATH variable is not set"
if not layerconf:
msg += (" and bitbake did not find a conf/bblayers.conf file in"
@@ -414,21 +292,29 @@ class CookerDataBuilder(object):
data = parse_config_file(p, data)
# Handle any INHERITs and inherit the base class
bbclasses = ["base"] + (data.getVar('INHERIT') or "").split()
bbclasses = ["base"] + (data.getVar('INHERIT', True) or "").split()
for bbclass in bbclasses:
data = _inherit(bbclass, data)
# Nomally we only register event handlers at the end of parsing .bb files
# We register any handlers we've found so far here...
for var in data.getVar('__BBHANDLERS', False) or []:
handlerfn = data.getVarFlag(var, "filename", False)
if not handlerfn:
parselog.critical("Undefined event handler function '%s'" % var)
sys.exit(1)
handlerln = int(data.getVarFlag(var, "lineno", False))
bb.event.register(var, data.getVar(var, False), (data.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln)
for var in data.getVar('__BBHANDLERS') or []:
bb.event.register(var, data.getVar(var), (data.getVarFlag(var, "eventmask", True) or "").split())
if data.getVar("BB_WORKERCONTEXT", False) is None:
bb.fetch.fetcher_init(data)
bb.codeparser.parser_cache_init(data)
bb.event.fire(bb.event.ConfigParsed(), data)
if data.getVar("BB_INVALIDCONF") is True:
data.setVar("BB_INVALIDCONF", False)
self.parseConfigurationFiles(self.prefiles, self.postfiles)
return
bb.parse.init_parser(data)
data.setVar('BBINCLUDED',bb.parse.get_file_depends(data))
self.data = data
self.data_hash = data.get_hash()
return data

View File

@@ -1,14 +1,48 @@
"""
Python Daemonizing helper
Originally based on code Copyright (C) 2005 Chad J. Schroeder but now heavily modified
to allow a function to be daemonized and return for bitbake use by Richard Purdie
Configurable daemon behaviors:
1.) The current working directory set to the "/" directory.
2.) The current file creation mode mask set to 0.
3.) Close all open files (1024).
4.) Redirect standard I/O streams to "/dev/null".
A failed call to fork() now raises an exception.
References:
1) Advanced Programming in the Unix Environment: W. Richard Stevens
http://www.apuebook.com/apue3e.html
2) The Linux Programming Interface: Michael Kerrisk
http://man7.org/tlpi/index.html
3) Unix Programming Frequently Asked Questions:
http://www.faqs.org/faqs/unix-faq/programmer/faq/
Modified to allow a function to be daemonized and return for
bitbake use by Richard Purdie
"""
import os
import sys
import io
import traceback
__author__ = "Chad J. Schroeder"
__copyright__ = "Copyright (C) 2005 Chad J. Schroeder"
__version__ = "0.2"
# Standard Python modules.
import os # Miscellaneous OS interfaces.
import sys # System-specific parameters and functions.
# Default daemon parameters.
# File mode creation mask of the daemon.
# For BitBake's children, we do want to inherit the parent umask.
UMASK = None
# Default maximum for the number of available file descriptors.
MAXFD = 1024
# The standard I/O file descriptors are redirected to /dev/null by default.
if (hasattr(os, "devnull")):
REDIRECT_TO = os.devnull
else:
REDIRECT_TO = "/dev/null"
def createDaemon(function, logfile):
"""
@@ -31,6 +65,36 @@ def createDaemon(function, logfile):
# leader of the new process group, we call os.setsid(). The process is
# also guaranteed not to have a controlling terminal.
os.setsid()
# Is ignoring SIGHUP necessary?
#
# It's often suggested that the SIGHUP signal should be ignored before
# the second fork to avoid premature termination of the process. The
# reason is that when the first child terminates, all processes, e.g.
# the second child, in the orphaned group will be sent a SIGHUP.
#
# "However, as part of the session management system, there are exactly
# two cases where SIGHUP is sent on the death of a process:
#
# 1) When the process that dies is the session leader of a session that
# is attached to a terminal device, SIGHUP is sent to all processes
# in the foreground process group of that terminal device.
# 2) When the death of a process causes a process group to become
# orphaned, and one or more processes in the orphaned group are
# stopped, then SIGHUP and SIGCONT are sent to all members of the
# orphaned group." [2]
#
# The first case can be ignored since the child is guaranteed not to have
# a controlling terminal. The second case isn't so easy to dismiss.
# The process group is orphaned when the first child terminates and
# POSIX.1 requires that every STOPPED process in an orphaned process
# group be sent a SIGHUP signal followed by a SIGCONT signal. Since the
# second child is not STOPPED though, we can safely forego ignoring the
# SIGHUP signal. In any case, there are no ill-effects if it is ignored.
#
# import signal # Set handlers for asynchronous events.
# signal.signal(signal.SIGHUP, signal.SIG_IGN)
try:
# Fork a second child and exit immediately to prevent zombies. This
# causes the second child process to be orphaned, making the init
@@ -44,39 +108,86 @@ def createDaemon(function, logfile):
except OSError as e:
raise Exception("%s [%d]" % (e.strerror, e.errno))
if (pid != 0):
if (pid == 0): # The second child.
# We probably don't want the file mode creation mask inherited from
# the parent, so we give the child complete control over permissions.
if UMASK is not None:
os.umask(UMASK)
else:
# Parent (the first child) of the second child.
# exit() or _exit()?
# _exit is like exit(), but it doesn't call any functions registered
# with atexit (and on_exit) or any registered signal handlers. It also
# closes any open file descriptors. Using exit() may cause all stdio
# streams to be flushed twice and any temporary files may be unexpectedly
# removed. It's therefore recommended that child branches of a fork()
# and the parent branch(es) of a daemon use _exit().
os._exit(0)
else:
os.waitpid(pid, 0)
# exit() or _exit()?
# _exit is like exit(), but it doesn't call any functions registered
# with atexit (and on_exit) or any registered signal handlers. It also
# closes any open file descriptors. Using exit() may cause all stdio
# streams to be flushed twice and any temporary files may be unexpectedly
# removed. It's therefore recommended that child branches of a fork()
# and the parent branch(es) of a daemon use _exit().
return
# The second child.
# Close all open file descriptors. This prevents the child from keeping
# open any file descriptors inherited from the parent. There is a variety
# of methods to accomplish this task. Three are listed below.
#
# Try the system configuration variable, SC_OPEN_MAX, to obtain the maximum
# number of open file descriptors to close. If it doesn't exist, use
# the default value (configurable).
#
# try:
# maxfd = os.sysconf("SC_OPEN_MAX")
# except (AttributeError, ValueError):
# maxfd = MAXFD
#
# OR
#
# if (os.sysconf_names.has_key("SC_OPEN_MAX")):
# maxfd = os.sysconf("SC_OPEN_MAX")
# else:
# maxfd = MAXFD
#
# OR
#
# Use the getrlimit method to retrieve the maximum file descriptor number
# that can be opened by this process. If there is no limit on the
# resource, use the default value.
#
import resource # Resource usage information.
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if (maxfd == resource.RLIM_INFINITY):
maxfd = MAXFD
# Iterate through and close all file descriptors.
# for fd in range(0, maxfd):
# try:
# os.close(fd)
# except OSError: # ERROR, fd wasn't open to begin with (ignored)
# pass
# Replace standard fds with our own
si = open('/dev/null', 'r')
# Redirect the standard I/O file descriptors to the specified file. Since
# the daemon has no controlling terminal, most daemons redirect stdin,
# stdout, and stderr to /dev/null. This is done to prevent side-effects
# from reads and writes to the standard I/O file descriptors.
# This call to open is guaranteed to return the lowest file descriptor,
# which will be 0 (stdin), since it was closed above.
# os.open(REDIRECT_TO, os.O_RDWR) # standard input (0)
# Duplicate standard input to standard output and standard error.
# os.dup2(0, 1) # standard output (1)
# os.dup2(0, 2) # standard error (2)
si = file('/dev/null', 'r')
so = file(logfile, 'w')
se = so
# Replace those fds with our own
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
try:
so = open(logfile, 'a+')
se = so
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
except io.UnsupportedOperation:
sys.stdout = open(logfile, 'a+')
sys.stderr = sys.stdout
function()
try:
function()
except Exception as e:
traceback.print_exc()
finally:
bb.event.print_ui_queue()
os._exit(0)
os._exit(0)

View File

@@ -78,6 +78,59 @@ def initVar(var, d):
"""Non-destructive var init for data structure"""
d.initVar(var)
def setVar(var, value, d):
"""Set a variable to a given value"""
d.setVar(var, value)
def getVar(var, d, exp = 0):
"""Gets the value of a variable"""
return d.getVar(var, exp)
def renameVar(key, newkey, d):
"""Renames a variable from key to newkey"""
d.renameVar(key, newkey)
def delVar(var, d):
"""Removes a variable from the data set"""
d.delVar(var)
def appendVar(var, value, d):
"""Append additional value to a variable"""
d.appendVar(var, value)
def setVarFlag(var, flag, flagvalue, d):
"""Set a flag for a given variable to a given value"""
d.setVarFlag(var, flag, flagvalue)
def getVarFlag(var, flag, d):
"""Gets given flag from given var"""
return d.getVarFlag(var, flag)
def delVarFlag(var, flag, d):
"""Removes a given flag from the variable's flags"""
d.delVarFlag(var, flag)
def setVarFlags(var, flags, d):
"""Set the flags for a given variable
Note:
setVarFlags will not clear previous
flags. Think of this method as
addVarFlags
"""
d.setVarFlags(var, flags)
def getVarFlags(var, d):
"""Gets a variable's flags"""
return d.getVarFlags(var)
def delVarFlags(var, d):
"""Removes a variable's flags"""
d.delVarFlags(var)
def keys(d):
"""Return a list of keys in d"""
return d.keys()
@@ -106,12 +159,13 @@ def expandKeys(alterdata, readdata = None):
# These two for loops are split for performance to maximise the
# usefulness of the expand cache
for key in sorted(todolist):
for key in todolist:
ekey = todolist[key]
newval = alterdata.getVar(ekey, False)
if newval is not None:
val = alterdata.getVar(key, False)
if val is not None:
newval = alterdata.getVar(ekey, 0)
if newval:
val = alterdata.getVar(key, 0)
if val is not None and newval is not None:
bb.warn("Variable key %s (%s) replaces original key %s (%s)." % (key, val, ekey, newval))
alterdata.renameVar(key, ekey)
@@ -121,7 +175,7 @@ def inheritFromOS(d, savedenv, permitted):
for s in savedenv.keys():
if s in permitted:
try:
d.setVar(s, savedenv.getVar(s), op = 'from env')
d.setVar(s, getVar(s, savedenv, True), op = 'from env')
if s in exportlist:
d.setVarFlag(s, "export", True, op = 'auto env export')
except TypeError:
@@ -129,39 +183,39 @@ def inheritFromOS(d, savedenv, permitted):
def emit_var(var, o=sys.__stdout__, d = init(), all=False):
"""Emit a variable to be sourced by a shell."""
func = d.getVarFlag(var, "func", False)
if d.getVarFlag(var, 'python', False) and func:
return False
if getVarFlag(var, "python", d):
return 0
export = d.getVarFlag(var, "export", False)
unexport = d.getVarFlag(var, "unexport", False)
export = getVarFlag(var, "export", d)
unexport = getVarFlag(var, "unexport", d)
func = getVarFlag(var, "func", d)
if not all and not export and not unexport and not func:
return False
return 0
try:
if all:
oval = d.getVar(var, False)
val = d.getVar(var)
oval = getVar(var, d, 0)
val = getVar(var, d, 1)
except (KeyboardInterrupt, bb.build.FuncFailed):
raise
except Exception as exc:
o.write('# expansion of %s threw %s: %s\n' % (var, exc.__class__.__name__, str(exc)))
return False
return 0
if all:
d.varhistory.emit(var, oval, val, o, d)
d.varhistory.emit(var, oval, val, o)
if (var.find("-") != -1 or var.find(".") != -1 or var.find('{') != -1 or var.find('}') != -1 or var.find('+') != -1) and not all:
return False
return 0
varExpanded = d.expand(var)
varExpanded = expand(var, d)
if unexport:
o.write('unset %s\n' % varExpanded)
return False
return 0
if val is None:
return False
return 0
val = str(val)
@@ -170,11 +224,10 @@ def emit_var(var, o=sys.__stdout__, d = init(), all=False):
val = val[3:] # Strip off "() "
o.write("%s() %s\n" % (varExpanded, val))
o.write("export -f %s\n" % (varExpanded))
return True
return 1
if func:
# NOTE: should probably check for unbalanced {} within the var
val = val.rstrip('\n')
o.write("%s() {\n%s\n}\n" % (varExpanded, val))
return 1
@@ -187,31 +240,29 @@ def emit_var(var, o=sys.__stdout__, d = init(), all=False):
alter = re.sub('\n', ' \\\n', alter)
alter = re.sub('\\$', '\\\\$', alter)
o.write('%s="%s"\n' % (varExpanded, alter))
return False
return 0
def emit_env(o=sys.__stdout__, d = init(), all=False):
"""Emits all items in the data store in a format such that it can be sourced by a shell."""
isfunc = lambda key: bool(d.getVarFlag(key, "func", False))
isfunc = lambda key: bool(d.getVarFlag(key, "func"))
keys = sorted((key for key in d.keys() if not key.startswith("__")), key=isfunc)
grouped = groupby(keys, isfunc)
for isfunc, keys in grouped:
for key in sorted(keys):
for key in keys:
emit_var(key, o, d, all and not isfunc) and o.write('\n')
def exported_keys(d):
return (key for key in d.keys() if not key.startswith('__') and
d.getVarFlag(key, 'export', False) and
not d.getVarFlag(key, 'unexport', False))
d.getVarFlag(key, 'export') and
not d.getVarFlag(key, 'unexport'))
def exported_vars(d):
k = list(exported_keys(d))
for key in k:
for key in exported_keys(d):
try:
value = d.getVar(key)
except Exception as err:
bb.warn("%s: Unable to export ${%s}: %s" % (d.getVar("FILE"), key, err))
continue
value = d.getVar(key, True)
except Exception:
pass
if value is not None:
yield key, str(value)
@@ -219,24 +270,23 @@ def exported_vars(d):
def emit_func(func, o=sys.__stdout__, d = init()):
"""Emits all items in the data store in a format such that it can be sourced by a shell."""
keys = (key for key in d.keys() if not key.startswith("__") and not d.getVarFlag(key, "func", False))
for key in sorted(keys):
emit_var(key, o, d, False)
keys = (key for key in d.keys() if not key.startswith("__") and not d.getVarFlag(key, "func"))
for key in keys:
emit_var(key, o, d, False) and o.write('\n')
o.write('\n')
emit_var(func, o, d, False) and o.write('\n')
newdeps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func))
newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
newdeps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func, True))
newdeps |= set((d.getVarFlag(func, "vardeps", True) or "").split())
seen = set()
while newdeps:
deps = newdeps
seen |= deps
newdeps = set()
for dep in deps:
if d.getVarFlag(dep, "func", False) and not d.getVarFlag(dep, "python", False):
if d.getVarFlag(dep, "func") and not d.getVarFlag(dep, "python"):
emit_var(dep, o, d, False) and o.write('\n')
newdeps |= bb.codeparser.ShellParser(dep, logger).parse_shell(d.getVar(dep))
newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
newdeps |= bb.codeparser.ShellParser(dep, logger).parse_shell(d.getVar(dep, True))
newdeps |= set((d.getVarFlag(dep, "vardeps", True) or "").split())
newdeps -= seen
_functionfmt = """
@@ -247,7 +297,7 @@ def emit_func_python(func, o=sys.__stdout__, d = init()):
"""Emits all items in the data store in a format such that it can be sourced by a shell."""
def write_func(func, o, call = False):
body = d.getVar(func, False)
body = d.getVar(func, True)
if not body.startswith("def"):
body = _functionfmt.format(function=func, body=body)
@@ -257,21 +307,21 @@ def emit_func_python(func, o=sys.__stdout__, d = init()):
write_func(func, o, True)
pp = bb.codeparser.PythonParser(func, logger)
pp.parse_python(d.getVar(func, False))
pp.parse_python(d.getVar(func, True))
newdeps = pp.execs
newdeps |= set((d.getVarFlag(func, "vardeps") or "").split())
newdeps |= set((d.getVarFlag(func, "vardeps", True) or "").split())
seen = set()
while newdeps:
deps = newdeps
seen |= deps
newdeps = set()
for dep in deps:
if d.getVarFlag(dep, "func", False) and d.getVarFlag(dep, "python", False):
if d.getVarFlag(dep, "func") and d.getVarFlag(dep, "python"):
write_func(dep, o)
pp = bb.codeparser.PythonParser(dep, logger)
pp.parse_python(d.getVar(dep, False))
pp.parse_python(d.getVar(dep, True))
newdeps |= pp.execs
newdeps |= set((d.getVarFlag(dep, "vardeps") or "").split())
newdeps |= set((d.getVarFlag(dep, "vardeps", True) or "").split())
newdeps -= seen
def update_data(d):
@@ -288,21 +338,19 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d):
deps |= parser.references
deps = deps | (keys & parser.execs)
return deps, value
varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "exports", "postfuncs", "prefuncs", "lineno", "filename"]) or {}
varflags = d.getVarFlags(key, ["vardeps", "vardepvalue", "vardepsexclude", "vardepvalueexclude", "postfuncs", "prefuncs"]) or {}
vardeps = varflags.get("vardeps")
value = d.getVarFlag(key, "_content", False)
value = d.getVar(key, False)
def handle_contains(value, contains, d):
newvalue = ""
for k in sorted(contains):
l = (d.getVar(k) or "").split()
for item in sorted(contains[k]):
for word in item.split():
if not word in l:
newvalue += "\n%s{%s} = Unset" % (k, item)
break
l = (d.getVar(k, True) or "").split()
for word in sorted(contains[k]):
if word in l:
newvalue += "\n%s{%s} = Set" % (k, word)
else:
newvalue += "\n%s{%s} = Set" % (k, item)
newvalue += "\n%s{%s} = Unset" % (k, word)
if not newvalue:
return value
if not value:
@@ -313,29 +361,27 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d):
value = varflags.get("vardepvalue")
elif varflags.get("func"):
if varflags.get("python"):
parsedvar = d.expandWithRefs(value, key)
parser = bb.codeparser.PythonParser(key, logger)
if value and "\t" in value:
logger.warning("Variable %s contains tabs, please remove these (%s)" % (key, d.getVar("FILE")))
parser.parse_python(value, filename=varflags.get("filename"), lineno=varflags.get("lineno"))
if parsedvar.value and "\t" in parsedvar.value:
logger.warn("Variable %s contains tabs, please remove these (%s)" % (key, d.getVar("FILE", True)))
parser.parse_python(parsedvar.value)
deps = deps | parser.references
deps = deps | (keys & parser.execs)
value = handle_contains(value, parser.contains, d)
else:
parsedvar = d.expandWithRefs(value, key)
parser = bb.codeparser.ShellParser(key, logger)
parser.parse_shell(parsedvar.value)
deps = deps | shelldeps
deps = deps | parsedvar.references
deps = deps | (keys & parser.execs) | (keys & parsedvar.execs)
value = handle_contains(value, parsedvar.contains, d)
if vardeps is None:
parser.log.flush()
if "prefuncs" in varflags:
deps = deps | set(varflags["prefuncs"].split())
if "postfuncs" in varflags:
deps = deps | set(varflags["postfuncs"].split())
if "exports" in varflags:
deps = deps | set(varflags["exports"].split())
deps = deps | parsedvar.references
deps = deps | (keys & parser.execs) | (keys & parsedvar.execs)
value = handle_contains(value, parsedvar.contains, d)
else:
parser = d.expandWithRefs(value, key)
deps |= parser.references
@@ -359,11 +405,8 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d):
deps |= set((vardeps or "").split())
deps -= set(varflags.get("vardepsexclude", "").split())
except bb.parse.SkipRecipe:
raise
except Exception as e:
bb.warn("Exception during build_dependencies for %s" % key)
raise
raise bb.data_smart.ExpansionError(key, None, e)
return deps, value
#bb.note("Variable %s references %s and calls %s" % (key, str(deps), str(execs)))
#d.setVarFlag(key, "vardeps", deps)
@@ -371,13 +414,13 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d):
def generate_dependencies(d):
keys = set(key for key in d if not key.startswith("__"))
shelldeps = set(key for key in d.getVar("__exportlist", False) if d.getVarFlag(key, "export", False) and not d.getVarFlag(key, "unexport", False))
varflagsexcl = d.getVar('BB_SIGNATURE_EXCLUDE_FLAGS')
shelldeps = set(key for key in d.getVar("__exportlist", False) if d.getVarFlag(key, "export") and not d.getVarFlag(key, "unexport"))
varflagsexcl = d.getVar('BB_SIGNATURE_EXCLUDE_FLAGS', True)
deps = {}
values = {}
tasklist = d.getVar('__BBTASKS', False) or []
tasklist = d.getVar('__BBTASKS') or []
for task in tasklist:
deps[task], values[task] = build_dependencies(task, keys, shelldeps, varflagsexcl, d)
newdeps = deps[task]
@@ -395,7 +438,7 @@ def generate_dependencies(d):
return tasklist, deps, values
def inherits_class(klass, d):
val = d.getVar('__inherit_cache', False) or []
val = getVar('__inherit_cache', d) or []
needle = os.path.join('classes', '%s.bbclass' % klass)
for v in val:
if v.endswith(needle):

View File

@@ -39,8 +39,8 @@ from bb.COW import COWDictBase
logger = logging.getLogger("BitBake.Data")
__setvar_keyword__ = ["_append", "_prepend", "_remove"]
__setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend|_remove)(_(?P<add>[^A-Z]*))?$')
__expand_var_regexp__ = re.compile(r"\${[^{}@\n\t :]+}")
__setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend|_remove)(_(?P<add>.*))?$')
__expand_var_regexp__ = re.compile(r"\${[^{}@\n\t ]+}")
__expand_python_regexp__ = re.compile(r"\${@.+?}")
def infer_caller_details(loginfo, parent = False, varval = True):
@@ -54,36 +54,27 @@ def infer_caller_details(loginfo, parent = False, varval = True):
return
# Infer caller's likely values for variable (var) and value (value),
# to reduce clutter in the rest of the code.
above = None
def set_above():
if varval and ('variable' not in loginfo or 'detail' not in loginfo):
try:
raise Exception
except Exception:
tb = sys.exc_info()[2]
if parent:
return tb.tb_frame.f_back.f_back.f_back
above = tb.tb_frame.f_back.f_back
else:
return tb.tb_frame.f_back.f_back
if varval and ('variable' not in loginfo or 'detail' not in loginfo):
if not above:
above = set_above()
lcls = above.f_locals.items()
above = tb.tb_frame.f_back
lcls = above.f_locals.items()
for k, v in lcls:
if k == 'value' and 'detail' not in loginfo:
loginfo['detail'] = v
if k == 'var' and 'variable' not in loginfo:
loginfo['variable'] = v
# Infer file/line/function from traceback
# Don't use traceback.extract_stack() since it fills the line contents which
# we don't need and that hits stat syscalls
if 'file' not in loginfo:
if not above:
above = set_above()
f = above.f_back
line = f.f_lineno
file = f.f_code.co_filename
func = f.f_code.co_name
depth = 3
if parent:
depth = 4
file, line, func, text = traceback.extract_stack(limit = depth)[0]
loginfo['file'] = file
loginfo['line'] = line
if func not in loginfo:
@@ -108,7 +99,7 @@ class VariableParse:
varparse = self.d.expand_cache[key]
var = varparse.value
else:
var = self.d.getVarFlag(key, "_content")
var = self.d.getVarFlag(key, "_content", True)
self.references.add(key)
if var is not None:
return var
@@ -116,21 +107,13 @@ class VariableParse:
return match.group()
def python_sub(self, match):
if isinstance(match, str):
code = match
else:
code = match.group()[3:-1]
if "_remote_data" in self.d:
connector = self.d["_remote_data"]
return connector.expandPythonRef(self.varname, code, self.d)
code = match.group()[3:-1]
codeobj = compile(code.strip(), self.varname or "<expansion>", "eval")
parser = bb.codeparser.PythonParser(self.varname, logger)
parser.parse_python(code)
if self.varname:
vardeps = self.d.getVarFlag(self.varname, "vardeps")
vardeps = self.d.getVarFlag(self.varname, "vardeps", True)
if vardeps is None:
parser.log.flush()
else:
@@ -143,7 +126,7 @@ class VariableParse:
self.contains[k] = parser.contains[k].copy()
else:
self.contains[k].update(parser.contains[k])
value = utils.better_eval(codeobj, DataContext(self.d), {'d' : self.d})
value = utils.better_eval(codeobj, DataContext(self.d))
return str(value)
@@ -154,8 +137,8 @@ class DataContext(dict):
self['d'] = metadata
def __missing__(self, key):
value = self.metadata.getVar(key)
if value is None or self.metadata.getVarFlag(key, 'func', False):
value = self.metadata.getVar(key, True)
if value is None or self.metadata.getVarFlag(key, 'func'):
raise KeyError(key)
else:
return value
@@ -230,19 +213,6 @@ class VariableHistory(object):
new.variables = self.variables.copy()
return new
def __getstate__(self):
vardict = {}
for k, v in self.variables.iteritems():
vardict[k] = v
return {'dataroot': self.dataroot,
'variables': vardict}
def __setstate__(self, state):
self.dataroot = state['dataroot']
self.variables = COWDictBase.copy()
for k, v in state['variables'].items():
self.variables[k] = v
def record(self, *kwonly, **loginfo):
if not self.dataroot._tracking:
return
@@ -261,37 +231,16 @@ class VariableHistory(object):
if var not in self.variables:
self.variables[var] = []
if not isinstance(self.variables[var], list):
return
if 'nodups' in loginfo and loginfo in self.variables[var]:
return
self.variables[var].append(loginfo.copy())
def variable(self, var):
remote_connector = self.dataroot.getVar('_remote_data', False)
if remote_connector:
varhistory = remote_connector.getVarHistory(var)
else:
varhistory = []
if var in self.variables:
varhistory.extend(self.variables[var])
return varhistory
return self.variables[var]
else:
return []
def emit(self, var, oval, val, o, d):
def emit(self, var, oval, val, o):
history = self.variable(var)
# Append override history
if var in d.overridedata:
for (r, override) in d.overridedata[var]:
for event in self.variable(r):
loginfo = event.copy()
if 'flag' in loginfo and not loginfo['flag'].startswith("_"):
continue
loginfo['variable'] = var
loginfo['op'] = 'override[%s]:%s' % (override, loginfo['op'])
history.append(loginfo)
commentVal = re.sub('\n', '\n#', str(oval))
if history:
if len(history) == 1:
@@ -338,31 +287,6 @@ class VariableHistory(object):
lines.append(line)
return lines
def get_variable_items_files(self, var, d):
"""
Use variable history to map items added to a list variable and
the files in which they were added.
"""
history = self.variable(var)
finalitems = (d.getVar(var) or '').split()
filemap = {}
isset = False
for event in history:
if 'flag' in event:
continue
if event['op'] == '_remove':
continue
if isset and event['op'] == 'set?':
continue
isset = True
items = d.expand(event['detail']).split()
for item in items:
# This is a little crude but is belt-and-braces to avoid us
# having to handle every possible operation type specifically
if item in finalitems and not item in filemap:
filemap[item] = event['file']
return filemap
def del_var_history(self, var, f=None, line=None):
"""If file f and line are not given, the entire history of var is deleted"""
if var in self.variables:
@@ -372,23 +296,23 @@ class VariableHistory(object):
self.variables[var] = []
class DataSmart(MutableMapping):
def __init__(self):
def __init__(self, special = None, seen = None ):
self.dict = {}
if special is None:
special = COWDictBase.copy()
if seen is None:
seen = COWDictBase.copy()
self.inchistory = IncludeHistory()
self.varhistory = VariableHistory(self)
self._tracking = False
self.expand_cache = {}
# cookie monster tribute
# Need to be careful about writes to overridedata as
# its only a shallow copy, could influence other data store
# copies!
self.overridedata = {}
self.overrides = None
self.overridevars = set(["OVERRIDES", "FILE"])
self.inoverride = False
self._special_values = special
self._seen_overrides = seen
self.expand_cache = {}
def enableTracking(self):
self._tracking = True
@@ -398,7 +322,7 @@ class DataSmart(MutableMapping):
def expandWithRefs(self, s, varname):
if not isinstance(s, str): # sanity check
if not isinstance(s, basestring): # sanity check
return VariableParse(varname, self, s)
if varname and varname in self.expand_cache:
@@ -410,12 +334,7 @@ class DataSmart(MutableMapping):
olds = s
try:
s = __expand_var_regexp__.sub(varparse.var_sub, s)
try:
s = __expand_python_regexp__.sub(varparse.python_sub, s)
except SyntaxError as e:
# Likely unmatched brackets, just don't expand the expression
if e.msg != "EOL while scanning string literal":
raise
s = __expand_python_regexp__.sub(varparse.python_sub, s)
if s == olds:
break
except ExpansionError:
@@ -423,7 +342,7 @@ class DataSmart(MutableMapping):
except bb.parse.SkipRecipe:
raise
except Exception as exc:
raise ExpansionError(varname, s, exc) from exc
raise ExpansionError(varname, s, exc)
varparse.value = s
@@ -435,34 +354,97 @@ class DataSmart(MutableMapping):
def expand(self, s, varname = None):
return self.expandWithRefs(s, varname).value
def finalize(self, parent = False):
return
def internal_finalize(self, parent = False):
"""Performs final steps upon the datastore, including application of overrides"""
self.overrides = None
def need_overrides(self):
if self.overrides is not None:
return
if self.inoverride:
return
for count in range(5):
self.inoverride = True
# Can end up here recursively so setup dummy values
self.overrides = []
self.overridesset = set()
self.overrides = (self.getVar("OVERRIDES") or "").split(":") or []
self.overridesset = set(self.overrides)
self.inoverride = False
self.expand_cache = {}
newoverrides = (self.getVar("OVERRIDES") or "").split(":") or []
if newoverrides == self.overrides:
break
self.overrides = newoverrides
self.overridesset = set(self.overrides)
else:
bb.fatal("Overrides could not be expanded into a stable state after 5 iterations, overrides must be being referenced by other overridden variables in some recursive fashion. Please provide your configuration to bitbake-devel so we can laugh, er, I mean try and understand how to make it work.")
overrides = (self.getVar("OVERRIDES", True) or "").split(":") or []
finalize_caller = {
'op': 'finalize',
}
infer_caller_details(finalize_caller, parent = parent, varval = False)
#
# Well let us see what breaks here. We used to iterate
# over each variable and apply the override and then
# do the line expanding.
# If we have bad luck - which we will have - the keys
# where in some order that is so important for this
# method which we don't have anymore.
# Anyway we will fix that and write test cases this
# time.
#
# First we apply all overrides
# Then we will handle _append and _prepend and store the _remove
# information for later.
#
# We only want to report finalization once per variable overridden.
finalizes_reported = {}
for o in overrides:
# calculate '_'+override
l = len(o) + 1
# see if one should even try
if o not in self._seen_overrides:
continue
vars = self._seen_overrides[o].copy()
for var in vars:
name = var[:-l]
try:
# Report only once, even if multiple changes.
if name not in finalizes_reported:
finalizes_reported[name] = True
finalize_caller['variable'] = name
finalize_caller['detail'] = 'was: ' + str(self.getVar(name, False))
self.varhistory.record(**finalize_caller)
# Copy history of the override over.
for event in self.varhistory.variable(var):
loginfo = event.copy()
loginfo['variable'] = name
loginfo['op'] = 'override[%s]:%s' % (o, loginfo['op'])
self.varhistory.record(**loginfo)
self.setVar(name, self.getVar(var, False), op = 'finalize', file = 'override[%s]' % o, line = '')
self.delVar(var)
except Exception:
logger.info("Untracked delVar")
# now on to the appends and prepends, and stashing the removes
for op in __setvar_keyword__:
if op in self._special_values:
appends = self._special_values[op] or []
for append in appends:
keep = []
for (a, o) in self.getVarFlag(append, op) or []:
match = True
if o:
for o2 in o.split("_"):
if not o2 in overrides:
match = False
if not match:
keep.append((a ,o))
continue
if op == "_append":
sval = self.getVar(append, False) or ""
sval += a
self.setVar(append, sval)
elif op == "_prepend":
sval = a + (self.getVar(append, False) or "")
self.setVar(append, sval)
elif op == "_remove":
removes = self.getVarFlag(append, "_removeactive", False) or []
removes.extend(a.split())
self.setVarFlag(append, "_removeactive", removes, ignore=True)
# We save overrides that may be applied at some later stage
if keep:
self.setVarFlag(append, op, keep, ignore=True)
else:
self.delVarFlag(append, op, ignore=True)
def initVar(self, var):
self.expand_cache = {}
@@ -473,22 +455,17 @@ class DataSmart(MutableMapping):
dest = self.dict
while dest:
if var in dest:
return dest[var], self.overridedata.get(var, None)
if "_remote_data" in dest:
connector = dest["_remote_data"]["_content"]
return connector.getVar(var)
return dest[var]
if "_data" not in dest:
break
dest = dest["_data"]
return None, self.overridedata.get(var, None)
def _makeShadowCopy(self, var):
if var in self.dict:
return
local_var, _ = self._findVar(var)
local_var = self._findVar(var)
if local_var:
self.dict[var] = copy.copy(local_var)
@@ -498,16 +475,6 @@ class DataSmart(MutableMapping):
def setVar(self, var, value, **loginfo):
#print("var=" + str(var) + " val=" + str(value))
parsing=False
if 'parsing' in loginfo:
parsing=True
if '_remote_data' in self.dict:
connector = self.dict["_remote_data"]["_content"]
res = connector.setVar(var, value)
if not res:
return
if 'op' not in loginfo:
loginfo['op'] = "set"
self.expand_cache = {}
@@ -516,7 +483,7 @@ class DataSmart(MutableMapping):
base = match.group('base')
keyword = match.group("keyword")
override = match.group('add')
l = self.getVarFlag(base, keyword, False) or []
l = self.getVarFlag(base, keyword) or []
l.append([value, override])
self.setVarFlag(base, keyword, l, ignore=True)
# And cause that to be recorded:
@@ -529,119 +496,65 @@ class DataSmart(MutableMapping):
self.varhistory.record(**loginfo)
# todo make sure keyword is not __doc__ or __module__
# pay the cookie monster
try:
self._special_values[keyword].add(base)
except KeyError:
self._special_values[keyword] = set()
self._special_values[keyword].add(base)
# more cookies for the cookie monster
if '_' in var:
self._setvar_update_overrides(base, **loginfo)
if base in self.overridevars:
self._setvar_update_overridevars(var, value)
return
if not var in self.dict:
self._makeShadowCopy(var)
if not parsing:
if "_append" in self.dict[var]:
del self.dict[var]["_append"]
if "_prepend" in self.dict[var]:
del self.dict[var]["_prepend"]
if "_remove" in self.dict[var]:
del self.dict[var]["_remove"]
if var in self.overridedata:
active = []
self.need_overrides()
for (r, o) in self.overridedata[var]:
if o in self.overridesset:
active.append(r)
elif "_" in o:
if set(o.split("_")).issubset(self.overridesset):
active.append(r)
for a in active:
self.delVar(a)
del self.overridedata[var]
# more cookies for the cookie monster
if '_' in var:
self._setvar_update_overrides(var, **loginfo)
self._setvar_update_overrides(var)
# setting var
self.dict[var]["_content"] = value
self.varhistory.record(**loginfo)
if var in self.overridevars:
self._setvar_update_overridevars(var, value)
def _setvar_update_overridevars(self, var, value):
vardata = self.expandWithRefs(value, var)
new = vardata.references
new.update(vardata.contains.keys())
while not new.issubset(self.overridevars):
nextnew = set()
self.overridevars.update(new)
for i in new:
vardata = self.expandWithRefs(self.getVar(i), i)
nextnew.update(vardata.references)
nextnew.update(vardata.contains.keys())
new = nextnew
self.internal_finalize(True)
def _setvar_update_overrides(self, var, **loginfo):
def _setvar_update_overrides(self, var):
# aka pay the cookie monster
override = var[var.rfind('_')+1:]
shortvar = var[:var.rfind('_')]
while override and override.islower():
if shortvar not in self.overridedata:
self.overridedata[shortvar] = []
if [var, override] not in self.overridedata[shortvar]:
# Force CoW by recreating the list first
self.overridedata[shortvar] = list(self.overridedata[shortvar])
self.overridedata[shortvar].append([var, override])
while override:
if override not in self._seen_overrides:
self._seen_overrides[override] = set()
self._seen_overrides[override].add( var )
override = None
if "_" in shortvar:
override = var[shortvar.rfind('_')+1:]
shortvar = var[:shortvar.rfind('_')]
if len(shortvar) == 0:
override = None
def getVar(self, var, expand=True, noweakdefault=False, parsing=False):
return self.getVarFlag(var, "_content", expand, noweakdefault, parsing)
def getVar(self, var, expand=False, noweakdefault=False):
return self.getVarFlag(var, "_content", expand, noweakdefault)
def renameVar(self, key, newkey, **loginfo):
"""
Rename the variable key to newkey
"""
if '_remote_data' in self.dict:
connector = self.dict["_remote_data"]["_content"]
res = connector.renameVar(key, newkey)
if not res:
return
val = self.getVar(key, 0, parsing=True)
val = self.getVar(key, 0)
if val is not None:
loginfo['variable'] = newkey
loginfo['op'] = 'rename from %s' % key
loginfo['detail'] = val
self.varhistory.record(**loginfo)
self.setVar(newkey, val, ignore=True, parsing=True)
self.setVar(newkey, val, ignore=True)
for i in (__setvar_keyword__):
src = self.getVarFlag(key, i, False)
src = self.getVarFlag(key, i)
if src is None:
continue
dest = self.getVarFlag(newkey, i, False) or []
dest = self.getVarFlag(newkey, i) or []
dest.extend(src)
self.setVarFlag(newkey, i, dest, ignore=True)
if key in self.overridedata:
self.overridedata[newkey] = []
for (v, o) in self.overridedata[key]:
self.overridedata[newkey].append([v.replace(key, newkey), o])
self.renameVar(v, v.replace(key, newkey))
if '_' in newkey and val is None:
self._setvar_update_overrides(newkey, **loginfo)
if i in self._special_values and key in self._special_values[i]:
self._special_values[i].remove(key)
self._special_values[i].add(newkey)
loginfo['variable'] = key
loginfo['op'] = 'rename (to)'
@@ -652,53 +565,27 @@ class DataSmart(MutableMapping):
def appendVar(self, var, value, **loginfo):
loginfo['op'] = 'append'
self.varhistory.record(**loginfo)
self.setVar(var + "_append", value, ignore=True, parsing=True)
newvalue = (self.getVar(var, False) or "") + value
self.setVar(var, newvalue, ignore=True)
def prependVar(self, var, value, **loginfo):
loginfo['op'] = 'prepend'
self.varhistory.record(**loginfo)
self.setVar(var + "_prepend", value, ignore=True, parsing=True)
newvalue = value + (self.getVar(var, False) or "")
self.setVar(var, newvalue, ignore=True)
def delVar(self, var, **loginfo):
if '_remote_data' in self.dict:
connector = self.dict["_remote_data"]["_content"]
res = connector.delVar(var)
if not res:
return
loginfo['detail'] = ""
loginfo['op'] = 'del'
self.varhistory.record(**loginfo)
self.expand_cache = {}
self.dict[var] = {}
if var in self.overridedata:
del self.overridedata[var]
if '_' in var:
override = var[var.rfind('_')+1:]
shortvar = var[:var.rfind('_')]
while override and override.islower():
try:
if shortvar in self.overridedata:
# Force CoW by recreating the list first
self.overridedata[shortvar] = list(self.overridedata[shortvar])
self.overridedata[shortvar].remove([var, override])
except ValueError as e:
pass
override = None
if "_" in shortvar:
override = var[shortvar.rfind('_')+1:]
shortvar = var[:shortvar.rfind('_')]
if len(shortvar) == 0:
override = None
if override and override in self._seen_overrides and var in self._seen_overrides[override]:
self._seen_overrides[override].remove(var)
def setVarFlag(self, var, flag, value, **loginfo):
if '_remote_data' in self.dict:
connector = self.dict["_remote_data"]["_content"]
res = connector.setVarFlag(var, flag, value)
if not res:
return
self.expand_cache = {}
if 'op' not in loginfo:
loginfo['op'] = "set"
loginfo['flag'] = flag
@@ -708,9 +595,7 @@ class DataSmart(MutableMapping):
self.dict[var][flag] = value
if flag == "_defaultval" and '_' in var:
self._setvar_update_overrides(var, **loginfo)
if flag == "_defaultval" and var in self.overridevars:
self._setvar_update_overridevars(var, value)
self._setvar_update_overrides(var)
if flag == "unexport" or flag == "export":
if not "__exportlist" in self.dict:
@@ -719,71 +604,14 @@ class DataSmart(MutableMapping):
self.dict["__exportlist"]["_content"] = set()
self.dict["__exportlist"]["_content"].add(var)
def getVarFlag(self, var, flag, expand=True, noweakdefault=False, parsing=False):
local_var, overridedata = self._findVar(var)
def getVarFlag(self, var, flag, expand=False, noweakdefault=False):
local_var = self._findVar(var)
value = None
if flag == "_content" and overridedata is not None and not parsing:
match = False
active = {}
self.need_overrides()
for (r, o) in overridedata:
# What about double overrides both with "_" in the name?
if o in self.overridesset:
active[o] = r
elif "_" in o:
if set(o.split("_")).issubset(self.overridesset):
active[o] = r
mod = True
while mod:
mod = False
for o in self.overrides:
for a in active.copy():
if a.endswith("_" + o):
t = active[a]
del active[a]
active[a.replace("_" + o, "")] = t
mod = True
elif a == o:
match = active[a]
del active[a]
if match:
value = self.getVar(match, False)
if local_var is not None and value is None:
if local_var is not None:
if flag in local_var:
value = copy.copy(local_var[flag])
elif flag == "_content" and "_defaultval" in local_var and not noweakdefault:
value = copy.copy(local_var["_defaultval"])
if flag == "_content" and local_var is not None and "_append" in local_var and not parsing:
if not value:
value = ""
self.need_overrides()
for (r, o) in local_var["_append"]:
match = True
if o:
for o2 in o.split("_"):
if not o2 in self.overrides:
match = False
if match:
value = value + r
if flag == "_content" and local_var is not None and "_prepend" in local_var and not parsing:
if not value:
value = ""
self.need_overrides()
for (r, o) in local_var["_prepend"]:
match = True
if o:
for o2 in o.split("_"):
if not o2 in self.overrides:
match = False
if match:
value = r + value
if expand and value:
# Only getvar (flag == _content) hits the expand cache
cachename = None
@@ -792,38 +620,20 @@ class DataSmart(MutableMapping):
else:
cachename = var + "[" + flag + "]"
value = self.expand(value, cachename)
if value and flag == "_content" and local_var is not None and "_remove" in local_var:
removes = []
self.need_overrides()
for (r, o) in local_var["_remove"]:
match = True
if o:
for o2 in o.split("_"):
if not o2 in self.overrides:
match = False
if match:
removes.extend(self.expand(r).split())
if removes:
filtered = filter(lambda v: v not in removes,
value.split())
value = " ".join(filtered)
if expand and var in self.expand_cache:
# We need to ensure the expand cache has the correct value
# flag == "_content" here
self.expand_cache[var].value = value
if value and flag == "_content" and local_var is not None and "_removeactive" in local_var:
removes = [self.expand(r).split() for r in local_var["_removeactive"]]
removes = reduce(lambda a, b: a+b, removes, [])
filtered = filter(lambda v: v not in removes,
value.split())
value = " ".join(filtered)
if expand:
# We need to ensure the expand cache has the correct value
# flag == "_content" here
self.expand_cache[var].value = value
return value
def delVarFlag(self, var, flag, **loginfo):
if '_remote_data' in self.dict:
connector = self.dict["_remote_data"]["_content"]
res = connector.delVarFlag(var, flag)
if not res:
return
self.expand_cache = {}
local_var, _ = self._findVar(var)
local_var = self._findVar(var)
if not local_var:
return
if not var in self.dict:
@@ -852,7 +662,6 @@ class DataSmart(MutableMapping):
self.setVarFlag(var, flag, newvalue, ignore=True)
def setVarFlags(self, var, flags, **loginfo):
self.expand_cache = {}
infer_caller_details(loginfo)
if not var in self.dict:
self._makeShadowCopy(var)
@@ -866,7 +675,7 @@ class DataSmart(MutableMapping):
self.dict[var][i] = flags[i]
def getVarFlags(self, var, expand = False, internalflags=False):
local_var, _ = self._findVar(var)
local_var = self._findVar(var)
flags = {}
if local_var:
@@ -882,7 +691,6 @@ class DataSmart(MutableMapping):
def delVarFlags(self, var, **loginfo):
self.expand_cache = {}
if not var in self.dict:
self._makeShadowCopy(var)
@@ -900,25 +708,20 @@ class DataSmart(MutableMapping):
else:
del self.dict[var]
def createCopy(self):
"""
Create a copy of self by setting _data to self
"""
# we really want this to be a DataSmart...
data = DataSmart()
data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
data.dict["_data"] = self.dict
data.varhistory = self.varhistory.copy()
data.varhistory.dataroot = data
data.varhistory.datasmart = data
data.inchistory = self.inchistory.copy()
data._tracking = self._tracking
data.overrides = None
data.overridevars = copy.copy(self.overridevars)
# Should really be a deepcopy but has heavy overhead.
# Instead, we're careful with writes.
data.overridedata = copy.copy(self.overridedata)
return data
def expandVarref(self, variable, parents=False):
@@ -939,21 +742,18 @@ class DataSmart(MutableMapping):
def localkeys(self):
for key in self.dict:
if key not in ['_data', '_remote_data']:
if key != '_data':
yield key
def __iter__(self):
deleted = set()
overrides = set()
def keylist(d):
klist = set()
for key in d:
if key in ["_data", "_remote_data"]:
if key == "_data":
continue
if key in deleted:
continue
if key in overrides:
continue
if not d[key]:
deleted.add(key)
continue
@@ -962,32 +762,13 @@ class DataSmart(MutableMapping):
if "_data" in d:
klist |= keylist(d["_data"])
if "_remote_data" in d:
connector = d["_remote_data"]["_content"]
for key in connector.getKeys():
if key in deleted:
continue
klist.add(key)
return klist
self.need_overrides()
for var in self.overridedata:
for (r, o) in self.overridedata[var]:
if o in self.overridesset:
overrides.add(var)
elif "_" in o:
if set(o.split("_")).issubset(self.overridesset):
overrides.add(var)
for k in keylist(self.dict):
yield k
for k in overrides:
yield k
def __len__(self):
return len(frozenset(iter(self)))
return len(frozenset(self))
def __getitem__(self, item):
value = self.getVar(item, False)
@@ -1006,8 +787,9 @@ class DataSmart(MutableMapping):
data = {}
d = self.createCopy()
bb.data.expandKeys(d)
bb.data.update_data(d)
config_whitelist = set((d.getVar("BB_HASHCONFIG_WHITELIST") or "").split())
config_whitelist = set((d.getVar("BB_HASHCONFIG_WHITELIST", True) or "").split())
keys = set(key for key in iter(d) if not key.startswith("__"))
for key in keys:
if key in config_whitelist:
@@ -1026,12 +808,13 @@ class DataSmart(MutableMapping):
for key in ["__BBTASKS", "__BBANONFUNCS", "__BBHANDLERS"]:
bb_list = d.getVar(key, False) or []
bb_list.sort()
data.update({key:str(bb_list)})
if key == "__BBANONFUNCS":
for i in bb_list:
value = d.getVar(i, False) or ""
value = d.getVar(i, True) or ""
data.update({i:value})
data_str = str([(k, data[k]) for k in sorted(data.keys())])
return hashlib.md5(data_str.encode("utf-8")).hexdigest()
return hashlib.md5(data_str).hexdigest()

View File

@@ -24,13 +24,13 @@ BitBake build tools.
import os, sys
import warnings
import pickle
try:
import cPickle as pickle
except ImportError:
import pickle
import logging
import atexit
import traceback
import ast
import threading
import bb.utils
import bb.compat
import bb.exceptions
@@ -48,16 +48,6 @@ class Event(object):
def __init__(self):
self.pid = worker_pid
class HeartbeatEvent(Event):
"""Triggered at regular time intervals of 10 seconds. Other events can fire much more often
(runQueueTaskStarted when there are many short tasks) or not at all for long periods
of time (again runQueueTaskStarted, when there is just one long-running task), so this
event is more suitable for doing some task-independent work occassionally."""
def __init__(self, time):
Event.__init__(self)
self.time = time
Registered = 10
AlreadyRegistered = 14
@@ -79,29 +69,9 @@ _ui_handler_seq = 0
_event_handler_map = {}
_catchall_handlers = {}
_eventfilter = None
_uiready = False
_thread_lock = threading.Lock()
_thread_lock_enabled = False
if hasattr(__builtins__, '__setitem__'):
builtins = __builtins__
else:
builtins = __builtins__.__dict__
def enable_threadlock():
global _thread_lock_enabled
_thread_lock_enabled = True
def disable_threadlock():
global _thread_lock_enabled
_thread_lock_enabled = False
def execute_handler(name, handler, event, d):
event.data = d
addedd = False
if 'd' not in builtins:
builtins['d'] = d
addedd = True
try:
ret = handler(event)
except (bb.parse.SkipRecipe, bb.BBHandledException):
@@ -117,8 +87,6 @@ def execute_handler(name, handler, event, d):
raise
finally:
del event.data
if addedd:
del builtins['d']
def fire_class_handlers(event, d):
if isinstance(event, logging.LogRecord):
@@ -126,7 +94,7 @@ def fire_class_handlers(event, d):
eid = str(event.__class__)[8:-2]
evt_hmap = _event_handler_map.get(eid, {})
for name, handler in list(_handlers.items()):
for name, handler in _handlers.iteritems():
if name in _catchall_handlers or name in evt_hmap:
if _eventfilter:
if not _eventfilter(name, handler, event, d):
@@ -139,57 +107,33 @@ def print_ui_queue():
"""If we're exiting before a UI has been spawned, display any queued
LogRecords to the console."""
logger = logging.getLogger("BitBake")
if not _uiready:
if not _ui_handlers:
from bb.msg import BBLogFormatter
stdout = logging.StreamHandler(sys.stdout)
stderr = logging.StreamHandler(sys.stderr)
formatter = BBLogFormatter("%(levelname)s: %(message)s")
stdout.setFormatter(formatter)
stderr.setFormatter(formatter)
console = logging.StreamHandler(sys.stdout)
console.setFormatter(BBLogFormatter("%(levelname)s: %(message)s"))
logger.handlers = [console]
# First check to see if we have any proper messages
msgprint = False
msgerrs = False
# Should we print to stderr?
for event in ui_queue[:]:
if isinstance(event, logging.LogRecord) and event.levelno >= logging.WARNING:
msgerrs = True
break
if msgerrs:
logger.addHandler(stderr)
else:
logger.addHandler(stdout)
for event in ui_queue[:]:
for event in ui_queue:
if isinstance(event, logging.LogRecord):
if event.levelno > logging.DEBUG:
logger.handle(event)
msgprint = True
if msgprint:
return
# Nope, so just print all of the messages we have (including debug messages)
if not msgprint:
for event in ui_queue[:]:
if isinstance(event, logging.LogRecord):
logger.handle(event)
if msgerrs:
logger.removeHandler(stderr)
else:
logger.removeHandler(stdout)
for event in ui_queue:
if isinstance(event, logging.LogRecord):
logger.handle(event)
def fire_ui_handlers(event, d):
global _thread_lock
global _thread_lock_enabled
if not _uiready:
if not _ui_handlers:
# No UI handlers registered yet, queue up the messages
ui_queue.append(event)
return
if _thread_lock_enabled:
_thread_lock.acquire()
errors = []
for h in _ui_handlers:
#print "Sending event %s" % event
@@ -208,9 +152,6 @@ def fire_ui_handlers(event, d):
for h in errors:
del _ui_handlers[h]
if _thread_lock_enabled:
_thread_lock.release()
def fire(event, d):
"""Fire off an Event"""
@@ -223,19 +164,13 @@ def fire(event, d):
if worker_fire:
worker_fire(event, d)
else:
# If messages have been queued up, clear the queue
global _uiready, ui_queue
if _uiready and ui_queue:
for queue_event in ui_queue:
fire_ui_handlers(queue_event, d)
ui_queue = []
fire_ui_handlers(event, d)
def fire_from_worker(event, d):
fire_ui_handlers(event, d)
noop = lambda _: None
def register(name, handler, mask=None, filename=None, lineno=None):
def register(name, handler, mask=[]):
"""Register an Event handler"""
# already registered
@@ -244,18 +179,10 @@ def register(name, handler, mask=None, filename=None, lineno=None):
if handler is not None:
# handle string containing python code
if isinstance(handler, str):
if isinstance(handler, basestring):
tmp = "def %s(e):\n%s" % (name, handler)
try:
code = bb.methodpool.compile_cache(tmp)
if not code:
if filename is None:
filename = "%s(e)" % name
code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
if lineno is not None:
ast.increment_lineno(code, lineno-1)
code = compile(code, filename, "exec")
bb.methodpool.compile_cache_add(tmp, code)
code = compile(tmp, "%s(e)" % name, "exec")
except SyntaxError:
logger.error("Unable to register event handler '%s':\n%s", name,
''.join(traceback.format_exc(limit=0)))
@@ -281,46 +208,23 @@ def register(name, handler, mask=None, filename=None, lineno=None):
def remove(name, handler):
"""Remove an Event handler"""
_handlers.pop(name)
if name in _catchall_handlers:
_catchall_handlers.pop(name)
for event in _event_handler_map.keys():
if name in _event_handler_map[event]:
_event_handler_map[event].pop(name)
def get_handlers():
return _handlers
def set_handlers(handlers):
global _handlers
_handlers = handlers
def set_eventfilter(func):
global _eventfilter
_eventfilter = func
def register_UIHhandler(handler, mainui=False):
def register_UIHhandler(handler):
bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1
_ui_handlers[_ui_handler_seq] = handler
level, debug_domains = bb.msg.constructLogOptions()
_ui_logfilters[_ui_handler_seq] = UIEventFilter(level, debug_domains)
if mainui:
global _uiready
_uiready = _ui_handler_seq
return _ui_handler_seq
def unregister_UIHhandler(handlerNum, mainui=False):
if mainui:
global _uiready
_uiready = False
def unregister_UIHhandler(handlerNum):
if handlerNum in _ui_handlers:
del _ui_handlers[handlerNum]
return
def get_uihandler():
if _uiready is False:
return None
return _uiready
# Class to allow filtering of events and specific filtering of LogRecords *before* we put them over the IPC
class UIEventFilter(object):
def __init__(self, level, debug_domains):
@@ -383,12 +287,6 @@ class OperationProgress(Event):
class ConfigParsed(Event):
"""Configuration Parsing Complete"""
class MultiConfigParsed(Event):
"""Multi-Config Parsing Complete"""
def __init__(self, mcdata):
self.mcdata = mcdata
Event.__init__(self)
class RecipeEvent(Event):
def __init__(self, fn):
self.fn = fn
@@ -397,17 +295,6 @@ class RecipeEvent(Event):
class RecipePreFinalise(RecipeEvent):
""" Recipe Parsing Complete but not yet finialised"""
class RecipeTaskPreProcess(RecipeEvent):
"""
Recipe Tasks about to be finalised
The list of tasks should be final at this point and handlers
are only able to change interdependencies
"""
def __init__(self, fn, tasklist):
self.fn = fn
self.tasklist = tasklist
Event.__init__(self)
class RecipeParsed(RecipeEvent):
""" Recipe Parsing Complete """
@@ -429,7 +316,7 @@ class StampUpdate(Event):
targets = property(getTargets)
class BuildBase(Event):
"""Base class for bitbake build events"""
"""Base class for bbmake run events"""
def __init__(self, n, p, failures = 0):
self._name = n
@@ -449,6 +336,12 @@ class BuildBase(Event):
def setName(self, name):
self._name = name
def getCfg(self):
return self.data
def setCfg(self, cfg):
self.data = cfg
def getFailures(self):
"""
Return the number of failed packages
@@ -457,27 +350,25 @@ class BuildBase(Event):
pkgs = property(getPkgs, setPkgs, None, "pkgs property")
name = property(getName, setName, None, "name property")
cfg = property(getCfg, setCfg, None, "cfg property")
class BuildInit(BuildBase):
"""buildFile or buildTargets was invoked"""
def __init__(self, p=[]):
name = None
BuildBase.__init__(self, name, p)
class BuildStarted(BuildBase, OperationStarted):
"""Event when builds start"""
"""bbmake build run started"""
def __init__(self, n, p, failures = 0):
OperationStarted.__init__(self, "Building Started")
BuildBase.__init__(self, n, p, failures)
class BuildCompleted(BuildBase, OperationCompleted):
"""Event when builds have completed"""
def __init__(self, total, n, p, failures=0, interrupted=0):
"""bbmake build run completed"""
def __init__(self, total, n, p, failures = 0):
if not failures:
OperationCompleted.__init__(self, total, "Building Succeeded")
else:
OperationCompleted.__init__(self, total, "Building Failed")
self._interrupted = interrupted
BuildBase.__init__(self, n, p, failures)
class DiskFull(Event):
@@ -489,27 +380,10 @@ class DiskFull(Event):
self._free = freespace
self._mountpoint = mountpoint
class DiskUsageSample:
def __init__(self, available_bytes, free_bytes, total_bytes):
# Number of bytes available to non-root processes.
self.available_bytes = available_bytes
# Number of bytes available to root processes.
self.free_bytes = free_bytes
# Total capacity of the volume.
self.total_bytes = total_bytes
class MonitorDiskEvent(Event):
"""If BB_DISKMON_DIRS is set, then this event gets triggered each time disk space is checked.
Provides information about devices that are getting monitored."""
def __init__(self, disk_usage):
Event.__init__(self)
# hash of device root path -> DiskUsageSample
self.disk_usage = disk_usage
class NoProvider(Event):
"""No Provider for an Event"""
def __init__(self, item, runtime=False, dependees=None, reasons=None, close_matches=None):
def __init__(self, item, runtime=False, dependees=None, reasons=[], close_matches=[]):
Event.__init__(self)
self._item = item
self._runtime = runtime
@@ -523,28 +397,6 @@ class NoProvider(Event):
def isRuntime(self):
return self._runtime
def __str__(self):
msg = ''
if self._runtime:
r = "R"
else:
r = ""
extra = ''
if not self._reasons:
if self._close_matches:
extra = ". Close matches:\n %s" % '\n '.join(self._close_matches)
if self._dependees:
msg = "Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s" % (r, self._item, ", ".join(self._dependees), r, extra)
else:
msg = "Nothing %sPROVIDES '%s'%s" % (r, self._item, extra)
if self._reasons:
for reason in self._reasons:
msg += '\n' + reason
return msg
class MultipleProviders(Event):
"""Multiple Providers"""
@@ -572,16 +424,6 @@ class MultipleProviders(Event):
"""
return self._candidates
def __str__(self):
msg = "Multiple providers are available for %s%s (%s)" % (self._is_runtime and "runtime " or "",
self._item,
", ".join(self._candidates))
rtime = ""
if self._is_runtime:
rtime = "R"
msg += "\nConsider defining a PREFERRED_%sPROVIDER entry to match %s" % (rtime, self._item)
return msg
class ParseStarted(OperationStarted):
"""Recipe parsing for the runqueue has begun"""
def __init__(self, total):
@@ -655,16 +497,6 @@ class TargetsTreeGenerated(Event):
Event.__init__(self)
self._model = model
class ReachableStamps(Event):
"""
An event listing all stamps reachable after parsing
which the metadata may use to clean up stale data
"""
def __init__(self, stamps):
Event.__init__(self)
self.stamps = stamps
class FilesMatchingFound(Event):
"""
Event when a list of files matching the supplied pattern has
@@ -675,6 +507,14 @@ class FilesMatchingFound(Event):
self._pattern = pattern
self._matches = matches
class CoreBaseFilesFound(Event):
"""
Event when a list of appropriate config files has been generated
"""
def __init__(self, paths):
Event.__init__(self)
self._paths = paths
class ConfigFilesFound(Event):
"""
Event when a list of appropriate config files has been generated
@@ -734,10 +574,7 @@ class LogHandler(logging.Handler):
etype, value, tb = record.exc_info
if hasattr(tb, 'tb_next'):
tb = list(bb.exceptions.extract_traceback(tb, context=3))
# Need to turn the value into something the logging system can pickle
record.bb_exc_info = (etype, value, tb)
record.bb_exc_formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
value = str(value)
record.exc_info = None
fire(record, None)
@@ -745,6 +582,19 @@ class LogHandler(logging.Handler):
record.taskpid = worker_pid
return True
class RequestPackageInfo(Event):
"""
Event to request package information
"""
class PackageInfo(Event):
"""
Package information for GUI
"""
def __init__(self, pkginfolist):
Event.__init__(self)
self._pkginfolist = pkginfolist
class MetadataEvent(Event):
"""
Generic event that target for OE-Core classes
@@ -755,33 +605,6 @@ class MetadataEvent(Event):
self.type = eventtype
self._localdata = eventdata
class ProcessStarted(Event):
"""
Generic process started event (usually part of the initial startup)
where further progress events will be delivered
"""
def __init__(self, processname, total):
Event.__init__(self)
self.processname = processname
self.total = total
class ProcessProgress(Event):
"""
Generic process progress event (usually part of the initial startup)
"""
def __init__(self, processname, progress):
Event.__init__(self)
self.processname = processname
self.progress = progress
class ProcessFinished(Event):
"""
Generic process finished event (usually part of the initial startup)
"""
def __init__(self, processname):
Event.__init__(self)
self.processname = processname
class SanityCheck(Event):
"""
Event to run sanity checks, either raise errors or generate events as return status.
@@ -822,10 +645,3 @@ class NetworkTestFailed(Event):
Event to indicate network test has failed
"""
class FindSigInfoResult(Event):
"""
Event to return results from findSigInfo command
"""
def __init__(self, result):
Event.__init__(self)
self.result = result

View File

@@ -1,4 +1,4 @@
from __future__ import absolute_import
import inspect
import traceback
import bb.namedtuple_with_abc
@@ -86,6 +86,6 @@ def format_exception(etype, value, tb, context=1, limit=None, formatter=None):
def to_string(exc):
if isinstance(exc, SystemExit):
if not isinstance(exc.code, str):
if not isinstance(exc.code, basestring):
return 'Exited with "%d"' % exc.code
return str(exc)

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@ import os
import sys
import logging
import bb
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import runfetchcmd
@@ -42,14 +43,14 @@ class Bzr(FetchMethod):
"""
# Create paths to bzr checkouts
relpath = self._strip_leading_slashes(ud.path)
ud.pkgdir = os.path.join(d.expand('${BZRDIR}'), ud.host, relpath)
ud.pkgdir = os.path.join(data.expand('${BZRDIR}', d), ud.host, relpath)
ud.setup_revisions(d)
ud.setup_revisons(d)
if not ud.revision:
ud.revision = self.latest_revision(ud, d)
ud.localfile = d.expand('bzr_%s_%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.revision))
ud.localfile = data.expand('bzr_%s_%s_%s.tar.gz' % (ud.host, ud.path.replace('/', '.'), ud.revision), d)
def _buildbzrcommand(self, ud, d, command):
"""
@@ -57,7 +58,7 @@ class Bzr(FetchMethod):
command is "fetch", "update", "revno"
"""
basecmd = d.expand('${FETCHCMD_bzr}')
basecmd = data.expand('${FETCHCMD_bzr}', d)
proto = ud.parm.get('protocol', 'http')
@@ -87,25 +88,28 @@ class Bzr(FetchMethod):
bzrcmd = self._buildbzrcommand(ud, d, "update")
logger.debug(1, "BZR Update %s", ud.url)
bb.fetch2.check_network_access(d, bzrcmd, ud.url)
runfetchcmd(bzrcmd, d, workdir=os.path.join(ud.pkgdir, os.path.basename(ud.path)))
os.chdir(os.path.join (ud.pkgdir, os.path.basename(ud.path)))
runfetchcmd(bzrcmd, d)
else:
bb.utils.remove(os.path.join(ud.pkgdir, os.path.basename(ud.pkgdir)), True)
bzrcmd = self._buildbzrcommand(ud, d, "fetch")
bb.fetch2.check_network_access(d, bzrcmd, ud.url)
logger.debug(1, "BZR Checkout %s", ud.url)
bb.utils.mkdirhier(ud.pkgdir)
os.chdir(ud.pkgdir)
logger.debug(1, "Running %s", bzrcmd)
runfetchcmd(bzrcmd, d, workdir=ud.pkgdir)
runfetchcmd(bzrcmd, d)
os.chdir(ud.pkgdir)
scmdata = ud.parm.get("scmdata", "")
if scmdata == "keep":
tar_flags = ""
else:
tar_flags = "--exclude='.bzr' --exclude='.bzrtags'"
tar_flags = "--exclude '.bzr' --exclude '.bzrtags'"
# tar them up to a defined filename
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.basename(ud.pkgdir)),
d, cleanup=[ud.localpath], workdir=ud.pkgdir)
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.basename(ud.pkgdir)), d, cleanup = [ud.localpath])
def supports_srcrev(self):
return True

View File

@@ -9,7 +9,7 @@ Usage in the recipe:
SRC_URI = "ccrc://cc.example.org/ccrc;vob=/example_vob;module=/example_module"
SRCREV = "EXAMPLE_CLEARCASE_TAG"
PV = "${@d.getVar("SRCREV", False).replace("/", "+")}"
PV = "${@d.getVar("SRCREV").replace("/", "+")}"
The fetcher uses the rcleartool or cleartool remote client, depending on which one is available.
@@ -65,10 +65,12 @@ import os
import sys
import shutil
import bb
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
from distutils import spawn
class ClearCase(FetchMethod):
"""Class to fetch urls via 'clearcase'"""
@@ -106,13 +108,13 @@ class ClearCase(FetchMethod):
else:
ud.module = ""
ud.basecmd = d.getVar("FETCHCMD_ccrc") or "/usr/bin/env cleartool || rcleartool"
ud.basecmd = d.getVar("FETCHCMD_ccrc", True) or spawn.find_executable("cleartool") or spawn.find_executable("rcleartool")
if d.getVar("SRCREV") == "INVALID":
if data.getVar("SRCREV", d, True) == "INVALID":
raise FetchError("Set a valid SRCREV for the clearcase fetcher in your recipe, e.g. SRCREV = \"/main/LATEST\" or any other label of your choice.")
ud.label = d.getVar("SRCREV", False)
ud.customspec = d.getVar("CCASE_CUSTOM_CONFIG_SPEC")
ud.label = d.getVar("SRCREV")
ud.customspec = d.getVar("CCASE_CUSTOM_CONFIG_SPEC", True)
ud.server = "%s://%s%s" % (ud.proto, ud.host, ud.path)
@@ -122,7 +124,7 @@ class ClearCase(FetchMethod):
ud.viewname = "%s-view%s" % (ud.identifier, d.getVar("DATETIME", d, True))
ud.csname = "%s-config-spec" % (ud.identifier)
ud.ccasedir = os.path.join(d.getVar("DL_DIR"), ud.type)
ud.ccasedir = os.path.join(data.getVar("DL_DIR", d, True), ud.type)
ud.viewdir = os.path.join(ud.ccasedir, ud.viewname)
ud.configspecfile = os.path.join(ud.ccasedir, ud.csname)
ud.localfile = "%s.tar.gz" % (ud.identifier)
@@ -142,7 +144,7 @@ class ClearCase(FetchMethod):
self.debug("configspecfile = %s" % ud.configspecfile)
self.debug("localfile = %s" % ud.localfile)
ud.localfile = os.path.join(d.getVar("DL_DIR"), ud.localfile)
ud.localfile = os.path.join(data.getVar("DL_DIR", d, True), ud.localfile)
def _build_ccase_command(self, ud, command):
"""
@@ -200,10 +202,11 @@ class ClearCase(FetchMethod):
def _remove_view(self, ud, d):
if os.path.exists(ud.viewdir):
os.chdir(ud.ccasedir)
cmd = self._build_ccase_command(ud, 'rmview');
logger.info("cleaning up [VOB=%s label=%s view=%s]", ud.vob, ud.label, ud.viewname)
bb.fetch2.check_network_access(d, cmd, ud.url)
output = runfetchcmd(cmd, d, workdir=ud.ccasedir)
output = runfetchcmd(cmd, d)
logger.info("rmview output: %s", output)
def need_update(self, ud, d):
@@ -238,10 +241,11 @@ class ClearCase(FetchMethod):
raise e
# Set configspec: Setting the configspec effectively fetches the files as defined in the configspec
os.chdir(ud.viewdir)
cmd = self._build_ccase_command(ud, 'setcs');
logger.info("fetching data [VOB=%s label=%s view=%s]", ud.vob, ud.label, ud.viewname)
bb.fetch2.check_network_access(d, cmd, ud.url)
output = runfetchcmd(cmd, d, workdir=ud.viewdir)
output = runfetchcmd(cmd, d)
logger.info("%s", output)
# Copy the configspec to the viewdir so we have it in our source tarball later

View File

@@ -63,7 +63,7 @@ class Cvs(FetchMethod):
if 'fullpath' in ud.parm:
fullpath = '_fullpath'
ud.localfile = d.expand('%s_%s_%s_%s%s%s.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.tag, ud.date, norecurse, fullpath))
ud.localfile = bb.data.expand('%s_%s_%s_%s%s%s.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.tag, ud.date, norecurse, fullpath), d)
def need_update(self, ud, d):
if (ud.date == "now"):
@@ -87,10 +87,10 @@ class Cvs(FetchMethod):
cvsroot = ud.path
else:
cvsroot = ":" + method
cvsproxyhost = d.getVar('CVS_PROXY_HOST')
cvsproxyhost = d.getVar('CVS_PROXY_HOST', True)
if cvsproxyhost:
cvsroot += ";proxy=" + cvsproxyhost
cvsproxyport = d.getVar('CVS_PROXY_PORT')
cvsproxyport = d.getVar('CVS_PROXY_PORT', True)
if cvsproxyport:
cvsroot += ";proxyport=" + cvsproxyport
cvsroot += ":" + ud.user
@@ -110,7 +110,7 @@ class Cvs(FetchMethod):
if ud.tag:
options.append("-r %s" % ud.tag)
cvsbasecmd = d.getVar("FETCHCMD_cvs")
cvsbasecmd = d.getVar("FETCHCMD_cvs", True)
cvscmd = cvsbasecmd + " '-d" + cvsroot + "' co " + " ".join(options) + " " + ud.module
cvsupdatecmd = cvsbasecmd + " '-d" + cvsroot + "' update -d -P " + " ".join(options)
@@ -120,26 +120,25 @@ class Cvs(FetchMethod):
# create module directory
logger.debug(2, "Fetch: checking for module directory")
pkg = d.getVar('PN')
pkgdir = os.path.join(d.getVar('CVSDIR'), pkg)
pkg = d.getVar('PN', True)
pkgdir = os.path.join(d.getVar('CVSDIR', True), pkg)
moddir = os.path.join(pkgdir, localdir)
workdir = None
if os.access(os.path.join(moddir, 'CVS'), os.R_OK):
logger.info("Update " + ud.url)
bb.fetch2.check_network_access(d, cvsupdatecmd, ud.url)
# update sources there
workdir = moddir
os.chdir(moddir)
cmd = cvsupdatecmd
else:
logger.info("Fetch " + ud.url)
# check out sources there
bb.utils.mkdirhier(pkgdir)
workdir = pkgdir
os.chdir(pkgdir)
logger.debug(1, "Running %s", cvscmd)
bb.fetch2.check_network_access(d, cvscmd, ud.url)
cmd = cvscmd
runfetchcmd(cmd, d, cleanup=[moddir], workdir=workdir)
runfetchcmd(cmd, d, cleanup = [moddir])
if not os.access(moddir, os.R_OK):
raise FetchError("Directory %s was not readable despite sucessful fetch?!" % moddir, ud.url)
@@ -148,24 +147,24 @@ class Cvs(FetchMethod):
if scmdata == "keep":
tar_flags = ""
else:
tar_flags = "--exclude='CVS'"
tar_flags = "--exclude 'CVS'"
# tar them up to a defined filename
workdir = None
if 'fullpath' in ud.parm:
workdir = pkgdir
os.chdir(pkgdir)
cmd = "tar %s -czf %s %s" % (tar_flags, ud.localpath, localdir)
else:
workdir = os.path.dirname(os.path.realpath(moddir))
os.chdir(moddir)
os.chdir('..')
cmd = "tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.basename(moddir))
runfetchcmd(cmd, d, cleanup=[ud.localpath], workdir=workdir)
runfetchcmd(cmd, d, cleanup = [ud.localpath])
def clean(self, ud, d):
""" Clean CVS Files and tarballs """
pkg = d.getVar('PN')
pkgdir = os.path.join(d.getVar("CVSDIR"), pkg)
pkg = d.getVar('PN', True)
pkgdir = os.path.join(d.getVar("CVSDIR", True), pkg)
bb.utils.remove(pkgdir, True)
bb.utils.remove(ud.localpath)

View File

@@ -49,10 +49,6 @@ Supported SRC_URI options are:
referring to commit which is valid in tag instead of branch.
The default is "0", set nobranch=1 if needed.
- usehead
For local git:// urls to use the current branch HEAD as the revision for use with
AUTOREV. Implies nobranch.
"""
#Copyright (C) 2005 Richard Purdie
@@ -70,64 +66,15 @@ Supported SRC_URI options are:
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import collections
import errno
import fnmatch
import os
import re
import subprocess
import tempfile
import bb
import bb.progress
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
class GitProgressHandler(bb.progress.LineFilterProgressHandler):
"""Extract progress information from git output"""
def __init__(self, d):
self._buffer = ''
self._count = 0
super(GitProgressHandler, self).__init__(d)
# Send an initial progress event so the bar gets shown
self._fire_progress(-1)
def write(self, string):
self._buffer += string
stages = ['Counting objects', 'Compressing objects', 'Receiving objects', 'Resolving deltas']
stage_weights = [0.2, 0.05, 0.5, 0.25]
stagenum = 0
for i, stage in reversed(list(enumerate(stages))):
if stage in self._buffer:
stagenum = i
self._buffer = ''
break
self._status = stages[stagenum]
percs = re.findall(r'(\d+)%', string)
if percs:
progress = int(round((int(percs[-1]) * stage_weights[stagenum]) + (sum(stage_weights[:stagenum]) * 100)))
rates = re.findall(r'([\d.]+ [a-zA-Z]*/s+)', string)
if rates:
rate = rates[-1]
else:
rate = None
self.update(progress, rate)
else:
if stagenum == 0:
percs = re.findall(r': (\d+)', string)
if percs:
count = int(percs[-1])
if count > self._count:
self._count = count
self._fire_progress(-count)
super(GitProgressHandler, self).write(string)
class Git(FetchMethod):
bitbake_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.join(os.path.abspath(__file__))), '..', '..', '..'))
make_shallow_path = os.path.join(bitbake_dir, 'bin', 'git-make-shallow')
"""Class to fetch a module or modules from git repositories"""
def init(self, d):
pass
@@ -162,13 +109,6 @@ class Git(FetchMethod):
ud.nobranch = ud.parm.get("nobranch","0") == "1"
# usehead implies nobranch
ud.usehead = ud.parm.get("usehead","0") == "1"
if ud.usehead:
if ud.proto != "file":
raise bb.fetch2.ParameterError("The usehead option is only for use with local ('protocol=file') git repositories", ud.url)
ud.nobranch = 1
# bareclone implies nocheckout
ud.bareclone = ud.parm.get("bareclone","0") == "1"
if ud.bareclone:
@@ -178,68 +118,17 @@ class Git(FetchMethod):
branches = ud.parm.get("branch", "master").split(',')
if len(branches) != len(ud.names):
raise bb.fetch2.ParameterError("The number of name and branch parameters is not balanced", ud.url)
ud.cloneflags = "-s -n"
if ud.bareclone:
ud.cloneflags += " --mirror"
ud.shallow = d.getVar("BB_GIT_SHALLOW") == "1"
ud.shallow_extra_refs = (d.getVar("BB_GIT_SHALLOW_EXTRA_REFS") or "").split()
depth_default = d.getVar("BB_GIT_SHALLOW_DEPTH")
if depth_default is not None:
try:
depth_default = int(depth_default or 0)
except ValueError:
raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH: %s" % depth_default)
else:
if depth_default < 0:
raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH: %s" % depth_default)
else:
depth_default = 1
ud.shallow_depths = collections.defaultdict(lambda: depth_default)
revs_default = d.getVar("BB_GIT_SHALLOW_REVS", True)
ud.shallow_revs = []
ud.branches = {}
for pos, name in enumerate(ud.names):
branch = branches[pos]
for name in ud.names:
branch = branches[ud.names.index(name)]
ud.branches[name] = branch
ud.unresolvedrev[name] = branch
shallow_depth = d.getVar("BB_GIT_SHALLOW_DEPTH_%s" % name)
if shallow_depth is not None:
try:
shallow_depth = int(shallow_depth or 0)
except ValueError:
raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH_%s: %s" % (name, shallow_depth))
else:
if shallow_depth < 0:
raise bb.fetch2.FetchError("Invalid depth for BB_GIT_SHALLOW_DEPTH_%s: %s" % (name, shallow_depth))
ud.shallow_depths[name] = shallow_depth
ud.basecmd = data.getVar("FETCHCMD_git", d, True) or "git -c core.fsyncobjectfiles=0"
revs = d.getVar("BB_GIT_SHALLOW_REVS_%s" % name)
if revs is not None:
ud.shallow_revs.extend(revs.split())
elif revs_default is not None:
ud.shallow_revs.extend(revs_default.split())
ud.write_tarballs = ((data.getVar("BB_GENERATE_MIRROR_TARBALLS", d, True) or "0") != "0") or ud.rebaseable
if (ud.shallow and
not ud.shallow_revs and
all(ud.shallow_depths[n] == 0 for n in ud.names)):
# Shallow disabled for this URL
ud.shallow = False
if ud.usehead:
ud.unresolvedrev['default'] = 'HEAD'
ud.basecmd = d.getVar("FETCHCMD_git") or "git -c core.fsyncobjectfiles=0"
write_tarballs = d.getVar("BB_GENERATE_MIRROR_TARBALLS") or "0"
ud.write_tarballs = write_tarballs != "0" or ud.rebaseable
ud.write_shallow_tarballs = (d.getVar("BB_GENERATE_SHALLOW_TARBALLS") or write_tarballs) != "0"
ud.setup_revisions(d)
ud.setup_revisons(d)
for name in ud.names:
# Ensure anything that doesn't look like a sha256 checksum/revision is translated into one
@@ -248,10 +137,7 @@ class Git(FetchMethod):
ud.unresolvedrev[name] = ud.revisions[name]
ud.revisions[name] = self.latest_revision(ud, d, name)
gitsrcname = '%s%s' % (ud.host.replace(':', '.'), ud.path.replace('/', '.').replace('*', '.'))
if gitsrcname.startswith('.'):
gitsrcname = gitsrcname[1:]
gitsrcname = '%s%s' % (ud.host.replace(':','.'), ud.path.replace('/', '.').replace('*', '.'))
# for rebaseable git repo, it is necessary to keep mirror tar ball
# per revision, so that even the revision disappears from the
# upstream repo in the future, the mirror will remain intact and still
@@ -259,53 +145,23 @@ class Git(FetchMethod):
if ud.rebaseable:
for name in ud.names:
gitsrcname = gitsrcname + '_' + ud.revisions[name]
dl_dir = d.getVar("DL_DIR")
gitdir = d.getVar("GITDIR") or (dl_dir + "/git2/")
ud.mirrortarball = 'git2_%s.tar.gz' % (gitsrcname)
ud.fullmirror = os.path.join(d.getVar("DL_DIR", True), ud.mirrortarball)
gitdir = d.getVar("GITDIR", True) or (d.getVar("DL_DIR", True) + "/git2/")
ud.clonedir = os.path.join(gitdir, gitsrcname)
ud.localfile = ud.clonedir
mirrortarball = 'git2_%s.tar.gz' % gitsrcname
ud.fullmirror = os.path.join(dl_dir, mirrortarball)
ud.mirrortarballs = [mirrortarball]
if ud.shallow:
tarballname = gitsrcname
if ud.bareclone:
tarballname = "%s_bare" % tarballname
if ud.shallow_revs:
tarballname = "%s_%s" % (tarballname, "_".join(sorted(ud.shallow_revs)))
for name, revision in sorted(ud.revisions.items()):
tarballname = "%s_%s" % (tarballname, ud.revisions[name][:7])
depth = ud.shallow_depths[name]
if depth:
tarballname = "%s-%s" % (tarballname, depth)
shallow_refs = []
if not ud.nobranch:
shallow_refs.extend(ud.branches.values())
if ud.shallow_extra_refs:
shallow_refs.extend(r.replace('refs/heads/', '').replace('*', 'ALL') for r in ud.shallow_extra_refs)
if shallow_refs:
tarballname = "%s_%s" % (tarballname, "_".join(sorted(shallow_refs)).replace('/', '.'))
fetcher = self.__class__.__name__.lower()
ud.shallowtarball = '%sshallow_%s.tar.gz' % (fetcher, tarballname)
ud.fullshallow = os.path.join(dl_dir, ud.shallowtarball)
ud.mirrortarballs.insert(0, ud.shallowtarball)
def localpath(self, ud, d):
return ud.clonedir
def need_update(self, ud, d):
if not os.path.exists(ud.clonedir):
return True
os.chdir(ud.clonedir)
for name in ud.names:
if not self._contains_ref(ud, d, name, ud.clonedir):
if not self._contains_ref(ud, d, name):
return True
if ud.shallow and ud.write_shallow_tarballs and not os.path.exists(ud.fullshallow):
return True
if ud.write_tarballs and not os.path.exists(ud.fullmirror):
return True
return False
@@ -313,7 +169,7 @@ class Git(FetchMethod):
def try_premirror(self, ud, d):
# If we don't do this, updating an existing checkout with only premirrors
# is not possible
if d.getVar("BB_FETCH_PREMIRRORONLY") is not None:
if d.getVar("BB_FETCH_PREMIRRORONLY", True) is not None:
return True
if os.path.exists(ud.clonedir):
return False
@@ -322,145 +178,74 @@ class Git(FetchMethod):
def download(self, ud, d):
"""Fetch url"""
no_clone = not os.path.exists(ud.clonedir)
need_update = no_clone or self.need_update(ud, d)
if ud.user:
username = ud.user + '@'
else:
username = ""
# A current clone is preferred to either tarball, a shallow tarball is
# preferred to an out of date clone, and a missing clone will use
# either tarball.
if ud.shallow and os.path.exists(ud.fullshallow) and need_update:
ud.localpath = ud.fullshallow
return
elif os.path.exists(ud.fullmirror) and no_clone:
ud.repochanged = not os.path.exists(ud.fullmirror)
# If the checkout doesn't exist and the mirror tarball does, extract it
if not os.path.exists(ud.clonedir) and os.path.exists(ud.fullmirror):
bb.utils.mkdirhier(ud.clonedir)
runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=ud.clonedir)
os.chdir(ud.clonedir)
runfetchcmd("tar -xzf %s" % (ud.fullmirror), d)
repourl = self._get_repo_url(ud)
repourl = "%s://%s%s%s" % (ud.proto, username, ud.host, ud.path)
# If the repo still doesn't exist, fallback to cloning it
if not os.path.exists(ud.clonedir):
# We do this since git will use a "-l" option automatically for local urls where possible
if repourl.startswith("file://"):
repourl = repourl[7:]
clone_cmd = "LANG=C %s clone --bare --mirror %s %s --progress" % (ud.basecmd, repourl, ud.clonedir)
clone_cmd = "%s clone --bare --mirror %s %s" % (ud.basecmd, repourl, ud.clonedir)
if ud.proto.lower() != 'file':
bb.fetch2.check_network_access(d, clone_cmd, ud.url)
progresshandler = GitProgressHandler(d)
runfetchcmd(clone_cmd, d, log=progresshandler)
bb.fetch2.check_network_access(d, clone_cmd)
runfetchcmd(clone_cmd, d)
os.chdir(ud.clonedir)
# Update the checkout if needed
needupdate = False
for name in ud.names:
if not self._contains_ref(ud, d, name, ud.clonedir):
if not self._contains_ref(ud, d, name):
needupdate = True
if needupdate:
output = runfetchcmd("%s remote" % ud.basecmd, d, quiet=True, workdir=ud.clonedir)
if "origin" in output:
runfetchcmd("%s remote rm origin" % ud.basecmd, d, workdir=ud.clonedir)
try:
runfetchcmd("%s remote rm origin" % ud.basecmd, d)
except bb.fetch2.FetchError:
logger.debug(1, "No Origin")
runfetchcmd("%s remote add --mirror=fetch origin %s" % (ud.basecmd, repourl), d, workdir=ud.clonedir)
fetch_cmd = "LANG=C %s fetch -f --progress %s refs/*:refs/*" % (ud.basecmd, repourl)
runfetchcmd("%s remote add --mirror=fetch origin %s" % (ud.basecmd, repourl), d)
fetch_cmd = "%s fetch -f --prune %s refs/*:refs/*" % (ud.basecmd, repourl)
if ud.proto.lower() != 'file':
bb.fetch2.check_network_access(d, fetch_cmd, ud.url)
progresshandler = GitProgressHandler(d)
runfetchcmd(fetch_cmd, d, log=progresshandler, workdir=ud.clonedir)
runfetchcmd("%s prune-packed" % ud.basecmd, d, workdir=ud.clonedir)
runfetchcmd("%s pack-refs --all" % ud.basecmd, d, workdir=ud.clonedir)
runfetchcmd("%s pack-redundant --all | xargs -r rm" % ud.basecmd, d, workdir=ud.clonedir)
try:
os.unlink(ud.fullmirror)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
runfetchcmd(fetch_cmd, d)
runfetchcmd("%s prune-packed" % ud.basecmd, d)
runfetchcmd("%s pack-redundant --all | xargs -r rm" % ud.basecmd, d)
ud.repochanged = True
os.chdir(ud.clonedir)
for name in ud.names:
if not self._contains_ref(ud, d, name, ud.clonedir):
if not self._contains_ref(ud, d, name):
raise bb.fetch2.FetchError("Unable to find revision %s in branch %s even from upstream" % (ud.revisions[name], ud.branches[name]))
def build_mirror_data(self, ud, d):
if ud.shallow and ud.write_shallow_tarballs:
if not os.path.exists(ud.fullshallow):
if os.path.islink(ud.fullshallow):
os.unlink(ud.fullshallow)
tempdir = tempfile.mkdtemp(dir=d.getVar('DL_DIR'))
shallowclone = os.path.join(tempdir, 'git')
try:
self.clone_shallow_local(ud, shallowclone, d)
logger.info("Creating tarball of git repository")
runfetchcmd("tar -czf %s ." % ud.fullshallow, d, workdir=shallowclone)
runfetchcmd("touch %s.done" % ud.fullshallow, d)
finally:
bb.utils.remove(tempdir, recurse=True)
elif ud.write_tarballs and not os.path.exists(ud.fullmirror):
# Generate a mirror tarball if needed
if ud.write_tarballs and (ud.repochanged or not os.path.exists(ud.fullmirror)):
# it's possible that this symlink points to read-only filesystem with PREMIRROR
if os.path.islink(ud.fullmirror):
os.unlink(ud.fullmirror)
os.chdir(ud.clonedir)
logger.info("Creating tarball of git repository")
runfetchcmd("tar -czf %s ." % ud.fullmirror, d, workdir=ud.clonedir)
runfetchcmd("touch %s.done" % ud.fullmirror, d)
def clone_shallow_local(self, ud, dest, d):
"""Clone the repo and make it shallow.
The upstream url of the new clone isn't set at this time, as it'll be
set correctly when unpacked."""
runfetchcmd("%s clone %s %s %s" % (ud.basecmd, ud.cloneflags, ud.clonedir, dest), d)
to_parse, shallow_branches = [], []
for name in ud.names:
revision = ud.revisions[name]
depth = ud.shallow_depths[name]
if depth:
to_parse.append('%s~%d^{}' % (revision, depth - 1))
# For nobranch, we need a ref, otherwise the commits will be
# removed, and for non-nobranch, we truncate the branch to our
# srcrev, to avoid keeping unnecessary history beyond that.
branch = ud.branches[name]
if ud.nobranch:
ref = "refs/shallow/%s" % name
elif ud.bareclone:
ref = "refs/heads/%s" % branch
else:
ref = "refs/remotes/origin/%s" % branch
shallow_branches.append(ref)
runfetchcmd("%s update-ref %s %s" % (ud.basecmd, ref, revision), d, workdir=dest)
# Map srcrev+depths to revisions
parsed_depths = runfetchcmd("%s rev-parse %s" % (ud.basecmd, " ".join(to_parse)), d, workdir=dest)
# Resolve specified revisions
parsed_revs = runfetchcmd("%s rev-parse %s" % (ud.basecmd, " ".join('"%s^{}"' % r for r in ud.shallow_revs)), d, workdir=dest)
shallow_revisions = parsed_depths.splitlines() + parsed_revs.splitlines()
# Apply extra ref wildcards
all_refs = runfetchcmd('%s for-each-ref "--format=%%(refname)"' % ud.basecmd,
d, workdir=dest).splitlines()
for r in ud.shallow_extra_refs:
if not ud.bareclone:
r = r.replace('refs/heads/', 'refs/remotes/origin/')
if '*' in r:
matches = filter(lambda a: fnmatch.fnmatchcase(a, r), all_refs)
shallow_branches.extend(matches)
else:
shallow_branches.append(r)
# Make the repository shallow
shallow_cmd = [self.make_shallow_path, '-s']
for b in shallow_branches:
shallow_cmd.append('-r')
shallow_cmd.append(b)
shallow_cmd.extend(shallow_revisions)
runfetchcmd(subprocess.list2cmdline(shallow_cmd), d, workdir=dest)
runfetchcmd("tar -czf %s %s" % (ud.fullmirror, os.path.join(".") ), d)
runfetchcmd("touch %s.done" % (ud.fullmirror), d)
def unpack(self, ud, destdir, d):
""" unpack the downloaded src to destdir"""
subdir = ud.parm.get("subpath", "")
if subdir != "":
readpathspec = ":%s" % subdir
readpathspec = ":%s" % (subdir)
def_destsuffix = "%s/" % os.path.basename(subdir.rstrip('/'))
else:
readpathspec = ""
@@ -471,28 +256,34 @@ class Git(FetchMethod):
if os.path.exists(destdir):
bb.utils.prunedir(destdir)
if ud.shallow and (not os.path.exists(ud.clonedir) or self.need_update(ud, d)):
bb.utils.mkdirhier(destdir)
runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=destdir)
else:
runfetchcmd("%s clone %s %s/ %s" % (ud.basecmd, ud.cloneflags, ud.clonedir, destdir), d)
cloneflags = "-s -n"
if ud.bareclone:
cloneflags += " --mirror"
repourl = self._get_repo_url(ud)
runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, repourl), d, workdir=destdir)
# Versions of git prior to 1.7.9.2 have issues where foo.git and foo get confused
# and you end up with some horrible union of the two when you attempt to clone it
# The least invasive workaround seems to be a symlink to the real directory to
# fool git into ignoring any .git version that may also be present.
#
# The issue is fixed in more recent versions of git so we can drop this hack in future
# when that version becomes common enough.
clonedir = ud.clonedir
if not ud.path.endswith(".git"):
indirectiondir = destdir[:-1] + ".indirectionsymlink"
if os.path.exists(indirectiondir):
os.remove(indirectiondir)
bb.utils.mkdirhier(os.path.dirname(indirectiondir))
os.symlink(ud.clonedir, indirectiondir)
clonedir = indirectiondir
runfetchcmd("%s clone %s %s/ %s" % (ud.basecmd, cloneflags, clonedir, destdir), d)
if not ud.nocheckout:
os.chdir(destdir)
if subdir != "":
runfetchcmd("%s read-tree %s%s" % (ud.basecmd, ud.revisions[ud.names[0]], readpathspec), d,
workdir=destdir)
runfetchcmd("%s checkout-index -q -f -a" % ud.basecmd, d, workdir=destdir)
elif not ud.nobranch:
branchname = ud.branches[ud.names[0]]
runfetchcmd("%s checkout -B %s %s" % (ud.basecmd, branchname, \
ud.revisions[ud.names[0]]), d, workdir=destdir)
runfetchcmd("%s branch %s --set-upstream-to origin/%s" % (ud.basecmd, branchname, \
branchname), d, workdir=destdir)
runfetchcmd("%s read-tree %s%s" % (ud.basecmd, ud.revisions[ud.names[0]], readpathspec), d)
runfetchcmd("%s checkout-index -q -f -a" % ud.basecmd, d)
else:
runfetchcmd("%s checkout %s" % (ud.basecmd, ud.revisions[ud.names[0]]), d, workdir=destdir)
runfetchcmd("%s checkout %s" % (ud.basecmd, ud.revisions[ud.names[0]]), d)
return True
def clean(self, ud, d):
@@ -505,7 +296,7 @@ class Git(FetchMethod):
def supports_srcrev(self):
return True
def _contains_ref(self, ud, d, name, wd):
def _contains_ref(self, ud, d, name):
cmd = ""
if ud.nobranch:
cmd = "%s log --pretty=oneline -n 1 %s -- 2> /dev/null | wc -l" % (
@@ -514,23 +305,13 @@ class Git(FetchMethod):
cmd = "%s branch --contains %s --list %s 2> /dev/null | wc -l" % (
ud.basecmd, ud.revisions[name], ud.branches[name])
try:
output = runfetchcmd(cmd, d, quiet=True, workdir=wd)
output = runfetchcmd(cmd, d, quiet=True)
except bb.fetch2.FetchError:
return False
if len(output.split()) > 1:
raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output))
return output.split()[0] != "0"
def _get_repo_url(self, ud):
"""
Return the repository URL
"""
if ud.user:
username = ud.user + '@'
else:
username = ""
return "%s://%s%s%s" % (ud.proto, username, ud.host, ud.path)
def _revision_key(self, ud, d, name):
"""
Return a unique key for the url
@@ -541,26 +322,18 @@ class Git(FetchMethod):
"""
Run git ls-remote with the specified search string
"""
# Prevent recursion e.g. in OE if SRCPV is in PV, PV is in WORKDIR,
# and WORKDIR is in PATH (as a result of RSS), our call to
# runfetchcmd() exports PATH so this function will get called again (!)
# In this scenario the return call of the function isn't actually
# important - WORKDIR isn't needed in PATH to call git ls-remote
# anyway.
if d.getVar('_BB_GIT_IN_LSREMOTE', False):
return ''
d.setVar('_BB_GIT_IN_LSREMOTE', '1')
try:
repourl = self._get_repo_url(ud)
cmd = "%s ls-remote %s %s" % \
(ud.basecmd, repourl, search)
if ud.proto.lower() != 'file':
bb.fetch2.check_network_access(d, cmd, repourl)
output = runfetchcmd(cmd, d, True)
if not output:
raise bb.fetch2.FetchError("The command %s gave empty output unexpectedly" % cmd, ud.url)
finally:
d.delVar('_BB_GIT_IN_LSREMOTE')
if ud.user:
username = ud.user + '@'
else:
username = ""
cmd = "%s ls-remote %s://%s%s%s %s" % \
(ud.basecmd, ud.proto, username, ud.host, ud.path, search)
if ud.proto.lower() != 'file':
bb.fetch2.check_network_access(d, cmd)
output = runfetchcmd(cmd, d, True)
if not output:
raise bb.fetch2.FetchError("The command %s gave empty output unexpectedly" % cmd, ud.url)
return output
def _latest_revision(self, ud, d, name):
@@ -569,19 +342,17 @@ class Git(FetchMethod):
"""
output = self._lsremote(ud, d, "")
# Tags of the form ^{} may not work, need to fallback to other form
if ud.unresolvedrev[name][:5] == "refs/" or ud.usehead:
if ud.unresolvedrev[name][:5] == "refs/":
head = ud.unresolvedrev[name]
tag = ud.unresolvedrev[name]
else:
head = "refs/heads/%s" % ud.unresolvedrev[name]
tag = "refs/tags/%s" % ud.unresolvedrev[name]
for s in [head, tag + "^{}", tag]:
for l in output.strip().split('\n'):
sha1, ref = l.split()
if s == ref:
return sha1
raise bb.fetch2.FetchError("Unable to resolve '%s' in upstream git repository in git ls-remote output for %s" % \
(ud.unresolvedrev[name], ud.host+ud.path))
for l in output.split('\n'):
if s in l:
return l.split()[0]
raise bb.fetch2.FetchError("Unable to resolve '%s' in upstream git repository in git ls-remote output" % ud.unresolvedrev[name])
def latest_versionstring(self, ud, d):
"""
@@ -589,29 +360,25 @@ class Git(FetchMethod):
by searching through the tags output of ls-remote, comparing
versions and returning the highest match.
"""
pupver = ('', '')
tagregex = re.compile(d.getVar('UPSTREAM_CHECK_GITTAGREGEX') or "(?P<pver>([0-9][\.|_]?)+)")
try:
output = self._lsremote(ud, d, "refs/tags/*")
except (bb.fetch2.FetchError, bb.fetch2.NetworkAccess) as e:
bb.note("Could not list remote: %s" % str(e))
return pupver
verstring = ""
revision = ""
tagregex = re.compile(d.getVar('GITTAGREGEX', True) or "(?P<pver>([0-9][\.|_]?)+)")
try:
output = self._lsremote(ud, d, "refs/tags/*^{}")
except bb.fetch2.FetchError or bb.fetch2.NetworkAccess:
return ""
for line in output.split("\n"):
if not line:
break
tag_head = line.split("/")[-1]
line = line.split("/")[-1]
# Ignore non-released branches
m = re.search("(alpha|beta|rc|final)+", tag_head)
m = re.search("(alpha|beta|rc|final)+", line)
if m:
continue
# search for version in the line
tag = tagregex.search(tag_head)
tag = tagregex.search(line)
if tag == None:
continue
@@ -620,44 +387,16 @@ class Git(FetchMethod):
if verstring and bb.utils.vercmp(("0", tag, ""), ("0", verstring, "")) < 0:
continue
verstring = tag
revision = line.split()[0]
pupver = (verstring, revision)
return pupver
return verstring
def _build_revision(self, ud, d, name):
return ud.revisions[name]
def gitpkgv_revision(self, ud, d, name):
"""
Return a sortable revision number by counting commits in the history
Based on gitpkgv.bblass in meta-openembedded
"""
rev = self._build_revision(ud, d, name)
localpath = ud.localpath
rev_file = os.path.join(localpath, "oe-gitpkgv_" + rev)
if not os.path.exists(localpath):
commits = None
else:
if not os.path.exists(rev_file) or not os.path.getsize(rev_file):
from pipes import quote
commits = bb.fetch2.runfetchcmd(
"git rev-list %s -- | wc -l" % quote(rev),
d, quiet=True).strip().lstrip('0')
if commits:
open(rev_file, "w").write("%d\n" % int(commits))
else:
commits = open(rev_file, "r").readline(128).strip()
if commits:
return False, "%s+%s" % (commits, rev[:7])
else:
return True, str(rev)
def checkstatus(self, fetch, ud, d):
def checkstatus(self, ud, d):
try:
self._lsremote(ud, d, "")
return True
except bb.fetch2.FetchError:
except FetchError:
return False

View File

@@ -22,6 +22,7 @@ BitBake 'Fetch' git annex implementation
import os
import bb
from bb import data
from bb.fetch2.git import Git
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
@@ -33,59 +34,43 @@ class GitANNEX(Git):
"""
return ud.type in ['gitannex']
def urldata_init(self, ud, d):
super(GitANNEX, self).urldata_init(ud, d)
if ud.shallow:
ud.shallow_extra_refs += ['refs/heads/git-annex', 'refs/heads/synced/*']
def uses_annex(self, ud, d, wd):
def uses_annex(self, ud, d):
for name in ud.names:
try:
runfetchcmd("%s rev-list git-annex" % (ud.basecmd), d, quiet=True, workdir=wd)
runfetchcmd("%s rev-list git-annex" % (ud.basecmd), d, quiet=True)
return True
except bb.fetch.FetchError:
pass
return False
def update_annex(self, ud, d, wd):
def update_annex(self, ud, d):
try:
runfetchcmd("%s annex get --all" % (ud.basecmd), d, quiet=True, workdir=wd)
runfetchcmd("%s annex get --all" % (ud.basecmd), d, quiet=True)
except bb.fetch.FetchError:
return False
runfetchcmd("chmod u+w -R %s/annex" % (ud.clonedir), d, quiet=True, workdir=wd)
runfetchcmd("chmod u+w -R %s/annex" % (ud.clonedir), d, quiet=True)
return True
def download(self, ud, d):
Git.download(self, ud, d)
if not ud.shallow or ud.localpath != ud.fullshallow:
if self.uses_annex(ud, d, ud.clonedir):
self.update_annex(ud, d, ud.clonedir)
def clone_shallow_local(self, ud, dest, d):
super(GitANNEX, self).clone_shallow_local(ud, dest, d)
try:
runfetchcmd("%s annex init" % ud.basecmd, d, workdir=dest)
except bb.fetch.FetchError:
pass
if self.uses_annex(ud, d, dest):
runfetchcmd("%s annex get" % ud.basecmd, d, workdir=dest)
runfetchcmd("chmod u+w -R %s/.git/annex" % (dest), d, quiet=True, workdir=dest)
os.chdir(ud.clonedir)
annex = self.uses_annex(ud, d)
if annex:
self.update_annex(ud, d)
def unpack(self, ud, destdir, d):
Git.unpack(self, ud, destdir, d)
os.chdir(ud.destdir)
try:
runfetchcmd("%s annex init" % (ud.basecmd), d, workdir=ud.destdir)
runfetchcmd("%s annex sync" % (ud.basecmd), d)
except bb.fetch.FetchError:
pass
annex = self.uses_annex(ud, d, ud.destdir)
annex = self.uses_annex(ud, d)
if annex:
runfetchcmd("%s annex get" % (ud.basecmd), d, workdir=ud.destdir)
runfetchcmd("chmod u+w -R %s/.git/annex" % (ud.destdir), d, quiet=True, workdir=ud.destdir)
runfetchcmd("%s annex get" % (ud.basecmd), d)
runfetchcmd("chmod u+w -R %s/.git/annex" % (ud.destdir), d, quiet=True)

View File

@@ -31,6 +31,7 @@ NOTE: Switching a SRC_URI from "git://" to "gitsm://" requires a clean of your r
import os
import bb
from bb import data
from bb.fetch2.git import Git
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
@@ -42,10 +43,10 @@ class GitSM(Git):
"""
return ud.type in ['gitsm']
def uses_submodules(self, ud, d, wd):
def uses_submodules(self, ud, d):
for name in ud.names:
try:
runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revisions[name]), d, quiet=True, workdir=wd)
runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revisions[name]), d, quiet=True)
return True
except bb.fetch.FetchError:
pass
@@ -106,30 +107,30 @@ class GitSM(Git):
os.mkdir(tmpclonedir)
os.rename(ud.clonedir, gitdir)
runfetchcmd("sed " + gitdir + "/config -i -e 's/bare.*=.*true/bare = false/'", d)
runfetchcmd(ud.basecmd + " reset --hard", d, workdir=tmpclonedir)
runfetchcmd(ud.basecmd + " checkout -f " + ud.revisions[ud.names[0]], d, workdir=tmpclonedir)
runfetchcmd(ud.basecmd + " submodule update --init --recursive", d, workdir=tmpclonedir)
os.chdir(tmpclonedir)
runfetchcmd(ud.basecmd + " reset --hard", d)
runfetchcmd(ud.basecmd + " submodule init", d)
runfetchcmd(ud.basecmd + " submodule update", d)
self._set_relative_paths(tmpclonedir)
runfetchcmd("sed " + gitdir + "/config -i -e 's/bare.*=.*false/bare = true/'", d, workdir=tmpclonedir)
runfetchcmd("sed " + gitdir + "/config -i -e 's/bare.*=.*false/bare = true/'", d)
os.rename(gitdir, ud.clonedir,)
bb.utils.remove(tmpclonedir, True)
def download(self, ud, d):
Git.download(self, ud, d)
if not ud.shallow or ud.localpath != ud.fullshallow:
submodules = self.uses_submodules(ud, d, ud.clonedir)
if submodules:
self.update_submodules(ud, d)
def clone_shallow_local(self, ud, dest, d):
super(GitSM, self).clone_shallow_local(ud, dest, d)
runfetchcmd('cp -fpPRH "%s/modules" "%s/"' % (ud.clonedir, os.path.join(dest, '.git')), d)
os.chdir(ud.clonedir)
submodules = self.uses_submodules(ud, d)
if submodules:
self.update_submodules(ud, d)
def unpack(self, ud, destdir, d):
Git.unpack(self, ud, destdir, d)
os.chdir(ud.destdir)
submodules = self.uses_submodules(ud, d)
if submodules:
runfetchcmd("cp -r " + ud.clonedir + "/modules " + ud.destdir + "/.git/", d)
runfetchcmd(ud.basecmd + " submodule init", d)
runfetchcmd(ud.basecmd + " submodule update", d)
if self.uses_submodules(ud, d, ud.destdir):
runfetchcmd(ud.basecmd + " checkout " + ud.revisions[ud.names[0]], d, workdir=ud.destdir)
runfetchcmd(ud.basecmd + " submodule update --init --recursive", d, workdir=ud.destdir)

View File

@@ -28,7 +28,7 @@ import os
import sys
import logging
import bb
import errno
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import MissingParameterError
@@ -43,13 +43,6 @@ class Hg(FetchMethod):
"""
return ud.type in ['hg']
def supports_checksum(self, urldata):
"""
Don't require checksums for local archives created from
repository checkouts.
"""
return False
def urldata_init(self, ud, d):
"""
init hg specific variable within url data
@@ -59,34 +52,19 @@ class Hg(FetchMethod):
ud.module = ud.parm["module"]
if 'protocol' in ud.parm:
ud.proto = ud.parm['protocol']
elif not ud.host:
ud.proto = 'file'
else:
ud.proto = "hg"
# Create paths to mercurial checkouts
relpath = self._strip_leading_slashes(ud.path)
ud.pkgdir = os.path.join(data.expand('${HGDIR}', d), ud.host, relpath)
ud.moddir = os.path.join(ud.pkgdir, ud.module)
ud.setup_revisions(d)
ud.setup_revisons(d)
if 'rev' in ud.parm:
ud.revision = ud.parm['rev']
elif not ud.revision:
ud.revision = self.latest_revision(ud, d)
# Create paths to mercurial checkouts
hgsrcname = '%s_%s_%s' % (ud.module.replace('/', '.'), \
ud.host, ud.path.replace('/', '.'))
mirrortarball = 'hg_%s.tar.gz' % hgsrcname
ud.fullmirror = os.path.join(d.getVar("DL_DIR"), mirrortarball)
ud.mirrortarballs = [mirrortarball]
hgdir = d.getVar("HGDIR") or (d.getVar("DL_DIR") + "/hg/")
ud.pkgdir = os.path.join(hgdir, hgsrcname)
ud.moddir = os.path.join(ud.pkgdir, ud.module)
ud.localfile = ud.moddir
ud.basecmd = d.getVar("FETCHCMD_hg") or "/usr/bin/env hg"
ud.write_tarballs = d.getVar("BB_GENERATE_MIRROR_TARBALLS")
ud.localfile = data.expand('%s_%s_%s_%s.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.path.replace('/', '.'), ud.revision), d)
def need_update(self, ud, d):
revTag = ud.parm.get('rev', 'tip')
@@ -96,21 +74,14 @@ class Hg(FetchMethod):
return True
return False
def try_premirror(self, ud, d):
# If we don't do this, updating an existing checkout with only premirrors
# is not possible
if d.getVar("BB_FETCH_PREMIRRORONLY") is not None:
return True
if os.path.exists(ud.moddir):
return False
return True
def _buildhgcommand(self, ud, d, command):
"""
Build up an hg commandline based on ud
command is "fetch", "update", "info"
"""
basecmd = data.expand('${FETCHCMD_hg}', d)
proto = ud.parm.get('protocol', 'http')
host = ud.host
@@ -127,7 +98,7 @@ class Hg(FetchMethod):
hgroot = ud.user + "@" + host + ud.path
if command == "info":
return "%s identify -i %s://%s/%s" % (ud.basecmd, proto, hgroot, ud.module)
return "%s identify -i %s://%s/%s" % (basecmd, proto, hgroot, ud.module)
options = [];
@@ -140,22 +111,22 @@ class Hg(FetchMethod):
if command == "fetch":
if ud.user and ud.pswd:
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" clone %s %s://%s/%s %s" % (ud.basecmd, ud.user, ud.pswd, proto, " ".join(options), proto, hgroot, ud.module, ud.module)
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" clone %s %s://%s/%s %s" % (basecmd, ud.user, ud.pswd, proto, " ".join(options), proto, hgroot, ud.module, ud.module)
else:
cmd = "%s clone %s %s://%s/%s %s" % (ud.basecmd, " ".join(options), proto, hgroot, ud.module, ud.module)
cmd = "%s clone %s %s://%s/%s %s" % (basecmd, " ".join(options), proto, hgroot, ud.module, ud.module)
elif command == "pull":
# do not pass options list; limiting pull to rev causes the local
# repo not to contain it and immediately following "update" command
# will crash
if ud.user and ud.pswd:
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull" % (ud.basecmd, ud.user, ud.pswd, proto)
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull" % (basecmd, ud.user, ud.pswd, proto)
else:
cmd = "%s pull" % (ud.basecmd)
cmd = "%s pull" % (basecmd)
elif command == "update":
if ud.user and ud.pswd:
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" update -C %s" % (ud.basecmd, ud.user, ud.pswd, proto, " ".join(options))
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" update -C %s" % (basecmd, ud.user, ud.pswd, proto, " ".join(options))
else:
cmd = "%s update -C %s" % (ud.basecmd, " ".join(options))
cmd = "%s update -C %s" % (basecmd, " ".join(options))
else:
raise FetchError("Invalid hg command %s" % command, ud.url)
@@ -166,53 +137,40 @@ class Hg(FetchMethod):
logger.debug(2, "Fetch: checking for module directory '" + ud.moddir + "'")
# If the checkout doesn't exist and the mirror tarball does, extract it
if not os.path.exists(ud.pkgdir) and os.path.exists(ud.fullmirror):
bb.utils.mkdirhier(ud.pkgdir)
runfetchcmd("tar -xzf %s" % (ud.fullmirror), d, workdir=ud.pkgdir)
if os.access(os.path.join(ud.moddir, '.hg'), os.R_OK):
# Found the source, check whether need pull
updatecmd = self._buildhgcommand(ud, d, "update")
updatecmd = self._buildhgcommand(ud, d, "pull")
logger.info("Update " + ud.url)
# update sources there
os.chdir(ud.moddir)
logger.debug(1, "Running %s", updatecmd)
try:
runfetchcmd(updatecmd, d, workdir=ud.moddir)
except bb.fetch2.FetchError:
# Runnning pull in the repo
pullcmd = self._buildhgcommand(ud, d, "pull")
logger.info("Pulling " + ud.url)
# update sources there
logger.debug(1, "Running %s", pullcmd)
bb.fetch2.check_network_access(d, pullcmd, ud.url)
runfetchcmd(pullcmd, d, workdir=ud.moddir)
try:
os.unlink(ud.fullmirror)
except OSError as exc:
if exc.errno != errno.ENOENT:
raise
bb.fetch2.check_network_access(d, updatecmd, ud.url)
runfetchcmd(updatecmd, d)
# No source found, clone it.
if not os.path.exists(ud.moddir):
else:
fetchcmd = self._buildhgcommand(ud, d, "fetch")
logger.info("Fetch " + ud.url)
# check out sources there
bb.utils.mkdirhier(ud.pkgdir)
os.chdir(ud.pkgdir)
logger.debug(1, "Running %s", fetchcmd)
bb.fetch2.check_network_access(d, fetchcmd, ud.url)
runfetchcmd(fetchcmd, d, workdir=ud.pkgdir)
runfetchcmd(fetchcmd, d)
# Even when we clone (fetch), we still need to update as hg's clone
# won't checkout the specified revision if its on a branch
updatecmd = self._buildhgcommand(ud, d, "update")
os.chdir(ud.moddir)
logger.debug(1, "Running %s", updatecmd)
runfetchcmd(updatecmd, d, workdir=ud.moddir)
runfetchcmd(updatecmd, d)
def clean(self, ud, d):
""" Clean the hg dir """
scmdata = ud.parm.get("scmdata", "")
if scmdata == "keep":
tar_flags = ""
else:
tar_flags = "--exclude '.hg' --exclude '.hgrags'"
bb.utils.remove(ud.localpath, True)
bb.utils.remove(ud.fullmirror)
bb.utils.remove(ud.fullmirror + ".done")
os.chdir(ud.pkgdir)
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.module), d, cleanup = [ud.localpath])
def supports_srcrev(self):
return True
@@ -221,7 +179,7 @@ class Hg(FetchMethod):
"""
Compute tip revision for the url
"""
bb.fetch2.check_network_access(d, self._buildhgcommand(ud, d, "info"), ud.url)
bb.fetch2.check_network_access(d, self._buildhgcommand(ud, d, "info"))
output = runfetchcmd(self._buildhgcommand(ud, d, "info"), d)
return output.strip()
@@ -233,38 +191,3 @@ class Hg(FetchMethod):
Return a unique key for the url
"""
return "hg:" + ud.moddir
def build_mirror_data(self, ud, d):
# Generate a mirror tarball if needed
if ud.write_tarballs == "1" and not os.path.exists(ud.fullmirror):
# it's possible that this symlink points to read-only filesystem with PREMIRROR
if os.path.islink(ud.fullmirror):
os.unlink(ud.fullmirror)
logger.info("Creating tarball of hg repository")
runfetchcmd("tar -czf %s %s" % (ud.fullmirror, ud.module), d, workdir=ud.pkgdir)
runfetchcmd("touch %s.done" % (ud.fullmirror), d, workdir=ud.pkgdir)
def localpath(self, ud, d):
return ud.pkgdir
def unpack(self, ud, destdir, d):
"""
Make a local clone or export for the url
"""
revflag = "-r %s" % ud.revision
subdir = ud.parm.get("destsuffix", ud.module)
codir = "%s/%s" % (destdir, subdir)
scmdata = ud.parm.get("scmdata", "")
if scmdata != "nokeep":
if not os.access(os.path.join(codir, '.hg'), os.R_OK):
logger.debug(2, "Unpack: creating new hg repository in '" + codir + "'")
runfetchcmd("%s init %s" % (ud.basecmd, codir), d)
logger.debug(2, "Unpack: updating source in '" + codir + "'")
runfetchcmd("%s pull %s" % (ud.basecmd, ud.moddir), d, workdir=codir)
runfetchcmd("%s up -C %s" % (ud.basecmd, revflag), d, workdir=codir)
else:
logger.debug(2, "Unpack: extracting source to '" + codir + "'")
runfetchcmd("%s archive -t files %s %s" % (ud.basecmd, revflag, codir), d, workdir=ud.moddir)

View File

@@ -26,9 +26,10 @@ BitBake build tools.
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
import os
import urllib.request, urllib.parse, urllib.error
import urllib
import bb
import bb.utils
from bb import data
from bb.fetch2 import FetchMethod, FetchError
from bb.fetch2 import logger
@@ -41,10 +42,9 @@ class Local(FetchMethod):
def urldata_init(self, ud, d):
# We don't set localfile as for this fetcher the file is already local!
ud.decodedurl = urllib.parse.unquote(ud.url.split("://")[1].split(";")[0])
ud.decodedurl = urllib.unquote(ud.url.split("://")[1].split(";")[0])
ud.basename = os.path.basename(ud.decodedurl)
ud.basepath = ud.decodedurl
ud.needdonestamp = False
return
def localpath(self, urldata, d):
@@ -62,11 +62,17 @@ class Local(FetchMethod):
newpath = path
if path[0] == "/":
return [path]
filespath = d.getVar('FILESPATH')
filespath = data.getVar('FILESPATH', d, True)
if filespath:
logger.debug(2, "Searching for %s in paths:\n %s" % (path, "\n ".join(filespath.split(":"))))
newpath, hist = bb.utils.which(filespath, path, history=True)
searched.extend(hist)
if not newpath:
filesdir = data.getVar('FILESDIR', d, True)
if filesdir:
logger.debug(2, "Searching for %s in path: %s" % (path, filesdir))
newpath = os.path.join(filesdir, path)
searched.append(newpath)
if (not newpath or not os.path.exists(newpath)) and path.find("*") != -1:
# For expressions using '*', best we can do is take the first directory in FILESPATH that exists
newpath, hist = bb.utils.which(filespath, ".", history=True)
@@ -74,7 +80,7 @@ class Local(FetchMethod):
logger.debug(2, "Searching for %s in path: %s" % (path, newpath))
return searched
if not os.path.exists(newpath):
dldirfile = os.path.join(d.getVar("DL_DIR"), path)
dldirfile = os.path.join(d.getVar("DL_DIR", True), path)
logger.debug(2, "Defaulting to %s for %s" % (dldirfile, path))
bb.utils.mkdirhier(os.path.dirname(dldirfile))
searched.append(dldirfile)
@@ -93,17 +99,20 @@ class Local(FetchMethod):
# no need to fetch local files, we'll deal with them in place.
if self.supports_checksum(urldata) and not os.path.exists(urldata.localpath):
locations = []
filespath = d.getVar('FILESPATH')
filespath = data.getVar('FILESPATH', d, True)
if filespath:
locations = filespath.split(":")
locations.append(d.getVar("DL_DIR"))
filesdir = data.getVar('FILESDIR', d, True)
if filesdir:
locations.append(filesdir)
locations.append(d.getVar("DL_DIR", True))
msg = "Unable to find file " + urldata.url + " anywhere. The paths that were searched were:\n " + "\n ".join(locations)
raise FetchError(msg)
return True
def checkstatus(self, fetch, urldata, d):
def checkstatus(self, urldata, d):
"""
Check the status of the url
"""

View File

@@ -1,308 +0,0 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' NPM implementation
The NPM fetcher is used to retrieve files from the npmjs repository
Usage in the recipe:
SRC_URI = "npm://registry.npmjs.org/;name=${PN};version=${PV}"
Suported SRC_URI options are:
- name
- version
npm://registry.npmjs.org/${PN}/-/${PN}-${PV}.tgz would become npm://registry.npmjs.org;name=${PN};version=${PV}
The fetcher all triggers off the existence of ud.localpath. If that exists and has the ".done" stamp, its assumed the fetch is good/done
"""
import os
import sys
import urllib.request, urllib.parse, urllib.error
import json
import subprocess
import signal
import bb
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import ChecksumError
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
from bb.fetch2 import UnpackError
from bb.fetch2 import ParameterError
def subprocess_setup():
# Python installs a SIGPIPE handler by default. This is usually not what
# non-Python subprocesses expect.
# SIGPIPE errors are known issues with gzip/bash
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
class Npm(FetchMethod):
"""Class to fetch urls via 'npm'"""
def init(self, d):
pass
def supports(self, ud, d):
"""
Check to see if a given url can be fetched with npm
"""
return ud.type in ['npm']
def debug(self, msg):
logger.debug(1, "NpmFetch: %s", msg)
def clean(self, ud, d):
logger.debug(2, "Calling cleanup %s" % ud.pkgname)
bb.utils.remove(ud.localpath, False)
bb.utils.remove(ud.pkgdatadir, True)
bb.utils.remove(ud.fullmirror, False)
def urldata_init(self, ud, d):
"""
init NPM specific variable within url data
"""
if 'downloadfilename' in ud.parm:
ud.basename = ud.parm['downloadfilename']
else:
ud.basename = os.path.basename(ud.path)
# can't call it ud.name otherwise fetcher base class will start doing sha1stuff
# TODO: find a way to get an sha1/sha256 manifest of pkg & all deps
ud.pkgname = ud.parm.get("name", None)
if not ud.pkgname:
raise ParameterError("NPM fetcher requires a name parameter", ud.url)
ud.version = ud.parm.get("version", None)
if not ud.version:
raise ParameterError("NPM fetcher requires a version parameter", ud.url)
ud.bbnpmmanifest = "%s-%s.deps.json" % (ud.pkgname, ud.version)
ud.bbnpmmanifest = ud.bbnpmmanifest.replace('/', '-')
ud.registry = "http://%s" % (ud.url.replace('npm://', '', 1).split(';'))[0]
prefixdir = "npm/%s" % ud.pkgname
ud.pkgdatadir = d.expand("${DL_DIR}/%s" % prefixdir)
if not os.path.exists(ud.pkgdatadir):
bb.utils.mkdirhier(ud.pkgdatadir)
ud.localpath = d.expand("${DL_DIR}/npm/%s" % ud.bbnpmmanifest)
self.basecmd = d.getVar("FETCHCMD_wget") or "/usr/bin/env wget -O -t 2 -T 30 -nv --passive-ftp --no-check-certificate "
ud.prefixdir = prefixdir
ud.write_tarballs = ((d.getVar("BB_GENERATE_MIRROR_TARBALLS") or "0") != "0")
mirrortarball = 'npm_%s-%s.tar.xz' % (ud.pkgname, ud.version)
mirrortarball = mirrortarball.replace('/', '-')
ud.fullmirror = os.path.join(d.getVar("DL_DIR"), mirrortarball)
ud.mirrortarballs = [mirrortarball]
def need_update(self, ud, d):
if os.path.exists(ud.localpath):
return False
return True
def _runwget(self, ud, d, command, quiet):
logger.debug(2, "Fetching %s using command '%s'" % (ud.url, command))
bb.fetch2.check_network_access(d, command, ud.url)
dldir = d.getVar("DL_DIR")
runfetchcmd(command, d, quiet, workdir=dldir)
def _unpackdep(self, ud, pkg, data, destdir, dldir, d):
file = data[pkg]['tgz']
logger.debug(2, "file to extract is %s" % file)
if file.endswith('.tgz') or file.endswith('.tar.gz') or file.endswith('.tar.Z'):
cmd = 'tar xz --strip 1 --no-same-owner --warning=no-unknown-keyword -f %s/%s' % (dldir, file)
else:
bb.fatal("NPM package %s downloaded not a tarball!" % file)
# Change to subdir before executing command
if not os.path.exists(destdir):
os.makedirs(destdir)
path = d.getVar('PATH')
if path:
cmd = "PATH=\"%s\" %s" % (path, cmd)
bb.note("Unpacking %s to %s/" % (file, destdir))
ret = subprocess.call(cmd, preexec_fn=subprocess_setup, shell=True, cwd=destdir)
if ret != 0:
raise UnpackError("Unpack command %s failed with return value %s" % (cmd, ret), ud.url)
if 'deps' not in data[pkg]:
return
for dep in data[pkg]['deps']:
self._unpackdep(ud, dep, data[pkg]['deps'], "%s/node_modules/%s" % (destdir, dep), dldir, d)
def unpack(self, ud, destdir, d):
dldir = d.getVar("DL_DIR")
with open("%s/npm/%s" % (dldir, ud.bbnpmmanifest)) as datafile:
workobj = json.load(datafile)
dldir = "%s/%s" % (os.path.dirname(ud.localpath), ud.pkgname)
if 'subdir' in ud.parm:
unpackdir = '%s/%s' % (destdir, ud.parm.get('subdir'))
else:
unpackdir = '%s/npmpkg' % destdir
self._unpackdep(ud, ud.pkgname, workobj, unpackdir, dldir, d)
def _parse_view(self, output):
'''
Parse the output of npm view --json; the last JSON result
is assumed to be the one that we're interested in.
'''
pdata = None
outdeps = {}
datalines = []
bracelevel = 0
for line in output.splitlines():
if bracelevel:
datalines.append(line)
elif '{' in line:
datalines = []
datalines.append(line)
bracelevel = bracelevel + line.count('{') - line.count('}')
if datalines:
pdata = json.loads('\n'.join(datalines))
return pdata
def _getdependencies(self, pkg, data, version, d, ud, optional=False, fetchedlist=None):
if fetchedlist is None:
fetchedlist = []
pkgfullname = pkg
if version != '*' and not '/' in version:
pkgfullname += "@'%s'" % version
logger.debug(2, "Calling getdeps on %s" % pkg)
fetchcmd = "npm view %s --json --registry %s" % (pkgfullname, ud.registry)
output = runfetchcmd(fetchcmd, d, True)
pdata = self._parse_view(output)
if not pdata:
raise FetchError("The command '%s' returned no output" % fetchcmd)
if optional:
pkg_os = pdata.get('os', None)
if pkg_os:
if not isinstance(pkg_os, list):
pkg_os = [pkg_os]
blacklist = False
for item in pkg_os:
if item.startswith('!'):
blacklist = True
break
if (not blacklist and 'linux' not in pkg_os) or '!linux' in pkg_os:
logger.debug(2, "Skipping %s since it's incompatible with Linux" % pkg)
return
#logger.debug(2, "Output URL is %s - %s - %s" % (ud.basepath, ud.basename, ud.localfile))
outputurl = pdata['dist']['tarball']
data[pkg] = {}
data[pkg]['tgz'] = os.path.basename(outputurl)
if outputurl in fetchedlist:
return
self._runwget(ud, d, "%s --directory-prefix=%s %s" % (self.basecmd, ud.prefixdir, outputurl), False)
fetchedlist.append(outputurl)
dependencies = pdata.get('dependencies', {})
optionalDependencies = pdata.get('optionalDependencies', {})
dependencies.update(optionalDependencies)
depsfound = {}
optdepsfound = {}
data[pkg]['deps'] = {}
for dep in dependencies:
if dep in optionalDependencies:
optdepsfound[dep] = dependencies[dep]
else:
depsfound[dep] = dependencies[dep]
for dep, version in optdepsfound.items():
self._getdependencies(dep, data[pkg]['deps'], version, d, ud, optional=True, fetchedlist=fetchedlist)
for dep, version in depsfound.items():
self._getdependencies(dep, data[pkg]['deps'], version, d, ud, fetchedlist=fetchedlist)
def _getshrinkeddependencies(self, pkg, data, version, d, ud, lockdown, manifest, toplevel=True):
logger.debug(2, "NPM shrinkwrap file is %s" % data)
if toplevel:
name = data.get('name', None)
if name and name != pkg:
for obj in data.get('dependencies', []):
if obj == pkg:
self._getshrinkeddependencies(obj, data['dependencies'][obj], data['dependencies'][obj]['version'], d, ud, lockdown, manifest, False)
return
outputurl = "invalid"
if ('resolved' not in data) or (not data['resolved'].startswith('http')):
# will be the case for ${PN}
fetchcmd = "npm view %s@%s dist.tarball --registry %s" % (pkg, version, ud.registry)
logger.debug(2, "Found this matching URL: %s" % str(fetchcmd))
outputurl = runfetchcmd(fetchcmd, d, True)
else:
outputurl = data['resolved']
self._runwget(ud, d, "%s --directory-prefix=%s %s" % (self.basecmd, ud.prefixdir, outputurl), False)
manifest[pkg] = {}
manifest[pkg]['tgz'] = os.path.basename(outputurl).rstrip()
manifest[pkg]['deps'] = {}
if pkg in lockdown:
sha1_expected = lockdown[pkg][version]
sha1_data = bb.utils.sha1_file("npm/%s/%s" % (ud.pkgname, manifest[pkg]['tgz']))
if sha1_expected != sha1_data:
msg = "\nFile: '%s' has %s checksum %s when %s was expected" % (manifest[pkg]['tgz'], 'sha1', sha1_data, sha1_expected)
raise ChecksumError('Checksum mismatch!%s' % msg)
else:
logger.debug(2, "No lockdown data for %s@%s" % (pkg, version))
if 'dependencies' in data:
for obj in data['dependencies']:
logger.debug(2, "Found dep is %s" % str(obj))
self._getshrinkeddependencies(obj, data['dependencies'][obj], data['dependencies'][obj]['version'], d, ud, lockdown, manifest[pkg]['deps'], False)
def download(self, ud, d):
"""Fetch url"""
jsondepobj = {}
shrinkobj = {}
lockdown = {}
if not os.listdir(ud.pkgdatadir) and os.path.exists(ud.fullmirror):
dest = d.getVar("DL_DIR")
bb.utils.mkdirhier(dest)
runfetchcmd("tar -xJf %s" % (ud.fullmirror), d, workdir=dest)
return
if ud.parm.get("noverify", None) != '1':
shwrf = d.getVar('NPM_SHRINKWRAP')
logger.debug(2, "NPM shrinkwrap file is %s" % shwrf)
if shwrf:
try:
with open(shwrf) as datafile:
shrinkobj = json.load(datafile)
except Exception as e:
raise FetchError('Error loading NPM_SHRINKWRAP file "%s" for %s: %s' % (shwrf, ud.pkgname, str(e)))
elif not ud.ignore_checksums:
logger.warning('Missing shrinkwrap file in NPM_SHRINKWRAP for %s, this will lead to unreliable builds!' % ud.pkgname)
lckdf = d.getVar('NPM_LOCKDOWN')
logger.debug(2, "NPM lockdown file is %s" % lckdf)
if lckdf:
try:
with open(lckdf) as datafile:
lockdown = json.load(datafile)
except Exception as e:
raise FetchError('Error loading NPM_LOCKDOWN file "%s" for %s: %s' % (lckdf, ud.pkgname, str(e)))
elif not ud.ignore_checksums:
logger.warning('Missing lockdown file in NPM_LOCKDOWN for %s, this will lead to unreproducible builds!' % ud.pkgname)
if ('name' not in shrinkobj):
self._getdependencies(ud.pkgname, jsondepobj, ud.version, d, ud)
else:
self._getshrinkeddependencies(ud.pkgname, shrinkobj, ud.version, d, ud, lockdown, jsondepobj)
with open(ud.localpath, 'w') as outfile:
json.dump(jsondepobj, outfile)
def build_mirror_data(self, ud, d):
# Generate a mirror tarball if needed
if ud.write_tarballs and not os.path.exists(ud.fullmirror):
# it's possible that this symlink points to read-only filesystem with PREMIRROR
if os.path.islink(ud.fullmirror):
os.unlink(ud.fullmirror)
dldir = d.getVar("DL_DIR")
logger.info("Creating tarball of npm data")
runfetchcmd("tar -cJf %s npm/%s npm/%s" % (ud.fullmirror, ud.bbnpmmanifest, ud.pkgname), d,
workdir=dldir)
runfetchcmd("touch %s.done" % (ud.fullmirror), d, workdir=dldir)

View File

@@ -10,6 +10,7 @@ import os
import sys
import logging
import bb
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import MissingParameterError
@@ -33,20 +34,20 @@ class Osc(FetchMethod):
# Create paths to osc checkouts
relpath = self._strip_leading_slashes(ud.path)
ud.pkgdir = os.path.join(d.getVar('OSCDIR'), ud.host)
ud.pkgdir = os.path.join(data.expand('${OSCDIR}', d), ud.host)
ud.moddir = os.path.join(ud.pkgdir, relpath, ud.module)
if 'rev' in ud.parm:
ud.revision = ud.parm['rev']
else:
pv = d.getVar("PV", False)
pv = data.getVar("PV", d, 0)
rev = bb.fetch2.srcrev_internal_helper(ud, d)
if rev and rev != True:
ud.revision = rev
else:
ud.revision = ""
ud.localfile = d.expand('%s_%s_%s.tar.gz' % (ud.module.replace('/', '.'), ud.path.replace('/', '.'), ud.revision))
ud.localfile = data.expand('%s_%s_%s.tar.gz' % (ud.module.replace('/', '.'), ud.path.replace('/', '.'), ud.revision), d)
def _buildosccommand(self, ud, d, command):
"""
@@ -54,7 +55,7 @@ class Osc(FetchMethod):
command is "fetch", "update", "info"
"""
basecmd = d.expand('${FETCHCMD_osc}')
basecmd = data.expand('${FETCHCMD_osc}', d)
proto = ud.parm.get('protocol', 'ocs')
@@ -83,25 +84,27 @@ class Osc(FetchMethod):
logger.debug(2, "Fetch: checking for module directory '" + ud.moddir + "'")
if os.access(os.path.join(d.getVar('OSCDIR'), ud.path, ud.module), os.R_OK):
if os.access(os.path.join(data.expand('${OSCDIR}', d), ud.path, ud.module), os.R_OK):
oscupdatecmd = self._buildosccommand(ud, d, "update")
logger.info("Update "+ ud.url)
# update sources there
os.chdir(ud.moddir)
logger.debug(1, "Running %s", oscupdatecmd)
bb.fetch2.check_network_access(d, oscupdatecmd, ud.url)
runfetchcmd(oscupdatecmd, d, workdir=ud.moddir)
runfetchcmd(oscupdatecmd, d)
else:
oscfetchcmd = self._buildosccommand(ud, d, "fetch")
logger.info("Fetch " + ud.url)
# check out sources there
bb.utils.mkdirhier(ud.pkgdir)
os.chdir(ud.pkgdir)
logger.debug(1, "Running %s", oscfetchcmd)
bb.fetch2.check_network_access(d, oscfetchcmd, ud.url)
runfetchcmd(oscfetchcmd, d, workdir=ud.pkgdir)
runfetchcmd(oscfetchcmd, d)
os.chdir(os.path.join(ud.pkgdir + ud.path))
# tar them up to a defined filename
runfetchcmd("tar -czf %s %s" % (ud.localpath, ud.module), d,
cleanup=[ud.localpath], workdir=os.path.join(ud.pkgdir + ud.path))
runfetchcmd("tar -czf %s %s" % (ud.localpath, ud.module), d, cleanup = [ud.localpath])
def supports_srcrev(self):
return False
@@ -111,7 +114,7 @@ class Osc(FetchMethod):
Generate a .oscrc to be used for this run.
"""
config_path = os.path.join(d.getVar('OSCDIR'), "oscrc")
config_path = os.path.join(data.expand('${OSCDIR}', d), "oscrc")
if (os.path.exists(config_path)):
os.remove(config_path)
@@ -120,8 +123,8 @@ class Osc(FetchMethod):
f.write("apisrv = %s\n" % ud.host)
f.write("scheme = http\n")
f.write("su-wrapper = su -c\n")
f.write("build-root = %s\n" % d.getVar('WORKDIR'))
f.write("urllist = %s\n" % d.getVar("OSCURLLIST"))
f.write("build-root = %s\n" % data.expand('${WORKDIR}', d))
f.write("urllist = http://moblin-obs.jf.intel.com:8888/build/%(project)s/%(repository)s/%(buildarch)s/:full/%(name)s.rpm\n")
f.write("extra-pkgs = gzip\n")
f.write("\n")
f.write("[%s]\n" % ud.host)

View File

@@ -1,12 +1,14 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for perforce
BitBake 'Fetch' implementations
Classes for obtaining upstream sources for the
BitBake build tools.
"""
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2016 Kodak Alaris, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -23,187 +25,163 @@ BitBake 'Fetch' implementation for perforce
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
from future_builtins import zip
import os
import subprocess
import logging
import bb
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import logger
from bb.fetch2 import runfetchcmd
class Perforce(FetchMethod):
""" Class to fetch from perforce repositories """
def supports(self, ud, d):
""" Check to see if a given url can be fetched with perforce. """
return ud.type in ['p4']
def urldata_init(self, ud, d):
"""
Initialize perforce specific variables within url data. If P4CONFIG is
provided by the env, use it. If P4PORT is specified by the recipe, use
its values, which may override the settings in P4CONFIG.
"""
ud.basecmd = d.getVar('FETCHCMD_p4')
if not ud.basecmd:
ud.basecmd = "/usr/bin/env p4"
ud.dldir = d.getVar('P4DIR')
if not ud.dldir:
ud.dldir = '%s/%s' % (d.getVar('DL_DIR'), 'p4')
path = ud.url.split('://')[1]
path = path.split(';')[0]
delim = path.find('@');
def doparse(url, d):
parm = {}
path = url.split("://")[1]
delim = path.find("@");
if delim != -1:
(ud.user, ud.pswd) = path.split('@')[0].split(':')
ud.path = path.split('@')[1]
(user, pswd, host, port) = path.split('@')[0].split(":")
path = path.split('@')[1]
else:
ud.path = path
(host, port) = d.getVar('P4PORT').split(':')
user = ""
pswd = ""
ud.usingp4config = False
p4port = d.getVar('P4PORT')
if path.find(";") != -1:
keys=[]
values=[]
plist = path.split(';')
for item in plist:
if item.count('='):
(key, value) = item.split('=')
keys.append(key)
values.append(value)
if p4port:
logger.debug(1, 'Using recipe provided P4PORT: %s' % p4port)
ud.host = p4port
else:
logger.debug(1, 'Trying to use P4CONFIG to automatically set P4PORT...')
ud.usingp4config = True
p4cmd = '%s info | grep "Server address"' % ud.basecmd
bb.fetch2.check_network_access(d, p4cmd, ud.url)
ud.host = runfetchcmd(p4cmd, d, True)
ud.host = ud.host.split(': ')[1].strip()
logger.debug(1, 'Determined P4PORT to be: %s' % ud.host)
if not ud.host:
raise FetchError('Could not determine P4PORT from P4CONFIG')
if ud.path.find('/...') >= 0:
ud.pathisdir = True
else:
ud.pathisdir = False
parm = dict(zip(keys, values))
path = "//" + path.split(';')[0]
host += ":%s" % (port)
parm["cset"] = Perforce.getcset(d, path, host, user, pswd, parm)
cleanedpath = ud.path.replace('/...', '').replace('/', '.')
cleanedhost = ud.host.replace(':', '.')
ud.pkgdir = os.path.join(ud.dldir, cleanedhost, cleanedpath)
return host, path, user, pswd, parm
doparse = staticmethod(doparse)
ud.setup_revisions(d)
ud.localfile = d.expand('%s_%s_%s.tar.gz' % (cleanedhost, cleanedpath, ud.revision))
def _buildp4command(self, ud, d, command, depot_filename=None):
"""
Build a p4 commandline. Valid commands are "changes", "print", and
"files". depot_filename is the full path to the file in the depot
including the trailing '#rev' value.
"""
def getcset(d, depot, host, user, pswd, parm):
p4opt = ""
if "cset" in parm:
return parm["cset"];
if user:
p4opt += " -u %s" % (user)
if pswd:
p4opt += " -P %s" % (pswd)
if host:
p4opt += " -p %s" % (host)
if ud.user:
p4opt += ' -u "%s"' % (ud.user)
p4date = d.getVar("P4DATE", True)
if "revision" in parm:
depot += "#%s" % (parm["revision"])
elif "label" in parm:
depot += "@%s" % (parm["label"])
elif p4date:
depot += "@%s" % (p4date)
if ud.pswd:
p4opt += ' -P "%s"' % (ud.pswd)
p4cmd = d.getVar('FETCHCMD_p4', True) or "p4"
logger.debug(1, "Running %s%s changes -m 1 %s", p4cmd, p4opt, depot)
p4file, errors = bb.process.run("%s%s changes -m 1 %s" % (p4cmd, p4opt, depot))
cset = p4file.strip()
logger.debug(1, "READ %s", cset)
if not cset:
return -1
if ud.host and not ud.usingp4config:
p4opt += ' -p %s' % (ud.host)
return cset.split(' ')[1]
getcset = staticmethod(getcset)
if hasattr(ud, 'revision') and ud.revision:
pathnrev = '%s@%s' % (ud.path, ud.revision)
def urldata_init(self, ud, d):
(host, path, user, pswd, parm) = Perforce.doparse(ud.url, d)
base_path = path.replace('/...', '')
base_path = self._strip_leading_slashes(base_path)
if "label" in parm:
version = parm["label"]
else:
pathnrev = '%s' % (ud.path)
version = Perforce.getcset(d, path, host, user, pswd, parm)
if depot_filename:
if ud.pathisdir: # Remove leading path to obtain filename
filename = depot_filename[len(ud.path)-1:]
else:
filename = depot_filename[depot_filename.rfind('/'):]
filename = filename[:filename.find('#')] # Remove trailing '#rev'
if command == 'changes':
p4cmd = '%s%s changes -m 1 //%s' % (ud.basecmd, p4opt, pathnrev)
elif command == 'print':
if depot_filename != None:
p4cmd = '%s%s print -o "p4/%s" "%s"' % (ud.basecmd, p4opt, filename, depot_filename)
else:
raise FetchError('No depot file name provided to p4 %s' % command, ud.url)
elif command == 'files':
p4cmd = '%s%s files //%s' % (ud.basecmd, p4opt, pathnrev)
else:
raise FetchError('Invalid p4 command %s' % command, ud.url)
return p4cmd
def _p4listfiles(self, ud, d):
"""
Return a list of the file names which are present in the depot using the
'p4 files' command, including trailing '#rev' file revision indicator
"""
p4cmd = self._buildp4command(ud, d, 'files')
bb.fetch2.check_network_access(d, p4cmd, ud.url)
p4fileslist = runfetchcmd(p4cmd, d, True)
p4fileslist = [f.rstrip() for f in p4fileslist.splitlines()]
if not p4fileslist:
raise FetchError('Unable to fetch listing of p4 files from %s@%s' % (ud.host, ud.path))
count = 0
filelist = []
for filename in p4fileslist:
item = filename.split(' - ')
lastaction = item[1].split()
logger.debug(1, 'File: %s Last Action: %s' % (item[0], lastaction[0]))
if lastaction[0] == 'delete':
continue
filelist.append(item[0])
return filelist
ud.localfile = data.expand('%s+%s+%s.tar.gz' % (host, base_path.replace('/', '.'), version), d)
def download(self, ud, d):
""" Get the list of files, fetch each one """
filelist = self._p4listfiles(ud, d)
if not filelist:
raise FetchError('No files found in depot %s@%s' % (ud.host, ud.path))
"""
Fetch urls
"""
bb.utils.remove(ud.pkgdir, True)
bb.utils.mkdirhier(ud.pkgdir)
(host, depot, user, pswd, parm) = Perforce.doparse(ud.url, d)
for afile in filelist:
p4fetchcmd = self._buildp4command(ud, d, 'print', afile)
bb.fetch2.check_network_access(d, p4fetchcmd, ud.url)
runfetchcmd(p4fetchcmd, d, workdir=ud.pkgdir)
if depot.find('/...') != -1:
path = depot[:depot.find('/...')]
else:
path = depot
runfetchcmd('tar -czf %s p4' % (ud.localpath), d, cleanup=[ud.localpath], workdir=ud.pkgdir)
module = parm.get('module', os.path.basename(path))
def clean(self, ud, d):
""" Cleanup p4 specific files and dirs"""
bb.utils.remove(ud.localpath)
bb.utils.remove(ud.pkgdir, True)
# Get the p4 command
p4opt = ""
if user:
p4opt += " -u %s" % (user)
def supports_srcrev(self):
return True
if pswd:
p4opt += " -P %s" % (pswd)
def _revision_key(self, ud, d, name):
""" Return a unique key for the url """
return 'p4:%s' % ud.pkgdir
if host:
p4opt += " -p %s" % (host)
def _latest_revision(self, ud, d, name):
""" Return the latest upstream scm revision number """
p4cmd = self._buildp4command(ud, d, "changes")
bb.fetch2.check_network_access(d, p4cmd, ud.url)
tip = runfetchcmd(p4cmd, d, True)
p4cmd = d.getVar('FETCHCMD_p4', True) or "p4"
if not tip:
raise FetchError('Could not determine the latest perforce changelist')
# create temp directory
logger.debug(2, "Fetch: creating temporary directory")
bb.utils.mkdirhier(d.expand('${WORKDIR}'))
mktemp = d.getVar("FETCHCMD_p4mktemp", True) or d.expand("mktemp -d -q '${WORKDIR}/oep4.XXXXXX'")
tmpfile, errors = bb.process.run(mktemp)
tmpfile = tmpfile.strip()
if not tmpfile:
raise FetchError("Fetch: unable to create temporary directory.. make sure 'mktemp' is in the PATH.", ud.url)
tipcset = tip.split(' ')[1]
logger.debug(1, 'p4 tip found to be changelist %s' % tipcset)
return tipcset
if "label" in parm:
depot = "%s@%s" % (depot, parm["label"])
else:
cset = Perforce.getcset(d, depot, host, user, pswd, parm)
depot = "%s@%s" % (depot, cset)
def sortable_revision(self, ud, d, name):
""" Return a sortable revision number """
return False, self._build_revision(ud, d)
os.chdir(tmpfile)
logger.info("Fetch " + ud.url)
logger.info("%s%s files %s", p4cmd, p4opt, depot)
p4file, errors = bb.process.run("%s%s files %s" % (p4cmd, p4opt, depot))
p4file = [f.rstrip() for f in p4file.splitlines()]
def _build_revision(self, ud, d):
return ud.revision
if not p4file:
raise FetchError("Fetch: unable to get the P4 files from %s" % depot, ud.url)
count = 0
for file in p4file:
list = file.split()
if list[2] == "delete":
continue
dest = list[0][len(path)+1:]
where = dest.find("#")
subprocess.call("%s%s print -o %s/%s %s" % (p4cmd, p4opt, module, dest[:where], list[0]), shell=True)
count = count + 1
if count == 0:
logger.error()
raise FetchError("Fetch: No files gathered from the P4 fetch", ud.url)
runfetchcmd("tar -czf %s %s" % (ud.localpath, module), d, cleanup = [ud.localpath])
# cleanup
bb.utils.prunedir(tmpfile)

View File

@@ -25,9 +25,9 @@ BitBake "Fetch" repo (git) implementation
import os
import bb
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
class Repo(FetchMethod):
"""Class to fetch a module or modules from repo (git) repositories"""
@@ -51,17 +51,17 @@ class Repo(FetchMethod):
if not ud.manifest.endswith('.xml'):
ud.manifest += '.xml'
ud.localfile = d.expand("repo_%s%s_%s_%s.tar.gz" % (ud.host, ud.path.replace("/", "."), ud.manifest, ud.branch))
ud.localfile = data.expand("repo_%s%s_%s_%s.tar.gz" % (ud.host, ud.path.replace("/", "."), ud.manifest, ud.branch), d)
def download(self, ud, d):
"""Fetch url"""
if os.access(os.path.join(d.getVar("DL_DIR"), ud.localfile), os.R_OK):
if os.access(os.path.join(data.getVar("DL_DIR", d, True), ud.localfile), os.R_OK):
logger.debug(1, "%s already exists (or was stashed). Skipping repo init / sync.", ud.localpath)
return
gitsrcname = "%s%s" % (ud.host, ud.path.replace("/", "."))
repodir = d.getVar("REPODIR") or os.path.join(d.getVar("DL_DIR"), "repo")
repodir = data.getVar("REPODIR", d, True) or os.path.join(data.getVar("DL_DIR", d, True), "repo")
codir = os.path.join(repodir, gitsrcname, ud.manifest)
if ud.user:
@@ -69,23 +69,24 @@ class Repo(FetchMethod):
else:
username = ""
repodir = os.path.join(codir, "repo")
bb.utils.mkdirhier(repodir)
if not os.path.exists(os.path.join(repodir, ".repo")):
bb.utils.mkdirhier(os.path.join(codir, "repo"))
os.chdir(os.path.join(codir, "repo"))
if not os.path.exists(os.path.join(codir, "repo", ".repo")):
bb.fetch2.check_network_access(d, "repo init -m %s -b %s -u %s://%s%s%s" % (ud.manifest, ud.branch, ud.proto, username, ud.host, ud.path), ud.url)
runfetchcmd("repo init -m %s -b %s -u %s://%s%s%s" % (ud.manifest, ud.branch, ud.proto, username, ud.host, ud.path), d, workdir=repodir)
runfetchcmd("repo init -m %s -b %s -u %s://%s%s%s" % (ud.manifest, ud.branch, ud.proto, username, ud.host, ud.path), d)
bb.fetch2.check_network_access(d, "repo sync %s" % ud.url, ud.url)
runfetchcmd("repo sync", d, workdir=repodir)
runfetchcmd("repo sync", d)
os.chdir(codir)
scmdata = ud.parm.get("scmdata", "")
if scmdata == "keep":
tar_flags = ""
else:
tar_flags = "--exclude='.repo' --exclude='.git'"
tar_flags = "--exclude '.repo' --exclude '.git'"
# Create a cache
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.join(".", "*") ), d, workdir=codir)
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, os.path.join(".", "*") ), d)
def supports_srcrev(self):
return False

View File

@@ -1,98 +0,0 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for Amazon AWS S3.
Class for fetching files from Amazon S3 using the AWS Command Line Interface.
The aws tool must be correctly installed and configured prior to use.
"""
# Copyright (C) 2017, Andre McCurdy <armccurdy@gmail.com>
#
# Based in part on bb.fetch2.wget:
# Copyright (C) 2003, 2004 Chris Larson
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
import os
import bb
import urllib.request, urllib.parse, urllib.error
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import runfetchcmd
class S3(FetchMethod):
"""Class to fetch urls via 'aws s3'"""
def supports(self, ud, d):
"""
Check to see if a given url can be fetched with s3.
"""
return ud.type in ['s3']
def recommends_checksum(self, urldata):
return True
def urldata_init(self, ud, d):
if 'downloadfilename' in ud.parm:
ud.basename = ud.parm['downloadfilename']
else:
ud.basename = os.path.basename(ud.path)
ud.localfile = d.expand(urllib.parse.unquote(ud.basename))
ud.basecmd = d.getVar("FETCHCMD_s3") or "/usr/bin/env aws s3"
def download(self, ud, d):
"""
Fetch urls
Assumes localpath was called first
"""
cmd = '%s cp s3://%s%s %s' % (ud.basecmd, ud.host, ud.path, ud.localpath)
bb.fetch2.check_network_access(d, cmd, ud.url)
runfetchcmd(cmd, d)
# Additional sanity checks copied from the wget class (although there
# are no known issues which mean these are required, treat the aws cli
# tool with a little healthy suspicion).
if not os.path.exists(ud.localpath):
raise FetchError("The aws cp command returned success for s3://%s%s but %s doesn't exist?!" % (ud.host, ud.path, ud.localpath))
if os.path.getsize(ud.localpath) == 0:
os.remove(ud.localpath)
raise FetchError("The aws cp command for s3://%s%s resulted in a zero size file?! Deleting and failing since this isn't right." % (ud.host, ud.path))
return True
def checkstatus(self, fetch, ud, d):
"""
Check the status of a URL
"""
cmd = '%s ls s3://%s%s' % (ud.basecmd, ud.host, ud.path)
bb.fetch2.check_network_access(d, cmd, ud.url)
output = runfetchcmd(cmd, d)
# "aws s3 ls s3://mybucket/foo" will exit with success even if the file
# is not found, so check output of the command to confirm success.
if not output:
raise FetchError("The aws ls command for s3://%s%s gave empty output" % (ud.host, ud.path))
return True

View File

@@ -61,11 +61,14 @@ SRC_URI = "sftp://user@host.example.com/dir/path.file.txt"
import os
import bb
import urllib.request, urllib.parse, urllib.error
import urllib
import commands
from bb import data
from bb.fetch2 import URI
from bb.fetch2 import FetchMethod
from bb.fetch2 import runfetchcmd
class SFTP(FetchMethod):
"""Class to fetch urls via 'sftp'"""
@@ -90,19 +93,19 @@ class SFTP(FetchMethod):
else:
ud.basename = os.path.basename(ud.path)
ud.localfile = d.expand(urllib.parse.unquote(ud.basename))
ud.localfile = data.expand(urllib.unquote(ud.basename), d)
def download(self, ud, d):
"""Fetch urls"""
urlo = URI(ud.url)
basecmd = 'sftp -oBatchMode=yes'
basecmd = 'sftp -oPasswordAuthentication=no'
port = ''
if urlo.port:
port = '-P %d' % urlo.port
urlo.port = None
dldir = d.getVar('DL_DIR')
dldir = data.getVar('DL_DIR', d, True)
lpath = os.path.join(dldir, ud.localfile)
user = ''
@@ -118,7 +121,8 @@ class SFTP(FetchMethod):
remote = '%s%s:%s' % (user, urlo.hostname, path)
cmd = '%s %s %s %s' % (basecmd, port, remote, lpath)
cmd = '%s %s %s %s' % (basecmd, port, commands.mkarg(remote),
commands.mkarg(lpath))
bb.fetch2.check_network_access(d, cmd, ud.url)
runfetchcmd(cmd, d)

View File

@@ -43,6 +43,7 @@ IETF secsh internet draft:
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import re, os
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import logger
@@ -86,11 +87,11 @@ class SSH(FetchMethod):
m = __pattern__.match(urldata.url)
path = m.group('path')
host = m.group('host')
urldata.localpath = os.path.join(d.getVar('DL_DIR'),
urldata.localpath = os.path.join(d.getVar('DL_DIR', True),
os.path.basename(os.path.normpath(path)))
def download(self, urldata, d):
dldir = d.getVar('DL_DIR')
dldir = d.getVar('DL_DIR', True)
m = __pattern__.match(urldata.url)
path = m.group('path')
@@ -113,10 +114,12 @@ class SSH(FetchMethod):
fr = host
fr += ':%s' % path
import commands
cmd = 'scp -B -r %s %s %s/' % (
portarg,
fr,
dldir
commands.mkarg(fr),
commands.mkarg(dldir)
)
bb.fetch2.check_network_access(d, cmd, urldata.url)

View File

@@ -28,6 +28,7 @@ import sys
import logging
import bb
import re
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import MissingParameterError
@@ -49,26 +50,21 @@ class Svn(FetchMethod):
if not "module" in ud.parm:
raise MissingParameterError('module', ud.url)
ud.basecmd = d.getVar('FETCHCMD_svn')
ud.basecmd = d.getVar('FETCHCMD_svn', True)
ud.module = ud.parm["module"]
if not "path_spec" in ud.parm:
ud.path_spec = ud.module
else:
ud.path_spec = ud.parm["path_spec"]
# Create paths to svn checkouts
relpath = self._strip_leading_slashes(ud.path)
ud.pkgdir = os.path.join(d.expand('${SVNDIR}'), ud.host, relpath)
ud.pkgdir = os.path.join(data.expand('${SVNDIR}', d), ud.host, relpath)
ud.moddir = os.path.join(ud.pkgdir, ud.module)
ud.setup_revisions(d)
ud.setup_revisons(d)
if 'rev' in ud.parm:
ud.revision = ud.parm['rev']
ud.localfile = d.expand('%s_%s_%s_%s_.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.path.replace('/', '.'), ud.revision))
ud.localfile = data.expand('%s_%s_%s_%s_.tar.gz' % (ud.module.replace('/', '.'), ud.host, ud.path.replace('/', '.'), ud.revision), d)
def _buildsvncommand(self, ud, d, command):
"""
@@ -78,9 +74,9 @@ class Svn(FetchMethod):
proto = ud.parm.get('protocol', 'svn')
svn_ssh = None
if proto == "svn+ssh" and "ssh" in ud.parm:
svn_ssh = ud.parm["ssh"]
svn_rsh = None
if proto == "svn+ssh" and "rsh" in ud.parm:
svn_rsh = ud.parm["rsh"]
svnroot = ud.host + ud.path
@@ -106,14 +102,14 @@ class Svn(FetchMethod):
if command == "fetch":
transportuser = ud.parm.get("transportuser", "")
svncmd = "%s co %s %s://%s%s/%s%s %s" % (ud.basecmd, " ".join(options), proto, transportuser, svnroot, ud.module, suffix, ud.path_spec)
svncmd = "%s co %s %s://%s%s/%s%s %s" % (ud.basecmd, " ".join(options), proto, transportuser, svnroot, ud.module, suffix, ud.module)
elif command == "update":
svncmd = "%s update %s" % (ud.basecmd, " ".join(options))
else:
raise FetchError("Invalid svn command %s" % command, ud.url)
if svn_ssh:
svncmd = "SVN_SSH=\"%s\" %s" % (svn_ssh, svncmd)
if svn_rsh:
svncmd = "svn_RSH=\"%s\" %s" % (svn_rsh, svncmd)
return svncmd
@@ -125,32 +121,35 @@ class Svn(FetchMethod):
if os.access(os.path.join(ud.moddir, '.svn'), os.R_OK):
svnupdatecmd = self._buildsvncommand(ud, d, "update")
logger.info("Update " + ud.url)
# update sources there
os.chdir(ud.moddir)
# We need to attempt to run svn upgrade first in case its an older working format
try:
runfetchcmd(ud.basecmd + " upgrade", d, workdir=ud.moddir)
runfetchcmd(ud.basecmd + " upgrade", d)
except FetchError:
pass
logger.debug(1, "Running %s", svnupdatecmd)
bb.fetch2.check_network_access(d, svnupdatecmd, ud.url)
runfetchcmd(svnupdatecmd, d, workdir=ud.moddir)
runfetchcmd(svnupdatecmd, d)
else:
svnfetchcmd = self._buildsvncommand(ud, d, "fetch")
logger.info("Fetch " + ud.url)
# check out sources there
bb.utils.mkdirhier(ud.pkgdir)
os.chdir(ud.pkgdir)
logger.debug(1, "Running %s", svnfetchcmd)
bb.fetch2.check_network_access(d, svnfetchcmd, ud.url)
runfetchcmd(svnfetchcmd, d, workdir=ud.pkgdir)
runfetchcmd(svnfetchcmd, d)
scmdata = ud.parm.get("scmdata", "")
if scmdata == "keep":
tar_flags = ""
else:
tar_flags = "--exclude='.svn'"
tar_flags = "--exclude '.svn'"
os.chdir(ud.pkgdir)
# tar them up to a defined filename
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.path_spec), d,
cleanup=[ud.localpath], workdir=ud.pkgdir)
runfetchcmd("tar %s -czf %s %s" % (tar_flags, ud.localpath, ud.module), d, cleanup = [ud.localpath])
def clean(self, ud, d):
""" Clean SVN specific files and dirs """
@@ -172,7 +171,7 @@ class Svn(FetchMethod):
"""
Return the latest upstream revision number
"""
bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"), ud.url)
bb.fetch2.check_network_access(d, self._buildsvncommand(ud, d, "log1"))
output = runfetchcmd("LANG=C LC_ALL=C " + self._buildsvncommand(ud, d, "log1"), d, True)

View File

@@ -30,38 +30,14 @@ import tempfile
import subprocess
import os
import logging
import errno
import bb
import bb.progress
import urllib.request, urllib.parse, urllib.error
import urllib
from bb import data
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import logger
from bb.fetch2 import runfetchcmd
from bb.utils import export_proxies
from bs4 import BeautifulSoup
from bs4 import SoupStrainer
class WgetProgressHandler(bb.progress.LineFilterProgressHandler):
"""
Extract progress information from wget output.
Note: relies on --progress=dot (with -v or without -q/-nv) being
specified on the wget command line.
"""
def __init__(self, d):
super(WgetProgressHandler, self).__init__(d)
# Send an initial progress event so the bar gets shown
self._fire_progress(0)
def writeline(self, line):
percs = re.findall(r'(\d+)%\s+([\d.]+[A-Z])', line)
if percs:
progress = int(percs[-1][0])
rate = percs[-1][1] + '/s'
self.update(progress, rate)
return False
return True
class Wget(FetchMethod):
"""Class to fetch urls via 'wget'"""
@@ -84,19 +60,15 @@ class Wget(FetchMethod):
else:
ud.basename = os.path.basename(ud.path)
ud.localfile = d.expand(urllib.parse.unquote(ud.basename))
if not ud.localfile:
ud.localfile = d.expand(urllib.parse.unquote(ud.host + ud.path).replace("/", "."))
ud.localfile = data.expand(urllib.unquote(ud.basename), d)
self.basecmd = d.getVar("FETCHCMD_wget") or "/usr/bin/env wget -t 2 -T 30 --passive-ftp --no-check-certificate"
self.basecmd = d.getVar("FETCHCMD_wget", True) or "/usr/bin/env wget -t 2 -T 30 -nv --passive-ftp --no-check-certificate"
def _runwget(self, ud, d, command, quiet, workdir=None):
progresshandler = WgetProgressHandler(d)
def _runwget(self, ud, d, command, quiet):
logger.debug(2, "Fetching %s using command '%s'" % (ud.url, command))
bb.fetch2.check_network_access(d, command, ud.url)
runfetchcmd(command + ' --progress=dot -v', d, quiet, log=progresshandler, workdir=workdir)
bb.fetch2.check_network_access(d, command)
runfetchcmd(command, d, quiet)
def download(self, ud, d):
"""Fetch urls"""
@@ -104,13 +76,10 @@ class Wget(FetchMethod):
fetchcmd = self.basecmd
if 'downloadfilename' in ud.parm:
dldir = d.getVar("DL_DIR")
dldir = d.getVar("DL_DIR", True)
bb.utils.mkdirhier(os.path.dirname(dldir + os.sep + ud.localfile))
fetchcmd += " -O " + dldir + os.sep + ud.localfile
if ud.user and ud.pswd:
fetchcmd += " --user=%s --password=%s --auth-no-challenge" % (ud.user, ud.pswd)
uri = ud.url.split(";")[0]
if os.path.exists(ud.localpath):
# file exists, but we didnt complete it.. trying again..
@@ -131,218 +100,13 @@ class Wget(FetchMethod):
return True
def checkstatus(self, fetch, ud, d, try_again=True):
import urllib.request, urllib.error, urllib.parse, socket, http.client
from urllib.response import addinfourl
from bb.fetch2 import FetchConnectionCache
def checkstatus(self, ud, d):
class HTTPConnectionCache(http.client.HTTPConnection):
if fetch.connection_cache:
def connect(self):
"""Connect to the host and port specified in __init__."""
uri = ud.url.split(";")[0]
fetchcmd = self.basecmd + " --spider '%s'" % uri
sock = fetch.connection_cache.get_connection(self.host, self.port)
if sock:
self.sock = sock
else:
self.sock = socket.create_connection((self.host, self.port),
self.timeout, self.source_address)
fetch.connection_cache.add_connection(self.host, self.port, self.sock)
self._runwget(ud, d, fetchcmd, True)
if self._tunnel_host:
self._tunnel()
class CacheHTTPHandler(urllib.request.HTTPHandler):
def http_open(self, req):
return self.do_open(HTTPConnectionCache, req)
def do_open(self, http_class, req):
"""Return an addinfourl object for the request, using http_class.
http_class must implement the HTTPConnection API from httplib.
The addinfourl return value is a file-like object. It also
has methods and attributes including:
- info(): return a mimetools.Message object for the headers
- geturl(): return the original request URL
- code: HTTP status code
"""
host = req.host
if not host:
raise urlllib2.URLError('no host given')
h = http_class(host, timeout=req.timeout) # will parse host:port
h.set_debuglevel(self._debuglevel)
headers = dict(req.unredirected_hdrs)
headers.update(dict((k, v) for k, v in list(req.headers.items())
if k not in headers))
# We want to make an HTTP/1.1 request, but the addinfourl
# class isn't prepared to deal with a persistent connection.
# It will try to read all remaining data from the socket,
# which will block while the server waits for the next request.
# So make sure the connection gets closed after the (only)
# request.
# Don't close connection when connection_cache is enabled,
if fetch.connection_cache is None:
headers["Connection"] = "close"
else:
headers["Connection"] = "Keep-Alive" # Works for HTTP/1.0
headers = dict(
(name.title(), val) for name, val in list(headers.items()))
if req._tunnel_host:
tunnel_headers = {}
proxy_auth_hdr = "Proxy-Authorization"
if proxy_auth_hdr in headers:
tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
# Proxy-Authorization should not be sent to origin
# server.
del headers[proxy_auth_hdr]
h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
try:
h.request(req.get_method(), req.selector, req.data, headers)
except socket.error as err: # XXX what error?
# Don't close connection when cache is enabled.
# Instead, try to detect connections that are no longer
# usable (for example, closed unexpectedly) and remove
# them from the cache.
if fetch.connection_cache is None:
h.close()
elif isinstance(err, OSError) and err.errno == errno.EBADF:
# This happens when the server closes the connection despite the Keep-Alive.
# Apparently urllib then uses the file descriptor, expecting it to be
# connected, when in reality the connection is already gone.
# We let the request fail and expect it to be
# tried once more ("try_again" in check_status()),
# with the dead connection removed from the cache.
# If it still fails, we give up, which can happend for bad
# HTTP proxy settings.
fetch.connection_cache.remove_connection(h.host, h.port)
raise urllib.error.URLError(err)
else:
try:
r = h.getresponse(buffering=True)
except TypeError: # buffering kw not supported
r = h.getresponse()
# Pick apart the HTTPResponse object to get the addinfourl
# object initialized properly.
# Wrap the HTTPResponse object in socket's file object adapter
# for Windows. That adapter calls recv(), so delegate recv()
# to read(). This weird wrapping allows the returned object to
# have readline() and readlines() methods.
# XXX It might be better to extract the read buffering code
# out of socket._fileobject() and into a base class.
r.recv = r.read
# no data, just have to read
r.read()
class fp_dummy(object):
def read(self):
return ""
def readline(self):
return ""
def close(self):
pass
closed = False
resp = addinfourl(fp_dummy(), r.msg, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
# Close connection when server request it.
if fetch.connection_cache is not None:
if 'Connection' in r.msg and r.msg['Connection'] == 'close':
fetch.connection_cache.remove_connection(h.host, h.port)
return resp
class HTTPMethodFallback(urllib.request.BaseHandler):
"""
Fallback to GET if HEAD is not allowed (405 HTTP error)
"""
def http_error_405(self, req, fp, code, msg, headers):
fp.read()
fp.close()
newheaders = dict((k,v) for k,v in list(req.headers.items())
if k.lower() not in ("content-length", "content-type"))
return self.parent.open(urllib.request.Request(req.get_full_url(),
headers=newheaders,
origin_req_host=req.origin_req_host,
unverifiable=True))
"""
Some servers (e.g. GitHub archives, hosted on Amazon S3) return 403
Forbidden when they actually mean 405 Method Not Allowed.
"""
http_error_403 = http_error_405
class FixedHTTPRedirectHandler(urllib.request.HTTPRedirectHandler):
"""
urllib2.HTTPRedirectHandler resets the method to GET on redirect,
when we want to follow redirects using the original method.
"""
def redirect_request(self, req, fp, code, msg, headers, newurl):
newreq = urllib.request.HTTPRedirectHandler.redirect_request(self, req, fp, code, msg, headers, newurl)
newreq.get_method = lambda: req.get_method()
return newreq
exported_proxies = export_proxies(d)
handlers = [FixedHTTPRedirectHandler, HTTPMethodFallback]
if export_proxies:
handlers.append(urllib.request.ProxyHandler())
handlers.append(CacheHTTPHandler())
# XXX: Since Python 2.7.9 ssl cert validation is enabled by default
# see PEP-0476, this causes verification errors on some https servers
# so disable by default.
import ssl
if hasattr(ssl, '_create_unverified_context'):
handlers.append(urllib.request.HTTPSHandler(context=ssl._create_unverified_context()))
opener = urllib.request.build_opener(*handlers)
try:
uri = ud.url.split(";")[0]
r = urllib.request.Request(uri)
r.get_method = lambda: "HEAD"
# Some servers (FusionForge, as used on Alioth) require that the
# optional Accept header is set.
r.add_header("Accept", "*/*")
def add_basic_auth(login_str, request):
'''Adds Basic auth to http request, pass in login:password as string'''
import base64
encodeuser = base64.b64encode(login_str.encode('utf-8')).decode("utf-8")
authheader = "Basic %s" % encodeuser
r.add_header("Authorization", authheader)
if ud.user:
add_basic_auth(ud.user, r)
try:
import netrc, urllib.parse
n = netrc.netrc()
login, unused, password = n.authenticators(urllib.parse.urlparse(uri).hostname)
add_basic_auth("%s:%s" % (login, password), r)
except (TypeError, ImportError, IOError, netrc.NetrcParseError):
pass
with opener.open(r) as response:
pass
except urllib.error.URLError as e:
if try_again:
logger.debug(2, "checkstatus: trying again")
return self.checkstatus(fetch, ud, d, False)
else:
# debug for now to avoid spamming the logs in e.g. remote sstate searches
logger.debug(2, "checkstatus() urlopen failed: %s" % e)
return False
return True
def _parse_path(self, regex, s):
@@ -421,16 +185,17 @@ class Wget(FetchMethod):
Run fetch checkstatus to get directory information
"""
f = tempfile.NamedTemporaryFile()
with tempfile.TemporaryDirectory(prefix="wget-index-") as workdir, tempfile.NamedTemporaryFile(dir=workdir, prefix="wget-listing-") as f:
agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/9.10 (karmic) Firefox/3.6.12"
fetchcmd = self.basecmd
fetchcmd += " -O " + f.name + " --user-agent='" + agent + "' '" + uri + "'"
try:
self._runwget(ud, d, fetchcmd, True, workdir=workdir)
fetchresult = f.read()
except bb.fetch2.BBFetchException:
fetchresult = ""
agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/9.10 (karmic) Firefox/3.6.12"
fetchcmd = self.basecmd
fetchcmd += " -O " + f.name + " --user-agent='" + agent + "' '" + uri + "'"
try:
self._runwget(ud, d, fetchcmd, True)
fetchresult = f.read()
except bb.fetch2.BBFetchException:
fetchresult = ""
f.close()
return fetchresult
def _check_latest_version(self, url, package, package_regex, current_version, ud, d):
@@ -442,7 +207,7 @@ class Wget(FetchMethod):
version = ['', '', '']
bb.debug(3, "VersionURL: %s" % (url))
soup = BeautifulSoup(self._fetch_index(url, ud, d), "html.parser", parse_only=SoupStrainer("a"))
soup = BeautifulSoup(self._fetch_index(url, ud, d))
if not soup:
bb.debug(3, "*** %s NO SOUP" % (url))
return ""
@@ -481,10 +246,10 @@ class Wget(FetchMethod):
version_dir = ['', '', '']
version = ['', '', '']
dirver_regex = re.compile("(?P<pfx>\D*)(?P<ver>(\d+[\.\-_])+(\d+))")
dirver_regex = re.compile("(\D*)((\d+[\.-_])+(\d+))")
s = dirver_regex.search(dirver)
if s:
version_dir[1] = s.group('ver')
version_dir[1] = s.group(2)
else:
version_dir[1] = dirver
@@ -492,26 +257,16 @@ class Wget(FetchMethod):
ud.path.split(dirver)[0], ud.user, ud.pswd, {}])
bb.debug(3, "DirURL: %s, %s" % (dirs_uri, package))
soup = BeautifulSoup(self._fetch_index(dirs_uri, ud, d), "html.parser", parse_only=SoupStrainer("a"))
soup = BeautifulSoup(self._fetch_index(dirs_uri, ud, d))
if not soup:
return version[1]
for line in soup.find_all('a', href=True):
s = dirver_regex.search(line['href'].strip("/"))
if s:
sver = s.group('ver')
# When prefix is part of the version directory it need to
# ensure that only version directory is used so remove previous
# directories if exists.
#
# Example: pfx = '/dir1/dir2/v' and version = '2.5' the expected
# result is v2.5.
spfx = s.group('pfx').split('/')[-1]
version_dir_new = ['', sver, '']
version_dir_new = ['', s.group(2), '']
if self._vercmp(version_dir, version_dir_new) <= 0:
dirver_new = spfx + sver
dirver_new = s.group(1) + s.group(2)
path = ud.path.replace(dirver, dirver_new, True) \
.split(package)[0]
uri = bb.fetch.encodeurl([ud.type, ud.host, path,
@@ -550,14 +305,14 @@ class Wget(FetchMethod):
pn_regex = "(%s|%s|%s)" % (pn_prefix1, pn_prefix2, pn_prefix3)
# match version
pver_regex = "(([A-Z]*\d+[a-zA-Z]*[\.\-_]*)+)"
pver_regex = "(([A-Z]*\d+[a-zA-Z]*[\.-_]*)+)"
# match arch
parch_regex = "-source|_all_"
# src.rpm extension was added only for rpm package. Can be removed if the rpm
# packaged will always be considered as having to be manually upgraded
psuffix_regex = "(tar\.gz|tgz|tar\.bz2|zip|xz|tar\.lz|rpm|bz2|orig\.tar\.gz|tar\.xz|src\.tar\.gz|src\.tgz|svnr\d+\.tar\.bz2|stable\.tar\.gz|src\.rpm)"
psuffix_regex = "(tar\.gz|tgz|tar\.bz2|zip|xz|rpm|bz2|orig\.tar\.gz|tar\.xz|src\.tar\.gz|src\.tgz|svnr\d+\.tar\.bz2|stable\.tar\.gz|src\.rpm)"
# match name, version and archive type of a package
package_regex_comp = re.compile("(?P<name>%s?\.?v?)(?P<pver>%s)(?P<arch>%s)?[\.-](?P<type>%s$)"
@@ -565,7 +320,7 @@ class Wget(FetchMethod):
self.suffix_regex_comp = re.compile(psuffix_regex)
# compile regex, can be specific by package or generic regex
pn_regex = d.getVar('UPSTREAM_CHECK_REGEX')
pn_regex = d.getVar('REGEX', True)
if pn_regex:
package_custom_regex_comp = re.compile(pn_regex)
else:
@@ -586,22 +341,22 @@ class Wget(FetchMethod):
sanity check to ensure same name and type.
"""
package = ud.path.split("/")[-1]
current_version = ['', d.getVar('PV'), '']
current_version = ['', d.getVar('PV', True), '']
"""possible to have no version in pkg name, such as spectrum-fw"""
if not re.search("\d+", package):
current_version[1] = re.sub('_', '.', current_version[1])
current_version[1] = re.sub('-', '.', current_version[1])
return (current_version[1], '')
return current_version[1]
package_regex = self._init_regexes(package, ud, d)
if package_regex is None:
bb.warn("latest_versionstring: package %s don't match pattern" % (package))
return ('', '')
return ""
bb.debug(3, "latest_versionstring, regex: %s" % (package_regex.pattern))
uri = ""
regex_uri = d.getVar("UPSTREAM_CHECK_URI")
regex_uri = d.getVar("REGEX_URI", True)
if not regex_uri:
path = ud.path.split(package)[0]
@@ -610,17 +365,17 @@ class Wget(FetchMethod):
dirver_regex = re.compile("(?P<dirver>[^/]*(\d+\.)*\d+([-_]r\d+)*)/")
m = dirver_regex.search(path)
if m:
pn = d.getVar('PN')
pn = d.getVar('PN', True)
dirver = m.group('dirver')
dirver_pn_regex = re.compile("%s\d?" % (re.escape(pn)))
if not dirver_pn_regex.search(dirver):
return (self._check_latest_version_by_dir(dirver,
package, package_regex, current_version, ud, d), '')
return self._check_latest_version_by_dir(dirver,
package, package_regex, current_version, ud, d)
uri = bb.fetch.encodeurl([ud.type, ud.host, path, ud.user, ud.pswd, {}])
else:
uri = regex_uri
return (self._check_latest_version(uri, package, package_regex,
current_version, ud, d), '')
return self._check_latest_version(uri, package, package_regex,
current_version, ud, d)

View File

@@ -27,9 +27,6 @@ import sys
import logging
import optparse
import warnings
import fcntl
import time
import traceback
import bb
from bb import event
@@ -39,79 +36,29 @@ from bb import ui
from bb import server
from bb import cookerdata
import bb.server.process
import bb.server.xmlrpcclient
__version__ = "1.26.0"
logger = logging.getLogger("BitBake")
class BBMainException(Exception):
class BBMainException(bb.BBHandledException):
pass
class BBMainFatal(bb.BBHandledException):
pass
def get_ui(config):
if not config.ui:
# modify 'ui' attribute because it is also read by cooker
config.ui = os.environ.get('BITBAKE_UI', 'knotty')
def present_options(optionlist):
if len(optionlist) > 1:
return ' or '.join([', '.join(optionlist[:-1]), optionlist[-1]])
else:
return optionlist[0]
interface = config.ui
class BitbakeHelpFormatter(optparse.IndentedHelpFormatter):
def format_option(self, option):
# We need to do this here rather than in the text we supply to
# add_option() because we don't want to call list_extension_modules()
# on every execution (since it imports all of the modules)
# Note also that we modify option.help rather than the returned text
# - this is so that we don't have to re-format the text ourselves
if option.dest == 'ui':
valid_uis = list_extension_modules(bb.ui, 'main')
option.help = option.help.replace('@CHOICES@', present_options(valid_uis))
return optparse.IndentedHelpFormatter.format_option(self, option)
def list_extension_modules(pkg, checkattr):
"""
Lists extension modules in a specific Python package
(e.g. UIs, servers). NOTE: Calling this function will import all of the
submodules of the specified module in order to check for the specified
attribute; this can have unusual side-effects. As a result, this should
only be called when displaying help text or error messages.
Parameters:
pkg: previously imported Python package to list
checkattr: attribute to look for in module to determine if it's valid
as the type of extension you are looking for
"""
import pkgutil
pkgdir = os.path.dirname(pkg.__file__)
modules = []
for _, modulename, _ in pkgutil.iter_modules([pkgdir]):
if os.path.isdir(os.path.join(pkgdir, modulename)):
# ignore directories
continue
try:
module = __import__(pkg.__name__, fromlist=[modulename])
except:
# If we can't import it, it's not valid
continue
module_if = getattr(module, modulename)
if getattr(module_if, 'hidden_extension', False):
continue
if not checkattr or hasattr(module_if, checkattr):
modules.append(modulename)
return modules
def import_extension_module(pkg, modulename, checkattr):
try:
# Dynamically load the UI based on the ui name. Although we
# suggest a fixed set this allows you to have flexibility in which
# ones are available.
module = __import__(pkg.__name__, fromlist=[modulename])
return getattr(module, modulename)
module = __import__("bb.ui", fromlist = [interface])
return getattr(module, interface)
except AttributeError:
modules = present_options(list_extension_modules(pkg, checkattr))
raise BBMainException('FATAL: Unable to import extension module "%s" from %s. '
'Valid extension modules: %s' % (modulename, pkg.__name__, modules))
raise BBMainException("FATAL: Invalid user interface '%s' specified.\n"
"Valid interfaces: depexp, goggle, ncurses, hob, knotty [default]." % interface)
# Display bitbake/OE warnings via the BitBake.Warnings logger, ignoring others"""
warnlog = logging.getLogger("BitBake.Warnings")
@@ -122,7 +69,7 @@ def _showwarning(message, category, filename, lineno, file=None, line=None):
_warnings_showwarning(message, category, filename, lineno, file, line)
else:
s = warnings.formatwarning(message, category, filename, lineno)
warnlog.warning(s)
warnlog.warn(s)
warnings.showwarning = _showwarning
warnings.filterwarnings("ignore")
@@ -136,204 +83,185 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters):
def parseCommandLine(self, argv=sys.argv):
parser = optparse.OptionParser(
formatter=BitbakeHelpFormatter(),
version="BitBake Build Tool Core version %s" % bb.__version__,
usage="""%prog [options] [recipename/target recipe:do_task ...]
version = "BitBake Build Tool Core version %s, %%prog version %s" % (bb.__version__, __version__),
usage = """%prog [options] [recipename/target ...]
Executes the specified task (default is 'build') for a given set of target recipes (.bb files).
It is assumed there is a conf/bblayers.conf available in cwd or in BBPATH which
will provide the layer, BBFILES and other configuration information.""")
parser.add_option("-b", "--buildfile", action="store", dest="buildfile", default=None,
help="Execute tasks from a specific .bb recipe directly. WARNING: Does "
"not handle any dependencies from other recipes.")
parser.add_option("-b", "--buildfile", help = "Execute tasks from a specific .bb recipe directly. WARNING: Does not handle any dependencies from other recipes.",
action = "store", dest = "buildfile", default = None)
parser.add_option("-k", "--continue", action="store_false", dest="abort", default=True,
help="Continue as much as possible after an error. While the target that "
"failed and anything depending on it cannot be built, as much as "
"possible will be built before stopping.")
parser.add_option("-k", "--continue", help = "Continue as much as possible after an error. While the target that failed and anything depending on it cannot be built, as much as possible will be built before stopping.",
action = "store_false", dest = "abort", default = True)
parser.add_option("-f", "--force", action="store_true", dest="force", default=False,
help="Force the specified targets/task to run (invalidating any "
"existing stamp file).")
parser.add_option("-a", "--tryaltconfigs", help = "Continue with builds by trying to use alternative providers where possible.",
action = "store_true", dest = "tryaltconfigs", default = False)
parser.add_option("-c", "--cmd", action="store", dest="cmd",
help="Specify the task to execute. The exact options available "
"depend on the metadata. Some examples might be 'compile'"
" or 'populate_sysroot' or 'listtasks' may give a list of "
"the tasks available.")
parser.add_option("-f", "--force", help = "Force the specified targets/task to run (invalidating any existing stamp file).",
action = "store_true", dest = "force", default = False)
parser.add_option("-C", "--clear-stamp", action="store", dest="invalidate_stamp",
help="Invalidate the stamp for the specified task such as 'compile' "
"and then run the default task for the specified target(s).")
parser.add_option("-c", "--cmd", help = "Specify the task to execute. The exact options available depend on the metadata. Some examples might be 'compile' or 'populate_sysroot' or 'listtasks' may give a list of the tasks available.",
action = "store", dest = "cmd")
parser.add_option("-r", "--read", action="append", dest="prefile", default=[],
help="Read the specified file before bitbake.conf.")
parser.add_option("-C", "--clear-stamp", help = "Invalidate the stamp for the specified task such as 'compile' and then run the default task for the specified target(s).",
action = "store", dest = "invalidate_stamp")
parser.add_option("-R", "--postread", action="append", dest="postfile", default=[],
help="Read the specified file after bitbake.conf.")
parser.add_option("-r", "--read", help = "Read the specified file before bitbake.conf.",
action = "append", dest = "prefile", default = [])
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
help="Enable tracing of shell tasks (with 'set -x'). "
"Also print bb.note(...) messages to stdout (in "
"addition to writing them to ${T}/log.do_<task>).")
parser.add_option("-R", "--postread", help = "Read the specified file after bitbake.conf.",
action = "append", dest = "postfile", default = [])
parser.add_option("-D", "--debug", action="count", dest="debug", default=0,
help="Increase the debug level. You can specify this "
"more than once. -D sets the debug level to 1, "
"where only bb.debug(1, ...) messages are printed "
"to stdout; -DD sets the debug level to 2, where "
"both bb.debug(1, ...) and bb.debug(2, ...) "
"messages are printed; etc. Without -D, no debug "
"messages are printed. Note that -D only affects "
"output to stdout. All debug messages are written "
"to ${T}/log.do_taskname, regardless of the debug "
"level.")
parser.add_option("-v", "--verbose", help = "Output more log message data to the terminal.",
action = "store_true", dest = "verbose", default = False)
parser.add_option("-q", "--quiet", action="count", dest="quiet", default=0,
help="Output less log message data to the terminal. You can specify this more than once.")
parser.add_option("-D", "--debug", help = "Increase the debug level. You can specify this more than once.",
action = "count", dest="debug", default = 0)
parser.add_option("-n", "--dry-run", action="store_true", dest="dry_run", default=False,
help="Don't execute, just go through the motions.")
parser.add_option("-n", "--dry-run", help = "Don't execute, just go through the motions.",
action = "store_true", dest = "dry_run", default = False)
parser.add_option("-S", "--dump-signatures", action="append", dest="dump_signatures",
default=[], metavar="SIGNATURE_HANDLER",
help="Dump out the signature construction information, with no task "
"execution. The SIGNATURE_HANDLER parameter is passed to the "
"handler. Two common values are none and printdiff but the handler "
"may define more/less. none means only dump the signature, printdiff"
" means compare the dumped signature with the cached one.")
parser.add_option("-S", "--dump-signatures", help = "Dump out the signature construction information, with no task execution. The SIGNATURE_HANDLER parameter is passed to the handler. Two common values are none and printdiff but the handler may define more/less. none means only dump the signature, printdiff means compare the dumped signature with the cached one.",
action = "append", dest = "dump_signatures", default = [], metavar="SIGNATURE_HANDLER")
parser.add_option("-p", "--parse-only", action="store_true",
dest="parse_only", default=False,
help="Quit after parsing the BB recipes.")
parser.add_option("-p", "--parse-only", help = "Quit after parsing the BB recipes.",
action = "store_true", dest = "parse_only", default = False)
parser.add_option("-s", "--show-versions", action="store_true",
dest="show_versions", default=False,
help="Show current and preferred versions of all recipes.")
parser.add_option("-s", "--show-versions", help = "Show current and preferred versions of all recipes.",
action = "store_true", dest = "show_versions", default = False)
parser.add_option("-e", "--environment", action="store_true",
dest="show_environment", default=False,
help="Show the global or per-recipe environment complete with information"
" about where variables were set/changed.")
parser.add_option("-e", "--environment", help = "Show the global or per-recipe environment complete with information about where variables were set/changed.",
action = "store_true", dest = "show_environment", default = False)
parser.add_option("-g", "--graphviz", action="store_true", dest="dot_graph", default=False,
help="Save dependency tree information for the specified "
"targets in the dot syntax.")
parser.add_option("-g", "--graphviz", help = "Save dependency tree information for the specified targets in the dot syntax.",
action = "store_true", dest = "dot_graph", default = False)
parser.add_option("-I", "--ignore-deps", action="append",
dest="extra_assume_provided", default=[],
help="Assume these dependencies don't exist and are already provided "
"(equivalent to ASSUME_PROVIDED). Useful to make dependency "
"graphs more appealing")
parser.add_option("-I", "--ignore-deps", help = """Assume these dependencies don't exist and are already provided (equivalent to ASSUME_PROVIDED). Useful to make dependency graphs more appealing""",
action = "append", dest = "extra_assume_provided", default = [])
parser.add_option("-l", "--log-domains", action="append", dest="debug_domains", default=[],
help="Show debug logging for the specified logging domains")
parser.add_option("-l", "--log-domains", help = """Show debug logging for the specified logging domains""",
action = "append", dest = "debug_domains", default = [])
parser.add_option("-P", "--profile", action="store_true", dest="profile", default=False,
help="Profile the command and save reports.")
parser.add_option("-P", "--profile", help = "Profile the command and save reports.",
action = "store_true", dest = "profile", default = False)
# @CHOICES@ is substituted out by BitbakeHelpFormatter above
parser.add_option("-u", "--ui", action="store", dest="ui",
default=os.environ.get('BITBAKE_UI', 'knotty'),
help="The user interface to use (@CHOICES@ - default %default).")
parser.add_option("-u", "--ui", help = "The user interface to use (e.g. knotty, hob, depexp).",
action = "store", dest = "ui")
parser.add_option("", "--token", action="store", dest="xmlrpctoken",
default=os.environ.get("BBTOKEN"),
help="Specify the connection token to be used when connecting "
"to a remote server.")
parser.add_option("-t", "--servertype", help = "Choose which server to use, process or xmlrpc.",
action = "store", dest = "servertype")
parser.add_option("", "--revisions-changed", action="store_true",
dest="revisions_changed", default=False,
help="Set the exit code depending on whether upstream floating "
"revisions have changed or not.")
parser.add_option("", "--token", help = "Specify the connection token to be used when connecting to a remote server.",
action = "store", dest = "xmlrpctoken")
parser.add_option("", "--server-only", action="store_true",
dest="server_only", default=False,
help="Run bitbake without a UI, only starting a server "
"(cooker) process.")
parser.add_option("", "--revisions-changed", help = "Set the exit code depending on whether upstream floating revisions have changed or not.",
action = "store_true", dest = "revisions_changed", default = False)
parser.add_option("-B", "--bind", action="store", dest="bind", default=False,
help="The name/address for the bitbake xmlrpc server to bind to.")
parser.add_option("", "--server-only", help = "Run bitbake without a UI, only starting a server (cooker) process.",
action = "store_true", dest = "server_only", default = False)
parser.add_option("-T", "--idle-timeout", type=float, dest="server_timeout",
default=os.getenv("BB_SERVER_TIMEOUT"),
help="Set timeout to unload bitbake server due to inactivity, "
"set to -1 means no unload, "
"default: Environment variable BB_SERVER_TIMEOUT.")
parser.add_option("-B", "--bind", help = "The name/address for the bitbake server to bind to.",
action = "store", dest = "bind", default = False)
parser.add_option("", "--no-setscene", action="store_true",
dest="nosetscene", default=False,
help="Do not run any setscene tasks. sstate will be ignored and "
"everything needed, built.")
parser.add_option("", "--no-setscene", help = "Do not run any setscene tasks. sstate will be ignored and everything needed, built.",
action = "store_true", dest = "nosetscene", default = False)
parser.add_option("", "--setscene-only", action="store_true",
dest="setsceneonly", default=False,
help="Only run setscene tasks, don't run any real tasks.")
parser.add_option("", "--remote-server", help = "Connect to the specified server.",
action = "store", dest = "remote_server", default = False)
parser.add_option("", "--remote-server", action="store", dest="remote_server",
default=os.environ.get("BBSERVER"),
help="Connect to the specified server.")
parser.add_option("-m", "--kill-server", help = "Terminate the remote server.",
action = "store_true", dest = "kill_server", default = False)
parser.add_option("-m", "--kill-server", action="store_true",
dest="kill_server", default=False,
help="Terminate any running bitbake server.")
parser.add_option("", "--observe-only", help = "Connect to a server as an observing-only client.",
action = "store_true", dest = "observe_only", default = False)
parser.add_option("", "--observe-only", action="store_true",
dest="observe_only", default=False,
help="Connect to a server as an observing-only client.")
parser.add_option("", "--status-only", action="store_true",
dest="status_only", default=False,
help="Check the status of the remote bitbake server.")
parser.add_option("-w", "--write-log", action="store", dest="writeeventlog",
default=os.environ.get("BBEVENTLOG"),
help="Writes the event log of the build to a bitbake event json file. "
"Use '' (empty string) to assign the name automatically.")
parser.add_option("", "--runall", action="append", dest="runall",
help="Run the specified task for any recipe in the taskgraph of the specified target (even if it wouldn't otherwise have run).")
parser.add_option("", "--runonly", action="append", dest="runonly",
help="Run only the specified task within the taskgraph of the specified targets (and any task dependencies those tasks may have).")
parser.add_option("", "--status-only", help = "Check the status of the remote bitbake server.",
action = "store_true", dest = "status_only", default = False)
parser.add_option("-w", "--write-log", help = "Writes the event log of the build to a bitbake event json file. Use '' (empty string) to assign the name automatically.",
action = "store", dest = "writeeventlog")
options, targets = parser.parse_args(argv)
if options.quiet and options.verbose:
parser.error("options --quiet and --verbose are mutually exclusive")
# some environmental variables set also configuration options
if "BBSERVER" in os.environ:
options.servertype = "xmlrpc"
options.remote_server = os.environ["BBSERVER"]
if options.quiet and options.debug:
parser.error("options --quiet and --debug are mutually exclusive")
if "BBTOKEN" in os.environ:
options.xmlrpctoken = os.environ["BBTOKEN"]
# use configuration files from environment variables
if "BBPRECONF" in os.environ:
options.prefile.append(os.environ["BBPRECONF"])
if "BBPOSTCONF" in os.environ:
options.postfile.append(os.environ["BBPOSTCONF"])
if "BBEVENTLOG" is os.environ:
options.writeeventlog = os.environ["BBEVENTLOG"]
# fill in proper log name if not supplied
if options.writeeventlog is not None and len(options.writeeventlog) == 0:
from datetime import datetime
eventlog = "bitbake_eventlog_%s.json" % datetime.now().strftime("%Y%m%d%H%M%S")
options.writeeventlog = eventlog
import datetime
options.writeeventlog = "bitbake_eventlog_%s.json" % datetime.datetime.now().strftime("%Y%m%d%H%M%S")
if options.bind:
try:
#Checking that the port is a number and is a ':' delimited value
(host, port) = options.bind.split(':')
port = int(port)
except (ValueError,IndexError):
raise BBMainException("FATAL: Malformed host:port bind parameter")
options.xmlrpcinterface = (host, port)
else:
options.xmlrpcinterface = (None, 0)
# if BBSERVER says to autodetect, let's do that
if options.remote_server:
[host, port] = options.remote_server.split(":", 2)
port = int(port)
# use automatic port if port set to -1, means read it from
# the bitbake.lock file; this is a bit tricky, but we always expect
# to be in the base of the build directory if we need to have a
# chance to start the server later, anyway
if port == -1:
lock_location = "./bitbake.lock"
# we try to read the address at all times; if the server is not started,
# we'll try to start it after the first connect fails, below
try:
lf = open(lock_location, 'r')
remotedef = lf.readline()
[host, port] = remotedef.split(":")
port = int(port)
lf.close()
options.remote_server = remotedef
except Exception as e:
raise BBMainException("Failed to read bitbake.lock (%s), invalid port" % str(e))
return options, targets[1:]
def start_server(servermodule, configParams, configuration, features):
server = servermodule.BitBakeServer()
if configParams.bind:
(host, port) = configParams.bind.split(':')
server.initServer((host, int(port)))
configuration.interface = [ server.serverImpl.host, server.serverImpl.port ]
else:
server.initServer()
configuration.interface = []
try:
configuration.setServerRegIdleCallback(server.getServerIdleCB())
cooker = bb.cooker.BBCooker(configuration, features)
server.addcooker(cooker)
server.saveConnectionDetails()
except Exception as e:
exc_info = sys.exc_info()
while hasattr(server, "event_queue"):
try:
import queue
except ImportError:
import Queue as queue
try:
event = server.event_queue.get(block=False)
except (queue.Empty, IOError):
break
if isinstance(event, logging.LogRecord):
logger.handle(event)
raise exc_info[1], None, exc_info[2]
server.detach()
cooker.lock.close()
return server
def bitbake_main(configParams, configuration):
# Python multiprocessing requires /dev/shm on Linux
@@ -345,165 +273,119 @@ def bitbake_main(configParams, configuration):
# updates to log files for use with tail
try:
if sys.stdout.name == '<stdout>':
# Reopen with O_SYNC (unbuffered)
fl = fcntl.fcntl(sys.stdout.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, fl)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
except:
pass
configuration.setConfigParameters(configParams)
if configParams.server_only and configParams.remote_server:
ui_module = get_ui(configParams)
# Server type can be xmlrpc or process currently, if nothing is specified,
# the default server is process
if configParams.servertype:
server_type = configParams.servertype
else:
server_type = 'process'
try:
module = __import__("bb.server", fromlist = [server_type])
servermodule = getattr(module, server_type)
except AttributeError:
raise BBMainException("FATAL: Invalid server type '%s' specified.\n"
"Valid interfaces: xmlrpc, process [default]." % server_type)
if configParams.server_only:
if configParams.servertype != "xmlrpc":
raise BBMainException("FATAL: If '--server-only' is defined, we must set the "
"servertype as 'xmlrpc'.\n")
if not configParams.bind:
raise BBMainException("FATAL: The '--server-only' option requires a name/address "
"to bind to with the -B option.\n")
if configParams.remote_server:
raise BBMainException("FATAL: The '--server-only' option conflicts with %s.\n" %
("the BBSERVER environment variable" if "BBSERVER" in os.environ \
else "the '--remote-server' option"))
else "the '--remote-server' option" ))
if configParams.observe_only and not (configParams.remote_server or configParams.bind):
if configParams.bind and configParams.servertype != "xmlrpc":
raise BBMainException("FATAL: If '-B' or '--bind' is defined, we must "
"set the servertype as 'xmlrpc'.\n")
if configParams.remote_server and configParams.servertype != "xmlrpc":
raise BBMainException("FATAL: If '--remote-server' is defined, we must "
"set the servertype as 'xmlrpc'.\n")
if configParams.observe_only and (not configParams.remote_server or configParams.bind):
raise BBMainException("FATAL: '--observe-only' can only be used by UI clients "
"connecting to a server.\n")
if configParams.kill_server and not configParams.remote_server:
raise BBMainException("FATAL: '--kill-server' can only be used to terminate a remote server")
if "BBDEBUG" in os.environ:
level = int(os.environ["BBDEBUG"])
if level > configuration.debug:
configuration.debug = level
bb.msg.init_msgconfig(configParams.verbose, configuration.debug,
configuration.debug_domains)
configuration.debug_domains)
server_connection, ui_module = setup_bitbake(configParams, configuration)
# No server connection
if server_connection is None:
if configParams.status_only:
return 1
if configParams.kill_server:
return 0
if not configParams.server_only:
if configParams.status_only:
server_connection.terminate()
return 0
try:
for event in bb.event.ui_queue:
server_connection.events.queue_event(event)
bb.event.ui_queue = []
return ui_module.main(server_connection.connection, server_connection.events,
configParams)
finally:
server_connection.terminate()
else:
return 0
return 1
def setup_bitbake(configParams, configuration, extrafeatures=None):
# Ensure logging messages get sent to the UI as events
handler = bb.event.LogHandler()
if not configParams.status_only:
# In status only mode there are no logs and no UI
logger.addHandler(handler)
if configParams.server_only:
featureset = []
ui_module = None
else:
ui_module = import_extension_module(bb.ui, configParams.ui, 'main')
# Clear away any spurious environment variables while we stoke up the cooker
cleanedvars = bb.utils.clean_environment()
featureset = []
if not configParams.server_only:
# Collect the feature set for the UI
featureset = getattr(ui_module, "featureSet", [])
if extrafeatures:
for feature in extrafeatures:
if not feature in featureset:
featureset.append(feature)
server_connection = None
# Clear away any spurious environment variables while we stoke up the cooker
# (done after import_extension_module() above since for example import gi triggers env var usage)
cleanedvars = bb.utils.clean_environment()
if configParams.remote_server:
# Connect to a remote XMLRPC server
server_connection = bb.server.xmlrpcclient.connectXMLRPC(configParams.remote_server, featureset,
configParams.observe_only, configParams.xmlrpctoken)
else:
retries = 8
while retries:
try:
topdir, lock = lockBitbake()
sockname = topdir + "/bitbake.sock"
if lock:
if configParams.status_only or configParams.kill_server:
logger.info("bitbake server is not running.")
lock.close()
return None, None
# we start a server with a given configuration
logger.info("Starting bitbake server...")
# Clear the event queue since we already displayed messages
bb.event.ui_queue = []
server = bb.server.process.BitBakeServer(lock, sockname, configuration, featureset)
else:
logger.info("Reconnecting to bitbake server...")
if not os.path.exists(sockname):
logger.info("Previous bitbake instance shutting down?, waiting to retry...")
i = 0
lock = None
# Wait for 5s or until we can get the lock
while not lock and i < 50:
time.sleep(0.1)
_, lock = lockBitbake()
i += 1
if lock:
bb.utils.unlockfile(lock)
raise bb.server.process.ProcessTimeout("Bitbake still shutting down as socket exists but no lock?")
if not configParams.server_only:
try:
server_connection = bb.server.process.connectProcessServer(sockname, featureset)
except EOFError:
# The server may have been shutting down but not closed the socket yet. If that happened,
# ignore it.
pass
if server_connection or configParams.server_only:
break
except BBMainFatal:
raise
except (Exception, bb.server.process.ProcessTimeout) as e:
if not retries:
raise
retries -= 1
if isinstance(e, (bb.server.process.ProcessTimeout, BrokenPipeError)):
logger.info("Retrying server connection...")
else:
logger.info("Retrying server connection... (%s)" % traceback.format_exc())
if not retries:
bb.fatal("Unable to connect to bitbake server, or start one")
if retries < 5:
time.sleep(5)
if configParams.kill_server:
server_connection.connection.terminateServer()
server_connection.terminate()
if not configParams.remote_server:
# we start a server with a given configuration
server = start_server(servermodule, configParams, configuration, featureset)
bb.event.ui_queue = []
logger.info("Terminated bitbake server.")
return None, None
else:
# we start a stub server that is actually a XMLRPClient that connects to a real server
server = servermodule.BitBakeXMLRPCClient(configParams.observe_only, configParams.xmlrpctoken)
server.saveConnectionDetails(configParams.remote_server)
# Restore the environment in case the UI needs it
for k in cleanedvars:
os.environ[k] = cleanedvars[k]
logger.removeHandler(handler)
if not configParams.server_only:
try:
server_connection = server.establishConnection(featureset)
except Exception as e:
if configParams.kill_server:
return 0
bb.fatal("Could not connect to server %s: %s" % (configParams.remote_server, str(e)))
return server_connection, ui_module
# Restore the environment in case the UI needs it
for k in cleanedvars:
os.environ[k] = cleanedvars[k]
def lockBitbake():
topdir = bb.cookerdata.findTopdir()
if not topdir:
bb.error("Unable to find conf/bblayers.conf or conf/bitbake.conf. BBAPTH is unset and/or not in a build directory?")
raise BBMainFatal
lockfile = topdir + "/bitbake.lock"
return topdir, bb.utils.lockfile(lockfile, False, False)
logger.removeHandler(handler)
if configParams.status_only:
server_connection.terminate()
return 0
if configParams.kill_server:
server_connection.connection.terminateServer()
bb.event.ui_queue = []
return 0
try:
return ui_module.main(server_connection.connection, server_connection.events, configParams)
finally:
bb.event.ui_queue = []
server_connection.terminate()
else:
print("Bitbake server address: %s, server port: %s" % (server.serverImpl.host, server.serverImpl.port))
return 0
return 1

View File

@@ -19,22 +19,11 @@
from bb.utils import better_compile, better_exec
def insert_method(modulename, code, fn, lineno):
def insert_method(modulename, code, fn):
"""
Add code of a module should be added. The methods
will be simply added, no checking will be done
"""
comp = better_compile(code, modulename, fn, lineno=lineno)
comp = better_compile(code, modulename, fn )
better_exec(comp, None, code, fn)
compilecache = {}
def compile_cache(code):
h = hash(code)
if h in compilecache:
return compilecache[h]
return None
def compile_cache_add(code, compileobj):
h = hash(code)
compilecache[h] = compileobj

View File

@@ -129,7 +129,7 @@ def getDiskData(BBDirs, configuration):
bb.utils.mkdirhier(path)
dev = getMountedDev(path)
# Use path/action as the key
devDict[(path, action)] = [dev, minSpace, minInode]
devDict[os.path.join(path, action)] = [dev, minSpace, minInode]
return devDict
@@ -141,7 +141,7 @@ def getInterval(configuration):
spaceDefault = 50 * 1024 * 1024
inodeDefault = 5 * 1024
interval = configuration.getVar("BB_DISKMON_WARNINTERVAL")
interval = configuration.getVar("BB_DISKMON_WARNINTERVAL", True)
if not interval:
return spaceDefault, inodeDefault
else:
@@ -179,7 +179,7 @@ class diskMonitor:
self.enableMonitor = False
self.configuration = configuration
BBDirs = configuration.getVar("BB_DISKMON_DIRS") or None
BBDirs = configuration.getVar("BB_DISKMON_DIRS", True) or None
if BBDirs:
self.devDict = getDiskData(BBDirs, configuration)
if self.devDict:
@@ -205,25 +205,22 @@ class diskMonitor:
""" Take action for the monitor """
if self.enableMonitor:
diskUsage = {}
for k, attributes in self.devDict.items():
path, action = k
dev, minSpace, minInode = attributes
for k in self.devDict:
path = os.path.dirname(k)
action = os.path.basename(k)
dev = self.devDict[k][0]
minSpace = self.devDict[k][1]
minInode = self.devDict[k][2]
st = os.statvfs(path)
# The available free space, integer number
# The free space, float point number
freeSpace = st.f_bavail * st.f_frsize
# Send all relevant information in the event.
freeSpaceRoot = st.f_bfree * st.f_frsize
totalSpace = st.f_blocks * st.f_frsize
diskUsage[dev] = bb.event.DiskUsageSample(freeSpace, freeSpaceRoot, totalSpace)
if minSpace and freeSpace < minSpace:
# Always show warning, the self.checked would always be False if the action is WARN
if self.preFreeS[k] == 0 or self.preFreeS[k] - freeSpace > self.spaceInterval and not self.checked[k]:
logger.warning("The free space of %s (%s) is running low (%.3fGB left)" % \
logger.warn("The free space of %s (%s) is running low (%.3fGB left)" % \
(path, dev, freeSpace / 1024 / 1024 / 1024.0))
self.preFreeS[k] = freeSpace
@@ -238,7 +235,7 @@ class diskMonitor:
rq.finish_runqueue(True)
bb.event.fire(bb.event.DiskFull(dev, 'disk', freeSpace, path), self.configuration)
# The free inodes, integer number
# The free inodes, float point number
freeInode = st.f_favail
if minInode and freeInode < minInode:
@@ -249,7 +246,7 @@ class diskMonitor:
continue
# Always show warning, the self.checked would always be False if the action is WARN
if self.preFreeI[k] == 0 or self.preFreeI[k] - freeInode > self.inodeInterval and not self.checked[k]:
logger.warning("The free inode of %s (%s) is running low (%.3fK left)" % \
logger.warn("The free inode of %s (%s) is running low (%.3fK left)" % \
(path, dev, freeInode / 1024.0))
self.preFreeI[k] = freeInode
@@ -263,6 +260,4 @@ class diskMonitor:
self.checked[k] = True
rq.finish_runqueue(True)
bb.event.fire(bb.event.DiskFull(dev, 'inode', freeInode, path), self.configuration)
bb.event.fire(bb.event.MonitorDiskEvent(diskUsage), self.configuration)
return

View File

@@ -57,7 +57,7 @@ class BBLogFormatter(logging.Formatter):
}
color_enabled = False
BASECOLOR, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = list(range(29,38))
BASECOLOR, BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(29,38)
COLORS = {
DEBUG3 : CYAN,
@@ -90,9 +90,8 @@ class BBLogFormatter(logging.Formatter):
if self.color_enabled:
record = self.colorize(record)
msg = logging.Formatter.format(self, record)
if hasattr(record, 'bb_exc_formatted'):
msg += '\n' + ''.join(record.bb_exc_formatted)
elif hasattr(record, 'bb_exc_info'):
if hasattr(record, 'bb_exc_info'):
etype, value, tb = record.bb_exc_info
formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
msg += '\n' + ''.join(formatted)
@@ -151,7 +150,7 @@ loggerDefaultVerbose = False
loggerVerboseLogs = False
loggerDefaultDomains = []
def init_msgconfig(verbose, debug, debug_domains=None):
def init_msgconfig(verbose, debug, debug_domains = []):
"""
Set default verbosity and debug levels config the logger
"""
@@ -159,10 +158,7 @@ def init_msgconfig(verbose, debug, debug_domains=None):
bb.msg.loggerDefaultVerbose = verbose
if verbose:
bb.msg.loggerVerboseLogs = True
if debug_domains:
bb.msg.loggerDefaultDomains = debug_domains
else:
bb.msg.loggerDefaultDomains = []
bb.msg.loggerDefaultDomains = debug_domains
def constructLogOptions():
debug = loggerDefaultDebugLevel
@@ -182,12 +178,9 @@ def constructLogOptions():
debug_domains["BitBake.%s" % domainarg] = logging.DEBUG - dlevel + 1
return level, debug_domains
def addDefaultlogFilter(handler, cls = BBLogFilter, forcelevel=None):
def addDefaultlogFilter(handler, cls = BBLogFilter):
level, debug_domains = constructLogOptions()
if forcelevel is not None:
level = forcelevel
cls(handler, level, debug_domains)
#
@@ -201,25 +194,3 @@ def fatal(msgdomain, msg):
logger = logging.getLogger("BitBake")
logger.critical(msg)
sys.exit(1)
def logger_create(name, output=sys.stderr, level=logging.INFO, preserve_handlers=False, color='auto'):
"""Standalone logger creation function"""
logger = logging.getLogger(name)
console = logging.StreamHandler(output)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
if color == 'always' or (color == 'auto' and output.isatty()):
format.enable_color()
console.setFormatter(format)
if preserve_handlers:
logger.addHandler(console)
else:
logger.handlers = [console]
logger.setLevel(level)
return logger
def has_console_handler(logger):
for handler in logger.handlers:
if isinstance(handler, logging.StreamHandler):
if handler.stream in [sys.stderr, sys.stdout]:
return True
return False

View File

@@ -26,10 +26,9 @@ File parsers for the BitBake build tools.
handlers = []
import errno
import logging
import os
import stat
import logging
import bb
import bb.utils
import bb.siggen
@@ -71,12 +70,7 @@ def cached_mtime_noerror(f):
return __mtime_cache[f]
def update_mtime(f):
try:
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
except OSError:
if f in __mtime_cache:
del __mtime_cache[f]
return 0
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
return __mtime_cache[f]
def update_cache(f):
@@ -84,14 +78,10 @@ def update_cache(f):
logger.debug(1, "Updating mtime cache for %s" % f)
update_mtime(f)
def clear_cache():
global __mtime_cache
__mtime_cache = {}
def mark_dependency(d, f):
if f.startswith('./'):
f = "%s/%s" % (os.getcwd(), f[2:])
deps = (d.getVar('__depends', False) or [])
deps = (d.getVar('__depends') or [])
s = (f, cached_mtime_noerror(f))
if s not in deps:
deps.append(s)
@@ -99,7 +89,7 @@ def mark_dependency(d, f):
def check_dependency(d, f):
s = (f, cached_mtime_noerror(f))
deps = (d.getVar('__depends', False) or [])
deps = (d.getVar('__depends') or [])
return s in deps
def supports(fn, data):
@@ -127,18 +117,17 @@ def init_parser(d):
def resolve_file(fn, d):
if not os.path.isabs(fn):
bbpath = d.getVar("BBPATH")
bbpath = d.getVar("BBPATH", True)
newfn, attempts = bb.utils.which(bbpath, fn, history=True)
for af in attempts:
mark_dependency(d, af)
if not newfn:
raise IOError(errno.ENOENT, "file %s not found in %s" % (fn, bbpath))
raise IOError("file %s not found in %s" % (fn, bbpath))
fn = newfn
else:
mark_dependency(d, fn)
mark_dependency(d, fn)
if not os.path.isfile(fn):
raise IOError(errno.ENOENT, "file %s not found" % fn)
raise IOError("file %s not found" % fn)
return fn
@@ -166,8 +155,8 @@ def vars_from_file(mypkg, d):
def get_file_depends(d):
'''Return the dependent files'''
dep_files = []
depends = d.getVar('__base_depends', False) or []
depends = depends + (d.getVar('__depends', False) or [])
depends = d.getVar('__base_depends', True) or []
depends = depends + (d.getVar('__depends', True) or [])
for (fn, _) in depends:
dep_files.append(os.path.abspath(fn))
return " ".join(dep_files)

View File

@@ -21,7 +21,8 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from __future__ import absolute_import
from future_builtins import filter
import re
import string
import logging
@@ -30,6 +31,8 @@ import itertools
from bb import methodpool
from bb.parse import logger
_bbversions_re = re.compile(r"\[(?P<from>[0-9]+)-(?P<to>[0-9]+)\]")
class StatementGroup(list):
def eval(self, data):
for statement in self:
@@ -67,33 +70,6 @@ class ExportNode(AstNode):
def eval(self, data):
data.setVarFlag(self.var, "export", 1, op = 'exported')
class UnsetNode(AstNode):
def __init__(self, filename, lineno, var):
AstNode.__init__(self, filename, lineno)
self.var = var
def eval(self, data):
loginfo = {
'variable': self.var,
'file': self.filename,
'line': self.lineno,
}
data.delVar(self.var,**loginfo)
class UnsetFlagNode(AstNode):
def __init__(self, filename, lineno, var, flag):
AstNode.__init__(self, filename, lineno)
self.var = var
self.flag = flag
def eval(self, data):
loginfo = {
'variable': self.var,
'file': self.filename,
'line': self.lineno,
}
data.delVarFlag(self.var, self.flag, **loginfo)
class DataNode(AstNode):
"""
Various data related updates. For the sake of sanity
@@ -107,9 +83,9 @@ class DataNode(AstNode):
def getFunc(self, key, data):
if 'flag' in self.groupd and self.groupd['flag'] != None:
return data.getVarFlag(key, self.groupd['flag'], expand=False, noweakdefault=True)
return data.getVarFlag(key, self.groupd['flag'], noweakdefault=True)
else:
return data.getVar(key, False, noweakdefault=True, parsing=True)
return data.getVar(key, noweakdefault=True)
def eval(self, data):
groupd = self.groupd
@@ -130,6 +106,7 @@ class DataNode(AstNode):
val = groupd["value"]
elif "colon" in groupd and groupd["colon"] != None:
e = data.createCopy()
bb.data.update_data(e)
op = "immediate"
val = e.expand(groupd["value"], key + "[:=]")
elif "append" in groupd and groupd["append"] != None:
@@ -159,42 +136,29 @@ class DataNode(AstNode):
if flag:
data.setVarFlag(key, flag, val, **loginfo)
else:
data.setVar(key, val, parsing=True, **loginfo)
data.setVar(key, val, **loginfo)
class MethodNode(AstNode):
tr_tbl = str.maketrans('/.+-@%&', '_______')
tr_tbl = string.maketrans('/.+-@%&', '_______')
def __init__(self, filename, lineno, func_name, body, python, fakeroot):
def __init__(self, filename, lineno, func_name, body):
AstNode.__init__(self, filename, lineno)
self.func_name = func_name
self.body = body
self.python = python
self.fakeroot = fakeroot
def eval(self, data):
text = '\n'.join(self.body)
funcname = self.func_name
if self.func_name == "__anonymous":
funcname = ("__anon_%s_%s" % (self.lineno, self.filename.translate(MethodNode.tr_tbl)))
self.python = True
text = "def %s(d):\n" % (funcname) + text
bb.methodpool.insert_method(funcname, text, self.filename, self.lineno - len(self.body))
anonfuncs = data.getVar('__BBANONFUNCS', False) or []
bb.methodpool.insert_method(funcname, text, self.filename)
anonfuncs = data.getVar('__BBANONFUNCS') or []
anonfuncs.append(funcname)
data.setVar('__BBANONFUNCS', anonfuncs)
if data.getVar(funcname, False):
# clean up old version of this piece of metadata, as its
# flags could cause problems
data.delVarFlag(funcname, 'python')
data.delVarFlag(funcname, 'fakeroot')
if self.python:
data.setVarFlag(funcname, "python", "1")
if self.fakeroot:
data.setVarFlag(funcname, "fakeroot", "1")
data.setVarFlag(funcname, "func", 1)
data.setVar(funcname, text, parsing=True)
data.setVarFlag(funcname, 'filename', self.filename)
data.setVarFlag(funcname, 'lineno', str(self.lineno - len(self.body)))
data.setVar(funcname, text)
else:
data.setVarFlag(self.func_name, "func", 1)
data.setVar(self.func_name, text)
class PythonMethodNode(AstNode):
def __init__(self, filename, lineno, function, modulename, body):
@@ -208,12 +172,31 @@ class PythonMethodNode(AstNode):
# 'this' file. This means we will not parse methods from
# bb classes twice
text = '\n'.join(self.body)
bb.methodpool.insert_method(self.modulename, text, self.filename, self.lineno - len(self.body) - 1)
bb.methodpool.insert_method(self.modulename, text, self.filename)
data.setVarFlag(self.function, "func", 1)
data.setVarFlag(self.function, "python", 1)
data.setVar(self.function, text, parsing=True)
data.setVarFlag(self.function, 'filename', self.filename)
data.setVarFlag(self.function, 'lineno', str(self.lineno - len(self.body) - 1))
data.setVar(self.function, text)
class MethodFlagsNode(AstNode):
def __init__(self, filename, lineno, key, m):
AstNode.__init__(self, filename, lineno)
self.key = key
self.m = m
def eval(self, data):
if data.getVar(self.key):
# clean up old version of this piece of metadata, as its
# flags could cause problems
data.setVarFlag(self.key, 'python', None)
data.setVarFlag(self.key, 'fakeroot', None)
if self.m.group("py") is not None:
data.setVarFlag(self.key, "python", "1")
else:
data.delVarFlag(self.key, "python")
if self.m.group("fr") is not None:
data.setVarFlag(self.key, "fakeroot", "1")
else:
data.delVarFlag(self.key, "fakeroot")
class ExportFuncsNode(AstNode):
def __init__(self, filename, lineno, fns, classname):
@@ -226,28 +209,26 @@ class ExportFuncsNode(AstNode):
for func in self.n:
calledfunc = self.classname + "_" + func
if data.getVar(func, False) and not data.getVarFlag(func, 'export_func', False):
if data.getVar(func) and not data.getVarFlag(func, 'export_func'):
continue
if data.getVar(func, False):
if data.getVar(func):
data.setVarFlag(func, 'python', None)
data.setVarFlag(func, 'func', None)
for flag in [ "func", "python" ]:
if data.getVarFlag(calledfunc, flag, False):
data.setVarFlag(func, flag, data.getVarFlag(calledfunc, flag, False))
if data.getVarFlag(calledfunc, flag):
data.setVarFlag(func, flag, data.getVarFlag(calledfunc, flag))
for flag in [ "dirs" ]:
if data.getVarFlag(func, flag, False):
data.setVarFlag(calledfunc, flag, data.getVarFlag(func, flag, False))
data.setVarFlag(func, "filename", "autogenerated")
data.setVarFlag(func, "lineno", 1)
if data.getVarFlag(func, flag):
data.setVarFlag(calledfunc, flag, data.getVarFlag(func, flag))
if data.getVarFlag(calledfunc, "python", False):
data.setVar(func, " bb.build.exec_func('" + calledfunc + "', d)\n", parsing=True)
if data.getVarFlag(calledfunc, "python"):
data.setVar(func, " bb.build.exec_func('" + calledfunc + "', d)\n")
else:
if "-" in self.classname:
bb.fatal("The classname %s contains a dash character and is calling an sh function %s using EXPORT_FUNCTIONS. Since a dash is illegal in sh function names, this cannot work, please rename the class or don't use EXPORT_FUNCTIONS." % (self.classname, calledfunc))
data.setVar(func, " " + calledfunc + "\n", parsing=True)
data.setVar(func, " " + calledfunc + "\n")
data.setVarFlag(func, 'export_func', '1')
class AddTaskNode(AstNode):
@@ -274,7 +255,7 @@ class BBHandlerNode(AstNode):
self.hs = fns.split()
def eval(self, data):
bbhands = data.getVar('__BBHANDLERS', False) or []
bbhands = data.getVar('__BBHANDLERS') or []
for h in self.hs:
bbhands.append(h)
data.setVarFlag(h, "handler", 1)
@@ -294,21 +275,18 @@ def handleInclude(statements, filename, lineno, m, force):
def handleExport(statements, filename, lineno, m):
statements.append(ExportNode(filename, lineno, m.group(1)))
def handleUnset(statements, filename, lineno, m):
statements.append(UnsetNode(filename, lineno, m.group(1)))
def handleUnsetFlag(statements, filename, lineno, m):
statements.append(UnsetFlagNode(filename, lineno, m.group(1), m.group(2)))
def handleData(statements, filename, lineno, groupd):
statements.append(DataNode(filename, lineno, groupd))
def handleMethod(statements, filename, lineno, func_name, body, python, fakeroot):
statements.append(MethodNode(filename, lineno, func_name, body, python, fakeroot))
def handleMethod(statements, filename, lineno, func_name, body):
statements.append(MethodNode(filename, lineno, func_name, body))
def handlePythonMethod(statements, filename, lineno, funcname, modulename, body):
statements.append(PythonMethodNode(filename, lineno, funcname, modulename, body))
def handleMethodFlags(statements, filename, lineno, key, m):
statements.append(MethodFlagsNode(filename, lineno, key, m))
def handleExportFuncs(statements, filename, lineno, m, classname):
statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname))
@@ -335,38 +313,31 @@ def handleInherit(statements, filename, lineno, m):
classes = m.group(1)
statements.append(InheritNode(filename, lineno, classes))
def runAnonFuncs(d):
code = []
for funcname in d.getVar("__BBANONFUNCS", False) or []:
code.append("%s(d)" % funcname)
bb.utils.better_exec("\n".join(code), {"d": d})
def finalize(fn, d, variant = None):
saved_handlers = bb.event.get_handlers().copy()
for var in d.getVar('__BBHANDLERS', False) or []:
all_handlers = {}
for var in d.getVar('__BBHANDLERS') or []:
# try to add the handler
handlerfn = d.getVarFlag(var, "filename", False)
if not handlerfn:
bb.fatal("Undefined event handler function '%s'" % var)
handlerln = int(d.getVarFlag(var, "lineno", False))
bb.event.register(var, d.getVar(var, False), (d.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln)
bb.event.register(var, d.getVar(var), (d.getVarFlag(var, "eventmask", True) or "").split())
bb.event.fire(bb.event.RecipePreFinalise(fn), d)
bb.data.expandKeys(d)
runAnonFuncs(d)
bb.data.update_data(d)
code = []
for funcname in d.getVar("__BBANONFUNCS") or []:
code.append("%s(d)" % funcname)
bb.utils.better_exec("\n".join(code), {"d": d})
bb.data.update_data(d)
tasklist = d.getVar('__BBTASKS', False) or []
bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
bb.build.add_tasks(tasklist, d)
tasklist = d.getVar('__BBTASKS') or []
deltasklist = d.getVar('__BBDELTASKS') or []
bb.build.add_tasks(tasklist, deltasklist, d)
bb.parse.siggen.finalise(fn, d, variant)
d.setVar('BBINCLUDED', bb.parse.get_file_depends(d))
bb.event.fire(bb.event.RecipeParsed(fn), d)
bb.event.set_handlers(saved_handlers)
def _create_variants(datastores, names, function, onlyfinalise):
def create_variant(name, orig_d, arg = None):
@@ -376,16 +347,37 @@ def _create_variants(datastores, names, function, onlyfinalise):
function(arg or name, new_d)
datastores[name] = new_d
for variant in list(datastores.keys()):
for variant, variant_d in datastores.items():
for name in names:
if not variant:
# Based on main recipe
create_variant(name, datastores[""])
create_variant(name, variant_d)
else:
create_variant("%s-%s" % (variant, name), datastores[variant], name)
create_variant("%s-%s" % (variant, name), variant_d, name)
def _expand_versions(versions):
def expand_one(version, start, end):
for i in xrange(start, end + 1):
ver = _bbversions_re.sub(str(i), version, 1)
yield ver
versions = iter(versions)
while True:
try:
version = next(versions)
except StopIteration:
break
range_ver = _bbversions_re.search(version)
if not range_ver:
yield version
else:
newversions = expand_one(version, int(range_ver.group("from")),
int(range_ver.group("to")))
versions = itertools.chain(newversions, versions)
def multi_finalize(fn, d):
appends = (d.getVar("__BBAPPEND") or "").split()
appends = (d.getVar("__BBAPPEND", True) or "").split()
for append in appends:
logger.debug(1, "Appending .bbappend file %s to %s", append, fn)
bb.parse.BBHandler.handle(append, d, True)
@@ -400,7 +392,51 @@ def multi_finalize(fn, d):
d.setVar("__SKIPPED", e.args[0])
datastores = {"": safe_d}
extended = d.getVar("BBCLASSEXTEND") or ""
versions = (d.getVar("BBVERSIONS", True) or "").split()
if versions:
pv = orig_pv = d.getVar("PV", True)
baseversions = {}
def verfunc(ver, d, pv_d = None):
if pv_d is None:
pv_d = d
overrides = d.getVar("OVERRIDES", True).split(":")
pv_d.setVar("PV", ver)
overrides.append(ver)
bpv = baseversions.get(ver) or orig_pv
pv_d.setVar("BPV", bpv)
overrides.append(bpv)
d.setVar("OVERRIDES", ":".join(overrides))
versions = list(_expand_versions(versions))
for pos, version in enumerate(list(versions)):
try:
pv, bpv = version.split(":", 2)
except ValueError:
pass
else:
versions[pos] = pv
baseversions[pv] = bpv
if pv in versions and not baseversions.get(pv):
versions.remove(pv)
else:
pv = versions.pop()
# This is necessary because our existing main datastore
# has already been finalized with the old PV, we need one
# that's been finalized with the new PV.
d = bb.data.createCopy(safe_d)
verfunc(pv, d, safe_d)
try:
finalize(fn, d)
except bb.parse.SkipRecipe as e:
d.setVar("__SKIPPED", e.args[0])
_create_variants(datastores, versions, verfunc, onlyfinalise)
extended = d.getVar("BBCLASSEXTEND", True) or ""
if extended:
# the following is to support bbextends with arguments, for e.g. multilib
# an example is as follows:
@@ -418,7 +454,7 @@ def multi_finalize(fn, d):
else:
extendedmap[ext] = ext
pn = d.getVar("PN")
pn = d.getVar("PN", True)
def extendfunc(name, d):
if name != extendedmap[name]:
d.setVar("BBEXTENDCURR", extendedmap[name])
@@ -430,13 +466,17 @@ def multi_finalize(fn, d):
safe_d.setVar("BBCLASSEXTEND", extended)
_create_variants(datastores, extendedmap.keys(), extendfunc, onlyfinalise)
for variant in datastores.keys():
for variant, variant_d in datastores.iteritems():
if variant:
try:
if not onlyfinalise or variant in onlyfinalise:
finalize(fn, datastores[variant], variant)
finalize(fn, variant_d, variant)
except bb.parse.SkipRecipe as e:
datastores[variant].setVar("__SKIPPED", e.args[0])
variant_d.setVar("__SKIPPED", e.args[0])
if len(datastores) > 1:
variants = filter(None, datastores.iterkeys())
safe_d.setVar("__VARIANTS", " ".join(variants))
datastores[""] = d
return datastores

View File

@@ -25,14 +25,14 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from __future__ import absolute_import
import re, bb, os
import logging
import bb.build, bb.utils
from bb import data
from . import ConfHandler
from .. import resolve_file, ast, logger, ParseError
from .. import resolve_file, ast, logger
from .ConfHandler import include, init
# For compatibility
@@ -47,26 +47,37 @@ __addhandler_regexp__ = re.compile( r"addhandler\s+(.+)" )
__def_regexp__ = re.compile( r"def\s+(\w+).*:" )
__python_func_regexp__ = re.compile( r"(\s+.*)|(^$)" )
__infunc__ = []
__infunc__ = ""
__inpython__ = False
__body__ = []
__classname__ = ""
cached_statements = {}
# We need to indicate EOF to the feeder. This code is so messy that
# factoring it out to a close_parse_file method is out of question.
# We will use the IN_PYTHON_EOF as an indicator to just close the method
#
# The two parts using it are tightly integrated anyway
IN_PYTHON_EOF = -9999999999999
def supports(fn, d):
"""Return True if fn has a supported extension"""
return os.path.splitext(fn)[-1] in [".bb", ".bbclass", ".inc"]
def inherit(files, fn, lineno, d):
__inherit_cache = d.getVar('__inherit_cache', False) or []
__inherit_cache = d.getVar('__inherit_cache') or []
files = d.expand(files).split()
for file in files:
if not os.path.isabs(file) and not file.endswith(".bbclass"):
file = os.path.join('classes', '%s.bbclass' % file)
if not os.path.isabs(file):
bbpath = d.getVar("BBPATH")
dname = os.path.dirname(fn)
bbpath = "%s:%s" % (dname, d.getVar("BBPATH", True))
abs_fn, attempts = bb.utils.which(bbpath, file, history=True)
for af in attempts:
if af != abs_fn:
@@ -79,7 +90,7 @@ def inherit(files, fn, lineno, d):
__inherit_cache.append( file )
d.setVar('__inherit_cache', __inherit_cache)
include(fn, file, lineno, d, "inherit")
__inherit_cache = d.getVar('__inherit_cache', False) or []
__inherit_cache = d.getVar('__inherit_cache') or []
def get_statements(filename, absolute_filename, base_name):
global cached_statements
@@ -87,20 +98,20 @@ def get_statements(filename, absolute_filename, base_name):
try:
return cached_statements[absolute_filename]
except KeyError:
with open(absolute_filename, 'r') as f:
statements = ast.StatementGroup()
lineno = 0
while True:
lineno = lineno + 1
s = f.readline()
if not s: break
s = s.rstrip()
feeder(lineno, s, filename, base_name, statements)
file = open(absolute_filename, 'r')
statements = ast.StatementGroup()
lineno = 0
while True:
lineno = lineno + 1
s = file.readline()
if not s: break
s = s.rstrip()
feeder(lineno, s, filename, base_name, statements)
file.close()
if __inpython__:
# add a blank line to close out any python definition
feeder(lineno, "", filename, base_name, statements, eof=True)
feeder(IN_PYTHON_EOF, "", filename, base_name, statements)
if filename.endswith(".bbclass") or filename.endswith(".inc"):
cached_statements[absolute_filename] = statements
@@ -109,7 +120,7 @@ def get_statements(filename, absolute_filename, base_name):
def handle(fn, d, include):
global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __infunc__, __body__, __residue__, __classname__
__body__ = []
__infunc__ = []
__infunc__ = ""
__classname__ = ""
__residue__ = []
@@ -119,52 +130,50 @@ def handle(fn, d, include):
if ext == ".bbclass":
__classname__ = root
__inherit_cache = d.getVar('__inherit_cache', False) or []
__inherit_cache = d.getVar('__inherit_cache') or []
if not fn in __inherit_cache:
__inherit_cache.append(fn)
d.setVar('__inherit_cache', __inherit_cache)
if include != 0:
oldfile = d.getVar('FILE', False)
oldfile = d.getVar('FILE')
else:
oldfile = None
abs_fn = resolve_file(fn, d)
if include:
bb.parse.mark_dependency(d, abs_fn)
# actual loading
statements = get_statements(fn, abs_fn, base_name)
# DONE WITH PARSING... time to evaluate
if ext != ".bbclass" and abs_fn != oldfile:
if ext != ".bbclass":
d.setVar('FILE', abs_fn)
try:
statements.eval(d)
except bb.parse.SkipRecipe:
d.setVar("__SKIPPED", True)
bb.data.setVar("__SKIPPED", True, d)
if include == 0:
return { "" : d }
if __infunc__:
raise ParseError("Shell function %s is never closed" % __infunc__[0], __infunc__[1], __infunc__[2])
if __residue__:
raise ParseError("Leftover unparsed (incomplete?) data %s from %s" % __residue__, fn)
if ext != ".bbclass" and include == 0:
return ast.multi_finalize(fn, d)
if ext != ".bbclass" and oldfile and abs_fn != oldfile:
if oldfile:
d.setVar("FILE", oldfile)
return d
def feeder(lineno, s, fn, root, statements, eof=False):
def feeder(lineno, s, fn, root, statements):
global __func_start_regexp__, __inherit_regexp__, __export_func_regexp__, __addtask_regexp__, __addhandler_regexp__, __def_regexp__, __python_func_regexp__, __inpython__, __infunc__, __body__, bb, __residue__, __classname__
if __infunc__:
if s == '}':
__body__.append('')
ast.handleMethod(statements, fn, lineno, __infunc__[0], __body__, __infunc__[3], __infunc__[4])
__infunc__ = []
ast.handleMethod(statements, fn, lineno, __infunc__, __body__)
__infunc__ = ""
__body__ = []
else:
__body__.append(s)
@@ -172,7 +181,7 @@ def feeder(lineno, s, fn, root, statements, eof=False):
if __inpython__:
m = __python_func_regexp__.match(s)
if m and not eof:
if m and lineno != IN_PYTHON_EOF:
__body__.append(s)
return
else:
@@ -181,7 +190,7 @@ def feeder(lineno, s, fn, root, statements, eof=False):
__body__ = []
__inpython__ = False
if eof:
if lineno == IN_PYTHON_EOF:
return
if s and s[0] == '#':
@@ -208,7 +217,8 @@ def feeder(lineno, s, fn, root, statements, eof=False):
m = __func_start_regexp__.match(s)
if m:
__infunc__ = [m.group("func") or "__anonymous", fn, lineno, m.group("py") is not None, m.group("fr") is not None]
__infunc__ = m.group("func") or "__anonymous"
ast.handleMethodFlags(statements, fn, lineno, __infunc__, m)
return
m = __def_regexp__.match(s)

View File

@@ -24,16 +24,15 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import errno
import re
import os
import re, os
import logging
import bb.utils
from bb.parse import ParseError, resolve_file, ast, logger, handle
__config_regexp__ = re.compile( r"""
^
(?P<exp>export\s+)?
(?P<var>[a-zA-Z0-9\-_+.${}/~]+?)
(?P<exp>export\s*)?
(?P<var>[a-zA-Z0-9\-~_+.${}/]+?)
(\[(?P<flag>[a-zA-Z0-9\-_+.]+)\])?
\s* (
@@ -56,12 +55,10 @@ __config_regexp__ = re.compile( r"""
""", re.X)
__include_regexp__ = re.compile( r"include\s+(.+)" )
__require_regexp__ = re.compile( r"require\s+(.+)" )
__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
__unset_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)$" )
__unset_flag_regexp__ = re.compile( r"unset\s+([a-zA-Z0-9\-_+.${}/~]+)\[([a-zA-Z0-9\-_+.]+)\]$" )
__export_regexp__ = re.compile( r"export\s+([a-zA-Z0-9\-_+.${}/]+)$" )
def init(data):
topdir = data.getVar('TOPDIR', False)
topdir = data.getVar('TOPDIR')
if not topdir:
data.setVar('TOPDIR', os.getcwd())
@@ -69,51 +66,38 @@ def init(data):
def supports(fn, d):
return fn[-5:] == ".conf"
def include(parentfn, fns, lineno, data, error_out):
def include(parentfn, fn, lineno, data, error_out):
"""
error_out: A string indicating the verb (e.g. "include", "inherit") to be
used in a ParseError that will be raised if the file to be included could
not be included. Specify False to avoid raising an error in this case.
"""
fns = data.expand(fns)
parentfn = data.expand(parentfn)
# "include" or "require" accept zero to n space-separated file names to include.
for fn in fns.split():
include_single_file(parentfn, fn, lineno, data, error_out)
def include_single_file(parentfn, fn, lineno, data, error_out):
"""
Helper function for include() which does not expand or split its parameters.
"""
if parentfn == fn: # prevent infinite recursion
return None
fn = data.expand(fn)
parentfn = data.expand(parentfn)
if not os.path.isabs(fn):
dname = os.path.dirname(parentfn)
bbpath = "%s:%s" % (dname, data.getVar("BBPATH"))
bbpath = "%s:%s" % (dname, data.getVar("BBPATH", True))
abs_fn, attempts = bb.utils.which(bbpath, fn, history=True)
if abs_fn and bb.parse.check_dependency(data, abs_fn):
logger.warning("Duplicate inclusion for %s in %s" % (abs_fn, data.getVar('FILE')))
logger.warn("Duplicate inclusion for %s in %s" % (abs_fn, data.getVar('FILE', True)))
for af in attempts:
bb.parse.mark_dependency(data, af)
if abs_fn:
fn = abs_fn
elif bb.parse.check_dependency(data, fn):
logger.warning("Duplicate inclusion for %s in %s" % (fn, data.getVar('FILE')))
logger.warn("Duplicate inclusion for %s in %s" % (fn, data.getVar('FILE', True)))
try:
bb.parse.handle(fn, data, True)
except (IOError, OSError) as exc:
if exc.errno == errno.ENOENT:
if error_out:
raise ParseError("Could not %s file %s" % (error_out, fn), parentfn, lineno)
logger.debug(2, "CONF file '%s' not found", fn)
else:
if error_out:
raise ParseError("Could not %s file %s: %s" % (error_out, fn, exc.strerror), parentfn, lineno)
else:
raise ParseError("Error parsing %s: %s" % (fn, exc.strerror), parentfn, lineno)
ret = bb.parse.handle(fn, data, True)
except (IOError, OSError):
if error_out:
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), parentfn, lineno)
logger.debug(2, "CONF file '%s' not found", fn)
bb.parse.mark_dependency(data, fn)
# We have an issue where a UI might want to enforce particular settings such as
# an empty DISTRO variable. If configuration files do something like assigning
@@ -129,11 +113,14 @@ def handle(fn, data, include):
if include == 0:
oldfile = None
else:
oldfile = data.getVar('FILE', False)
oldfile = data.getVar('FILE')
abs_fn = resolve_file(fn, data)
f = open(abs_fn, 'r')
if include:
bb.parse.mark_dependency(data, abs_fn)
statements = ast.StatementGroup()
lineno = 0
while True:
@@ -192,16 +179,6 @@ def feeder(lineno, s, fn, statements):
ast.handleExport(statements, fn, lineno, m)
return
m = __unset_regexp__.match(s)
if m:
ast.handleUnset(statements, fn, lineno, m)
return
m = __unset_flag_regexp__.match(s)
if m:
ast.handleUnsetFlag(statements, fn, lineno, m)
return
raise ParseError("unparsed line: '%s'" % s, fn, lineno);
# Add us to the handlers list

View File

@@ -28,7 +28,11 @@ import sys
import warnings
from bb.compat import total_ordering
from collections import Mapping
import sqlite3
try:
import sqlite3
except ImportError:
from pysqlite2 import dbapi2 as sqlite3
sqlversion = sqlite3.sqlite_version_info
if sqlversion[0] < 3 or (sqlversion[0] == 3 and sqlversion[1] < 3):
@@ -88,9 +92,9 @@ class SQLTable(collections.MutableMapping):
self._execute("DELETE from %s where key=?;" % self.table, [key])
def __setitem__(self, key, value):
if not isinstance(key, str):
if not isinstance(key, basestring):
raise TypeError('Only string keys are supported')
elif not isinstance(value, str):
elif not isinstance(value, basestring):
raise TypeError('Only string values are supported')
data = self._execute("SELECT * from %s where key=?;" %
@@ -174,7 +178,7 @@ class PersistData(object):
"""
Return a list of key + value pairs for a domain
"""
return list(self.data[domain].items())
return self.data[domain].items()
def getValue(self, domain, key):
"""
@@ -197,14 +201,13 @@ class PersistData(object):
def connect(database):
connection = sqlite3.connect(database, timeout=5, isolation_level=None)
connection.execute("pragma synchronous = off;")
connection.text_factory = str
return connection
def persist(domain, d):
"""Convenience factory for SQLTable objects based upon metadata"""
import bb.utils
cachedir = (d.getVar("PERSISTENT_DIR") or
d.getVar("CACHE"))
cachedir = (d.getVar("PERSISTENT_DIR", True) or
d.getVar("CACHE", True))
if not cachedir:
logger.critical("Please set the 'PERSISTENT_DIR' or 'CACHE' variable")
sys.exit(1)

View File

@@ -17,7 +17,7 @@ class CmdError(RuntimeError):
self.msg = msg
def __str__(self):
if not isinstance(self.command, str):
if not isinstance(self.command, basestring):
cmd = subprocess.list2cmdline(self.command)
else:
cmd = self.command
@@ -64,7 +64,7 @@ class Popen(subprocess.Popen):
options.update(kwargs)
subprocess.Popen.__init__(self, *args, **options)
def _logged_communicate(pipe, log, input, extrafiles):
def _logged_communicate(pipe, log, input):
if pipe.stdin:
if input is not None:
pipe.stdin.write(input)
@@ -79,82 +79,40 @@ def _logged_communicate(pipe, log, input, extrafiles):
if pipe.stderr is not None:
bb.utils.nonblockingfd(pipe.stderr.fileno())
rin.append(pipe.stderr)
for fobj, _ in extrafiles:
bb.utils.nonblockingfd(fobj.fileno())
rin.append(fobj)
def readextras(selected):
for fobj, func in extrafiles:
if fobj in selected:
try:
data = fobj.read()
except IOError as err:
if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
data = None
if data is not None:
func(data)
def read_all_pipes(log, rin, outdata, errdata):
rlist = rin
stdoutbuf = b""
stderrbuf = b""
try:
r,w,e = select.select (rlist, [], [], 1)
except OSError as e:
if e.errno != errno.EINTR:
raise
readextras(r)
if pipe.stdout in r:
data = stdoutbuf + pipe.stdout.read()
if data is not None and len(data) > 0:
try:
data = data.decode("utf-8")
outdata.append(data)
log.write(data)
log.flush()
stdoutbuf = b""
except UnicodeDecodeError:
stdoutbuf = data
if pipe.stderr in r:
data = stderrbuf + pipe.stderr.read()
if data is not None and len(data) > 0:
try:
data = data.decode("utf-8")
errdata.append(data)
log.write(data)
log.flush()
stderrbuf = b""
except UnicodeDecodeError:
stderrbuf = data
try:
# Read all pipes while the process is open
while pipe.poll() is None:
read_all_pipes(log, rin, outdata, errdata)
rlist = rin
try:
r,w,e = select.select (rlist, [], [], 1)
except OSError as e:
if e.errno != errno.EINTR:
raise
# Pocess closed, drain all pipes...
read_all_pipes(log, rin, outdata, errdata)
finally:
if pipe.stdout in r:
data = pipe.stdout.read()
if data is not None:
outdata.append(data)
log.write(data)
if pipe.stderr in r:
data = pipe.stderr.read()
if data is not None:
errdata.append(data)
log.write(data)
finally:
log.flush()
if pipe.stdout is not None:
pipe.stdout.close()
if pipe.stderr is not None:
pipe.stderr.close()
return ''.join(outdata), ''.join(errdata)
def run(cmd, input=None, log=None, extrafiles=None, **options):
def run(cmd, input=None, log=None, **options):
"""Convenience function to run a command and return its output, raising an
exception when the command fails"""
if not extrafiles:
extrafiles = []
if isinstance(cmd, str) and not "shell" in options:
if isinstance(cmd, basestring) and not "shell" in options:
options["shell"] = True
try:
@@ -166,13 +124,9 @@ def run(cmd, input=None, log=None, extrafiles=None, **options):
raise CmdError(cmd, exc)
if log:
stdout, stderr = _logged_communicate(pipe, log, input, extrafiles)
stdout, stderr = _logged_communicate(pipe, log, input)
else:
stdout, stderr = pipe.communicate(input)
if not stdout is None:
stdout = stdout.decode("utf-8")
if not stderr is None:
stderr = stderr.decode("utf-8")
if pipe.returncode != 0:
raise ExecutionError(cmd, pipe.returncode, stdout, stderr)

View File

@@ -1,276 +0,0 @@
"""
BitBake progress handling code
"""
# Copyright (C) 2016 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import sys
import re
import time
import inspect
import bb.event
import bb.build
class ProgressHandler(object):
"""
Base class that can pretend to be a file object well enough to be
used to build objects to intercept console output and determine the
progress of some operation.
"""
def __init__(self, d, outfile=None):
self._progress = 0
self._data = d
self._lastevent = 0
if outfile:
self._outfile = outfile
else:
self._outfile = sys.stdout
def _fire_progress(self, taskprogress, rate=None):
"""Internal function to fire the progress event"""
bb.event.fire(bb.build.TaskProgress(taskprogress, rate), self._data)
def write(self, string):
self._outfile.write(string)
def flush(self):
self._outfile.flush()
def update(self, progress, rate=None):
ts = time.time()
if progress > 100:
progress = 100
if progress != self._progress or self._lastevent + 1 < ts:
self._fire_progress(progress, rate)
self._lastevent = ts
self._progress = progress
class LineFilterProgressHandler(ProgressHandler):
"""
A ProgressHandler variant that provides the ability to filter out
the lines if they contain progress information. Additionally, it
filters out anything before the last line feed on a line. This can
be used to keep the logs clean of output that we've only enabled for
getting progress, assuming that that can be done on a per-line
basis.
"""
def __init__(self, d, outfile=None):
self._linebuffer = ''
super(LineFilterProgressHandler, self).__init__(d, outfile)
def write(self, string):
self._linebuffer += string
while True:
breakpos = self._linebuffer.find('\n') + 1
if breakpos == 0:
break
line = self._linebuffer[:breakpos]
self._linebuffer = self._linebuffer[breakpos:]
# Drop any line feeds and anything that precedes them
lbreakpos = line.rfind('\r') + 1
if lbreakpos:
line = line[lbreakpos:]
if self.writeline(line):
super(LineFilterProgressHandler, self).write(line)
def writeline(self, line):
return True
class BasicProgressHandler(ProgressHandler):
def __init__(self, d, regex=r'(\d+)%', outfile=None):
super(BasicProgressHandler, self).__init__(d, outfile)
self._regex = re.compile(regex)
# Send an initial progress event so the bar gets shown
self._fire_progress(0)
def write(self, string):
percs = self._regex.findall(string)
if percs:
progress = int(percs[-1])
self.update(progress)
super(BasicProgressHandler, self).write(string)
class OutOfProgressHandler(ProgressHandler):
def __init__(self, d, regex, outfile=None):
super(OutOfProgressHandler, self).__init__(d, outfile)
self._regex = re.compile(regex)
# Send an initial progress event so the bar gets shown
self._fire_progress(0)
def write(self, string):
nums = self._regex.findall(string)
if nums:
progress = (float(nums[-1][0]) / float(nums[-1][1])) * 100
self.update(progress)
super(OutOfProgressHandler, self).write(string)
class MultiStageProgressReporter(object):
"""
Class which allows reporting progress without the caller
having to know where they are in the overall sequence. Useful
for tasks made up of python code spread across multiple
classes / functions - the progress reporter object can
be passed around or stored at the object level and calls
to next_stage() and update() made whereever needed.
"""
def __init__(self, d, stage_weights, debug=False):
"""
Initialise the progress reporter.
Parameters:
* d: the datastore (needed for firing the events)
* stage_weights: a list of weight values, one for each stage.
The value is scaled internally so you only need to specify
values relative to other values in the list, so if there
are two stages and the first takes 2s and the second takes
10s you would specify [2, 10] (or [1, 5], it doesn't matter).
* debug: specify True (and ensure you call finish() at the end)
in order to show a printout of the calculated stage weights
based on timing each stage. Use this to determine what the
weights should be when you're not sure.
"""
self._data = d
total = sum(stage_weights)
self._stage_weights = [float(x)/total for x in stage_weights]
self._stage = -1
self._base_progress = 0
# Send an initial progress event so the bar gets shown
self._fire_progress(0)
self._debug = debug
self._finished = False
if self._debug:
self._last_time = time.time()
self._stage_times = []
self._stage_total = None
self._callers = []
def _fire_progress(self, taskprogress):
bb.event.fire(bb.build.TaskProgress(taskprogress), self._data)
def next_stage(self, stage_total=None):
"""
Move to the next stage.
Parameters:
* stage_total: optional total for progress within the stage,
see update() for details
NOTE: you need to call this before the first stage.
"""
self._stage += 1
self._stage_total = stage_total
if self._stage == 0:
# First stage
if self._debug:
self._last_time = time.time()
else:
if self._stage < len(self._stage_weights):
self._base_progress = sum(self._stage_weights[:self._stage]) * 100
if self._debug:
currtime = time.time()
self._stage_times.append(currtime - self._last_time)
self._last_time = currtime
self._callers.append(inspect.getouterframes(inspect.currentframe())[1])
elif not self._debug:
bb.warn('ProgressReporter: current stage beyond declared number of stages')
self._base_progress = 100
self._fire_progress(self._base_progress)
def update(self, stage_progress):
"""
Update progress within the current stage.
Parameters:
* stage_progress: progress value within the stage. If stage_total
was specified when next_stage() was last called, then this
value is considered to be out of stage_total, otherwise it should
be a percentage value from 0 to 100.
"""
if self._stage_total:
stage_progress = (float(stage_progress) / self._stage_total) * 100
if self._stage < 0:
bb.warn('ProgressReporter: update called before first call to next_stage()')
elif self._stage < len(self._stage_weights):
progress = self._base_progress + (stage_progress * self._stage_weights[self._stage])
else:
progress = self._base_progress
if progress > 100:
progress = 100
self._fire_progress(progress)
def finish(self):
if self._finished:
return
self._finished = True
if self._debug:
import math
self._stage_times.append(time.time() - self._last_time)
mintime = max(min(self._stage_times), 0.01)
self._callers.append(None)
stage_weights = [int(math.ceil(x / mintime)) for x in self._stage_times]
bb.warn('Stage weights: %s' % stage_weights)
out = []
for stage_weight, caller in zip(stage_weights, self._callers):
if caller:
out.append('Up to %s:%d: %d' % (caller[1], caller[2], stage_weight))
else:
out.append('Up to finish: %d' % stage_weight)
bb.warn('Stage times:\n %s' % '\n '.join(out))
class MultiStageProcessProgressReporter(MultiStageProgressReporter):
"""
Version of MultiStageProgressReporter intended for use with
standalone processes (such as preparing the runqueue)
"""
def __init__(self, d, processname, stage_weights, debug=False):
self._processname = processname
self._started = False
MultiStageProgressReporter.__init__(self, d, stage_weights, debug)
def start(self):
if not self._started:
bb.event.fire(bb.event.ProcessStarted(self._processname, 100), self._data)
self._started = True
def _fire_progress(self, taskprogress):
if taskprogress == 0:
self.start()
return
bb.event.fire(bb.event.ProcessProgress(self._processname, taskprogress), self._data)
def finish(self):
MultiStageProgressReporter.finish(self)
bb.event.fire(bb.event.ProcessFinished(self._processname), self._data)
class DummyMultiStageProcessProgressReporter(MultiStageProgressReporter):
"""
MultiStageProcessProgressReporter that takes the calls and does nothing
with them (to avoid a bunch of "if progress_reporter:" checks)
"""
def __init__(self):
MultiStageProcessProgressReporter.__init__(self, "", None, [])
def _fire_progress(self, taskprogress, rate=None):
pass
def start(self):
pass
def next_stage(self, stage_total=None):
pass
def update(self, stage_progress):
pass
def finish(self):
pass

View File

@@ -48,6 +48,7 @@ def findProviders(cfgData, dataCache, pkg_pn = None):
# Need to ensure data store is expanded
localdata = data.createCopy(cfgData)
bb.data.update_data(localdata)
bb.data.expandKeys(localdata)
preferred_versions = {}
@@ -120,14 +121,11 @@ def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
preferred_file = None
preferred_ver = None
# pn can contain '_', e.g. gcc-cross-x86_64 and an override cannot
# hence we do this manually rather than use OVERRIDES
preferred_v = cfgData.getVar("PREFERRED_VERSION_pn-%s" % pn)
if not preferred_v:
preferred_v = cfgData.getVar("PREFERRED_VERSION_%s" % pn)
if not preferred_v:
preferred_v = cfgData.getVar("PREFERRED_VERSION")
localdata = data.createCopy(cfgData)
localdata.setVar('OVERRIDES', "%s:pn-%s:%s" % (data.getVar('OVERRIDES', localdata), pn, pn))
bb.data.update_data(localdata)
preferred_v = localdata.getVar('PREFERRED_VERSION', True)
if preferred_v:
m = re.match('(\d+:)*(.*)(_.*)*', preferred_v)
if m:
@@ -225,7 +223,7 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
def _filterProviders(providers, item, cfgData, dataCache):
"""
Take a list of providers and filter/reorder according to the
environment variables
environment variables and previous build results
"""
eligible = []
preferred_versions = {}
@@ -244,17 +242,17 @@ def _filterProviders(providers, item, cfgData, dataCache):
pkg_pn[pn] = []
pkg_pn[pn].append(p)
logger.debug(1, "providers for %s are: %s", item, list(sorted(pkg_pn.keys())))
logger.debug(1, "providers for %s are: %s", item, pkg_pn.keys())
# First add PREFERRED_VERSIONS
for pn in sorted(pkg_pn):
for pn in pkg_pn:
sortpkg_pn[pn] = sortPriorities(pn, dataCache, pkg_pn)
preferred_versions[pn] = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item)
if preferred_versions[pn][1]:
eligible.append(preferred_versions[pn][1])
# Now add latest versions
for pn in sorted(sortpkg_pn):
for pn in sortpkg_pn:
if pn in preferred_versions and preferred_versions[pn][1]:
continue
preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0])
@@ -282,13 +280,13 @@ def _filterProviders(providers, item, cfgData, dataCache):
def filterProviders(providers, item, cfgData, dataCache):
"""
Take a list of providers and filter/reorder according to the
environment variables
environment variables and previous build results
Takes a "normal" target item
"""
eligible = _filterProviders(providers, item, cfgData, dataCache)
prefervar = cfgData.getVar('PREFERRED_PROVIDER_%s' % item)
prefervar = cfgData.getVar('PREFERRED_PROVIDER_%s' % item, True)
if prefervar:
dataCache.preferred[item] = prefervar
@@ -310,56 +308,38 @@ def filterProviders(providers, item, cfgData, dataCache):
def filterProvidersRunTime(providers, item, cfgData, dataCache):
"""
Take a list of providers and filter/reorder according to the
environment variables
environment variables and previous build results
Takes a "runtime" target item
"""
eligible = _filterProviders(providers, item, cfgData, dataCache)
# First try and match any PREFERRED_RPROVIDER entry
prefervar = cfgData.getVar('PREFERRED_RPROVIDER_%s' % item)
foundUnique = False
if prefervar:
for p in eligible:
pn = dataCache.pkg_fn[p]
if prefervar == pn:
logger.verbose("selecting %s to satisfy %s due to PREFERRED_RPROVIDER", pn, item)
eligible.remove(p)
eligible = [p] + eligible
foundUnique = True
numberPreferred = 1
# Should use dataCache.preferred here?
preferred = []
preferred_vars = []
pns = {}
for p in eligible:
pns[dataCache.pkg_fn[p]] = p
for p in eligible:
pn = dataCache.pkg_fn[p]
provides = dataCache.pn_provides[pn]
for provide in provides:
prefervar = cfgData.getVar('PREFERRED_PROVIDER_%s' % provide, True)
#logger.debug(1, "checking PREFERRED_PROVIDER_%s (value %s) against %s", provide, prefervar, pns.keys())
if prefervar in pns and pns[prefervar] not in preferred:
var = "PREFERRED_PROVIDER_%s = %s" % (provide, prefervar)
logger.verbose("selecting %s to satisfy runtime %s due to %s", prefervar, item, var)
preferred_vars.append(var)
pref = pns[prefervar]
eligible.remove(pref)
eligible = [pref] + eligible
preferred.append(pref)
break
# If we didn't find an RPROVIDER entry, try and infer the provider from PREFERRED_PROVIDER entries
# by looking through the provides of each eligible recipe and seeing if a PREFERRED_PROVIDER was set.
# This is most useful for virtual/ entries rather than having a RPROVIDER per entry.
if not foundUnique:
# Should use dataCache.preferred here?
preferred = []
preferred_vars = []
pns = {}
for p in eligible:
pns[dataCache.pkg_fn[p]] = p
for p in eligible:
pn = dataCache.pkg_fn[p]
provides = dataCache.pn_provides[pn]
for provide in provides:
prefervar = cfgData.getVar('PREFERRED_PROVIDER_%s' % provide)
#logger.debug(1, "checking PREFERRED_PROVIDER_%s (value %s) against %s", provide, prefervar, pns.keys())
if prefervar in pns and pns[prefervar] not in preferred:
var = "PREFERRED_PROVIDER_%s = %s" % (provide, prefervar)
logger.verbose("selecting %s to satisfy runtime %s due to %s", prefervar, item, var)
preferred_vars.append(var)
pref = pns[prefervar]
eligible.remove(pref)
eligible = [pref] + eligible
preferred.append(pref)
break
numberPreferred = len(preferred)
numberPreferred = len(preferred)
if numberPreferred > 1:
logger.error("Trying to resolve runtime dependency %s resulted in conflicting PREFERRED_PROVIDER entries being found.\nThe providers found were: %s\nThe PREFERRED_PROVIDER entries resulting in this conflict were: %s. You could set PREFERRED_RPROVIDER_%s" % (item, preferred, preferred_vars, item))
logger.error("Trying to resolve runtime dependency %s resulted in conflicting PREFERRED_PROVIDER entries being found.\nThe providers found were: %s\nThe PREFERRED_PROVIDER entries resulting in this conflict were: %s", item, preferred, preferred_vars)
logger.debug(1, "sorted runtime providers for %s are: %s", item, eligible)
@@ -399,32 +379,3 @@ def getRuntimeProviders(dataCache, rdepend):
logger.debug(1, "Assuming %s is a dynamic package, but it may not exist" % rdepend)
return rproviders
def buildWorldTargetList(dataCache, task=None):
"""
Build package list for "bitbake world"
"""
if dataCache.world_target:
return
logger.debug(1, "collating packages for \"world\"")
for f in dataCache.possible_world:
terminal = True
pn = dataCache.pkg_fn[f]
if task and task not in dataCache.task_deps[f]['tasks']:
logger.debug(2, "World build skipping %s as task %s doesn't exist", f, task)
terminal = False
for p in dataCache.pn_provides[pn]:
if p.startswith('virtual/'):
logger.debug(2, "World build skipping %s due to %s provider starting with virtual/", f, p)
terminal = False
break
for pf in dataCache.providers[p]:
if dataCache.pkg_fn[pf] != pn:
logger.debug(2, "World build skipping %s due to both us and %s providing %s", f, pf, p)
terminal = False
break
if terminal:
dataCache.world_target.add(pn)

View File

@@ -527,7 +527,7 @@ def utility_sed(name, args, interp, env, stdin, stdout, stderr, debugflags):
print interp.log(' '.join([name, str(args), interp['PWD']]) + '\n')
# Scan pattern arguments and append a space if necessary
for i in range(len(args)):
for i in xrange(len(args)):
if not RE_SED.search(args[i]):
continue
args[i] = args[i] + ' '

View File

@@ -474,7 +474,7 @@ class Environment:
"""
# Save and remove previous arguments
prevargs = []
for i in range(int(self._env['#'])):
for i in xrange(int(self._env['#'])):
i = str(i+1)
prevargs.append(self._env[i])
del self._env[i]
@@ -488,7 +488,7 @@ class Environment:
return prevargs
def get_positional_args(self):
return [self._env[str(i+1)] for i in range(int(self._env['#']))]
return [self._env[str(i+1)] for i in xrange(int(self._env['#']))]
def get_variables(self):
return dict(self._env)

View File

@@ -20,7 +20,7 @@ except NameError:
from Set import Set as set
from ply import lex
from bb.pysh.sherrors import *
from sherrors import *
class NeedMore(Exception):
pass

View File

@@ -10,11 +10,11 @@
import os.path
import sys
import bb.pysh.pyshlex as pyshlex
import pyshlex
tokens = pyshlex.tokens
from ply import yacc
import bb.pysh.sherrors as sherrors
import sherrors
class IORedirect:
def __init__(self, op, filename, io_number=None):

View File

@@ -1,116 +0,0 @@
"""
BitBake 'remotedata' module
Provides support for using a datastore from the bitbake client
"""
# Copyright (C) 2016 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import bb.data
class RemoteDatastores:
"""Used on the server side to manage references to server-side datastores"""
def __init__(self, cooker):
self.cooker = cooker
self.datastores = {}
self.locked = []
self.nextindex = 1
def __len__(self):
return len(self.datastores)
def __getitem__(self, key):
if key is None:
return self.cooker.data
else:
return self.datastores[key]
def items(self):
return self.datastores.items()
def store(self, d, locked=False):
"""
Put a datastore into the collection. If locked=True then the datastore
is understood to be managed externally and cannot be released by calling
release().
"""
idx = self.nextindex
self.datastores[idx] = d
if locked:
self.locked.append(idx)
self.nextindex += 1
return idx
def check_store(self, d, locked=False):
"""
Put a datastore into the collection if it's not already in there;
in either case return the index
"""
for key, val in self.datastores.items():
if val is d:
idx = key
break
else:
idx = self.store(d, locked)
return idx
def release(self, idx):
"""Discard a datastore in the collection"""
if idx in self.locked:
raise Exception('Tried to release locked datastore %d' % idx)
del self.datastores[idx]
def receive_datastore(self, remote_data):
"""Receive a datastore object sent from the client (as prepared by transmit_datastore())"""
dct = dict(remote_data)
d = bb.data_smart.DataSmart()
d.dict = dct
while True:
if '_remote_data' in dct:
dsindex = dct['_remote_data']['_content']
del dct['_remote_data']
if dsindex is None:
dct['_data'] = self.cooker.data.dict
else:
dct['_data'] = self.datastores[dsindex].dict
break
elif '_data' in dct:
idct = dict(dct['_data'])
dct['_data'] = idct
dct = idct
else:
break
return d
@staticmethod
def transmit_datastore(d):
"""Prepare a datastore object for sending over IPC from the client end"""
# FIXME content might be a dict, need to turn that into a list as well
def copy_dicts(dct):
if '_remote_data' in dct:
dsindex = dct['_remote_data']['_content'].dsindex
newdct = dct.copy()
newdct['_remote_data'] = {'_content': dsindex}
return list(newdct.items())
elif '_data' in dct:
newdct = dct.copy()
newdata = copy_dicts(dct['_data'])
if newdata:
newdct['_data'] = newdata
return list(newdct.items())
return None
main_dict = copy_dicts(d.dict)
return main_dict

File diff suppressed because it is too large Load Diff

View File

@@ -18,4 +18,79 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
""" Base code for Bitbake server process
Have a common base for that all Bitbake server classes ensures a consistent
approach to the interface, and minimize risks associated with code duplication.
"""
""" BaseImplServer() the base class for all XXServer() implementations.
These classes contain the actual code that runs the server side, i.e.
listens for the commands and executes them. Although these implementations
contain all the data of the original bitbake command, i.e the cooker instance,
they may well run on a different process or even machine.
"""
class BaseImplServer():
def __init__(self):
self._idlefuns = {}
def addcooker(self, cooker):
self.cooker = cooker
def register_idle_function(self, function, data):
"""Register a function to be called while the server is idle"""
assert hasattr(function, '__call__')
self._idlefuns[function] = data
""" BitBakeBaseServerConnection class is the common ancestor to all
BitBakeServerConnection classes.
These classes control the remote server. The only command currently
implemented is the terminate() command.
"""
class BitBakeBaseServerConnection():
def __init__(self, serverImpl):
pass
def terminate(self):
pass
""" BitBakeBaseServer class is the common ancestor to all Bitbake servers
Derive this class in order to implement a BitBakeServer which is the
controlling stub for the actual server implementation
"""
class BitBakeBaseServer(object):
def initServer(self):
self.serverImpl = None # we ensure a runtime crash if not overloaded
self.connection = None
return
def addcooker(self, cooker):
self.cooker = cooker
self.serverImpl.addcooker(cooker)
def getServerIdleCB(self):
return self.serverImpl.register_idle_function
def saveConnectionDetails(self):
return
def detach(self):
return
def establishConnection(self, featureset):
raise "Must redefine the %s.establishConnection()" % self.__class__.__name__
def endSession(self):
self.connection.terminate()

View File

@@ -22,268 +22,112 @@
import bb
import bb.event
import itertools
import logging
import multiprocessing
import threading
import array
import os
import signal
import sys
import time
import select
import socket
import subprocess
import errno
import re
import datetime
import bb.server.xmlrpcserver
from bb import daemonize
from multiprocessing import queues
from Queue import Empty
from multiprocessing import Event, Process, util, Queue, Pipe, queues, Manager
from . import BitBakeBaseServer, BitBakeBaseServerConnection, BaseImplServer
logger = logging.getLogger('BitBake')
class ProcessTimeout(SystemExit):
pass
class ServerCommunicator():
def __init__(self, connection, event_handle, server):
self.connection = connection
self.event_handle = event_handle
self.server = server
class ProcessServer(multiprocessing.Process):
def runCommand(self, command):
# @todo try/except
self.connection.send(command)
if not self.server.is_alive():
raise SystemExit
while True:
# don't let the user ctrl-c while we're waiting for a response
try:
if self.connection.poll(20):
return self.connection.recv()
else:
bb.fatal("Timeout while attempting to communicate with bitbake server")
except KeyboardInterrupt:
pass
def getEventHandle(self):
return self.event_handle.value
class EventAdapter():
"""
Adapter to wrap our event queue since the caller (bb.event) expects to
call a send() method, but our actual queue only has put()
"""
def __init__(self, queue):
self.queue = queue
def send(self, event):
try:
self.queue.put(event)
except Exception as err:
print("EventAdapter puked: %s" % str(err))
class ProcessServer(Process, BaseImplServer):
profile_filename = "profile.log"
profile_processed_filename = "profile.log.processed"
def __init__(self, lock, sock, sockname):
multiprocessing.Process.__init__(self)
self.command_channel = False
self.command_channel_reply = False
def __init__(self, command_channel, event_queue, featurelist):
BaseImplServer.__init__(self)
Process.__init__(self)
self.command_channel = command_channel
self.event_queue = event_queue
self.event = EventAdapter(event_queue)
self.featurelist = featurelist
self.quit = False
self.heartbeat_seconds = 1 # default, BB_HEARTBEAT_EVENT will be checked once we have a datastore.
self.next_heartbeat = time.time()
self.event_handle = None
self.haveui = False
self.lastui = False
self.xmlrpc = False
self._idlefuns = {}
self.bitbake_lock = lock
self.sock = sock
self.sockname = sockname
def register_idle_function(self, function, data):
"""Register a function to be called while the server is idle"""
assert hasattr(function, '__call__')
self._idlefuns[function] = data
self.quitin, self.quitout = Pipe()
self.event_handle = multiprocessing.Value("i")
def run(self):
for event in bb.event.ui_queue:
self.event_queue.put(event)
self.event_handle.value = bb.event.register_UIHhandler(self)
if self.xmlrpcinterface[0]:
self.xmlrpc = bb.server.xmlrpcserver.BitBakeXMLRPCServer(self.xmlrpcinterface, self.cooker, self)
print("Bitbake XMLRPC server address: %s, server port: %s" % (self.xmlrpc.host, self.xmlrpc.port))
heartbeat_event = self.cooker.data.getVar('BB_HEARTBEAT_EVENT')
if heartbeat_event:
try:
self.heartbeat_seconds = float(heartbeat_event)
except:
bb.warn('Ignoring invalid BB_HEARTBEAT_EVENT=%s, must be a float specifying seconds.' % heartbeat_event)
self.timeout = self.server_timeout or self.cooker.data.getVar('BB_SERVER_TIMEOUT')
try:
if self.timeout:
self.timeout = float(self.timeout)
except:
bb.warn('Ignoring invalid BB_SERVER_TIMEOUT=%s, must be a float specifying seconds.' % self.timeout)
try:
self.bitbake_lock.seek(0)
self.bitbake_lock.truncate()
if self.xmlrpc:
self.bitbake_lock.write("%s %s:%s\n" % (os.getpid(), self.xmlrpc.host, self.xmlrpc.port))
else:
self.bitbake_lock.write("%s\n" % (os.getpid()))
self.bitbake_lock.flush()
except Exception as e:
print("Error writing to lock file: %s" % str(e))
pass
if self.cooker.configuration.profile:
try:
import cProfile as profile
except:
import profile
prof = profile.Profile()
ret = profile.Profile.runcall(prof, self.main)
prof.dump_stats("profile.log")
bb.utils.process_profilelog("profile.log")
print("Raw profiling information saved to profile.log and processed statistics to profile.log.processed")
else:
ret = self.main()
return ret
bb.cooker.server_main(self.cooker, self.main)
def main(self):
self.cooker.pre_serve()
bb.utils.set_process_name("Cooker")
ready = []
newconnections = []
self.controllersock = False
fds = [self.sock]
if self.xmlrpc:
fds.append(self.xmlrpc)
print("Entering server connection loop")
def disconnect_client(self, fds):
print("Disconnecting Client")
if self.controllersock:
fds.remove(self.controllersock)
self.controllersock.close()
self.controllersock = False
if self.haveui:
fds.remove(self.command_channel)
bb.event.unregister_UIHhandler(self.event_handle, True)
self.command_channel_reply.writer.close()
self.event_writer.writer.close()
self.command_channel.close()
self.command_channel = False
del self.event_writer
self.lastui = time.time()
self.cooker.clientComplete()
self.haveui = False
ready = select.select(fds,[],[],0)[0]
if newconnections:
print("Starting new client")
conn = newconnections.pop(-1)
fds.append(conn)
self.controllersock = conn
elif self.timeout is None and not ready:
print("No timeout, exiting.")
self.quit = True
# Ignore SIGINT within the server, as all SIGINT handling is done by
# the UI and communicated to us
self.quitin.close()
signal.signal(signal.SIGINT, signal.SIG_IGN)
while not self.quit:
if self.sock in ready:
while select.select([self.sock],[],[],0)[0]:
controllersock, address = self.sock.accept()
if self.controllersock:
print("Queuing %s (%s)" % (str(ready), str(newconnections)))
newconnections.append(controllersock)
else:
print("Accepting %s (%s)" % (str(ready), str(newconnections)))
self.controllersock = controllersock
fds.append(controllersock)
if self.controllersock in ready:
try:
print("Processing Client")
ui_fds = recvfds(self.controllersock, 3)
print("Connecting Client")
# Where to write events to
writer = ConnectionWriter(ui_fds[0])
self.event_handle = bb.event.register_UIHhandler(writer, True)
self.event_writer = writer
# Where to read commands from
reader = ConnectionReader(ui_fds[1])
fds.append(reader)
self.command_channel = reader
# Where to send command return values to
writer = ConnectionWriter(ui_fds[2])
self.command_channel_reply = writer
self.haveui = True
except (EOFError, OSError):
disconnect_client(self, fds)
if not self.timeout == -1.0 and not self.haveui and self.lastui and self.timeout and \
(self.lastui + self.timeout) < time.time():
print("Server timeout, exiting.")
self.quit = True
if self.command_channel in ready:
try:
command = self.command_channel.get()
except EOFError:
# Client connection shutting down
ready = []
disconnect_client(self, fds)
continue
if command[0] == "terminateServer":
try:
if self.command_channel.poll():
command = self.command_channel.recv()
self.runCommand(command)
if self.quitout.poll():
self.quitout.recv()
self.quit = True
continue
try:
print("Running command %s" % command)
self.command_channel_reply.send(self.cooker.command.runCommand(command))
except Exception as e:
logger.exception('Exception in server main event loop running command %s (%s)' % (command, str(e)))
if self.xmlrpc in ready:
self.xmlrpc.handle_requests()
self.idle_commands(.1, [self.command_channel, self.quitout])
except Exception:
logger.exception('Running command %s', command)
ready = self.idle_commands(.1, fds)
self.event_queue.close()
bb.event.unregister_UIHhandler(self.event_handle.value)
self.command_channel.close()
self.cooker.shutdown(True)
print("Exiting")
# Remove the socket file so we don't get any more connections to avoid races
os.unlink(self.sockname)
self.sock.close()
try:
self.cooker.shutdown(True)
self.cooker.notifier.stop()
self.cooker.confignotifier.stop()
except:
pass
self.cooker.post_serve()
# Finally release the lockfile but warn about other processes holding it open
lock = self.bitbake_lock
lockfile = lock.name
lock.close()
lock = None
while not lock:
with bb.utils.timeout(3):
lock = bb.utils.lockfile(lockfile, shared=False, retry=False, block=True)
if lock:
# We hold the lock so we can remove the file (hide stale pid data)
bb.utils.remove(lockfile)
bb.utils.unlockfile(lock)
return
if not lock:
# Some systems may not have lsof available
procs = None
try:
procs = subprocess.check_output(["lsof", '-w', lockfile], stderr=subprocess.STDOUT)
except OSError as e:
if e.errno != errno.ENOENT:
raise
if procs is None:
# Fall back to fuser if lsof is unavailable
try:
procs = subprocess.check_output(["fuser", '-v', lockfile], stderr=subprocess.STDOUT)
except OSError as e:
if e.errno != errno.ENOENT:
raise
msg = "Delaying shutdown due to active processes which appear to be holding bitbake.lock"
if procs:
msg += ":\n%s" % str(procs)
print(msg)
def idle_commands(self, delay, fds=None):
def idle_commands(self, delay, fds = []):
nextsleep = delay
if not fds:
fds = []
for function, data in list(self._idlefuns.items()):
for function, data in self._idlefuns.items():
try:
retval = function(self, data, False)
if retval is False:
@@ -291,7 +135,7 @@ class ProcessServer(multiprocessing.Process):
nextsleep = None
elif retval is True:
nextsleep = None
elif isinstance(retval, float) and nextsleep:
elif isinstance(retval, float):
if (retval < nextsleep):
nextsleep = retval
elif nextsleep is None:
@@ -300,365 +144,109 @@ class ProcessServer(multiprocessing.Process):
fds = fds + retval
except SystemExit:
raise
except Exception as exc:
if not isinstance(exc, bb.BBHandledException):
logger.exception('Running idle function')
except Exception:
logger.exception('Running idle function')
del self._idlefuns[function]
self.quit = True
# Create new heartbeat event?
now = time.time()
if now >= self.next_heartbeat:
# We might have missed heartbeats. Just trigger once in
# that case and continue after the usual delay.
self.next_heartbeat += self.heartbeat_seconds
if self.next_heartbeat <= now:
self.next_heartbeat = now + self.heartbeat_seconds
heartbeat = bb.event.HeartbeatEvent(now)
bb.event.fire(heartbeat, self.cooker.data)
if nextsleep and now + nextsleep > self.next_heartbeat:
# Shorten timeout so that we we wake up in time for
# the heartbeat.
nextsleep = self.next_heartbeat - now
if nextsleep is not None:
if self.xmlrpc:
nextsleep = self.xmlrpc.get_timeout(nextsleep)
try:
return select.select(fds,[],[],nextsleep)[0]
except InterruptedError:
# Ignore EINTR
return []
else:
return select.select(fds,[],[],0)[0]
class ServerCommunicator():
def __init__(self, connection, recv):
self.connection = connection
self.recv = recv
select.select(fds,[],[],nextsleep)
def runCommand(self, command):
self.connection.send(command)
if not self.recv.poll(30):
raise ProcessTimeout("Timeout while waiting for a reply from the bitbake server")
return self.recv.get()
"""
Run a cooker command on the server
"""
self.command_channel.send(self.cooker.command.runCommand(command))
def updateFeatureSet(self, featureset):
_, error = self.runCommand(["setFeatures", featureset])
def stop(self):
self.quitin.send("quit")
self.quitin.close()
class BitBakeProcessServerConnection(BitBakeBaseServerConnection):
def __init__(self, serverImpl, ui_channel, event_queue):
self.procserver = serverImpl
self.ui_channel = ui_channel
self.event_queue = event_queue
self.connection = ServerCommunicator(self.ui_channel, self.procserver.event_handle, self.procserver)
self.events = self.event_queue
def sigterm_terminate(self):
bb.error("UI received SIGTERM")
self.terminate()
def terminate(self):
def flushevents():
while True:
try:
event = self.event_queue.get(block=False)
except (Empty, IOError):
break
if isinstance(event, logging.LogRecord):
logger.handle(event)
signal.signal(signal.SIGINT, signal.SIG_IGN)
self.procserver.stop()
while self.procserver.is_alive():
flushevents()
self.procserver.join(0.1)
self.ui_channel.close()
self.event_queue.close()
self.event_queue.setexit()
# Wrap Queue to provide API which isn't server implementation specific
class ProcessEventQueue(multiprocessing.queues.Queue):
def __init__(self, maxsize):
multiprocessing.queues.Queue.__init__(self, maxsize)
self.exit = False
def setexit(self):
self.exit = True
def waitEvent(self, timeout):
if self.exit:
sys.exit(1)
try:
if not self.server.is_alive():
self.setexit()
return None
return self.get(True, timeout)
except Empty:
return None
def getEvent(self):
try:
if not self.server.is_alive():
self.setexit()
return None
return self.get(False)
except Empty:
return None
class BitBakeServer(BitBakeBaseServer):
def initServer(self):
# establish communication channels. We use bidirectional pipes for
# ui <--> server command/response pairs
# and a queue for server -> ui event notifications
#
self.ui_channel, self.server_channel = Pipe()
self.event_queue = ProcessEventQueue(0)
self.serverImpl = ProcessServer(self.server_channel, self.event_queue, None)
self.event_queue.server = self.serverImpl
def detach(self):
self.serverImpl.start()
return
def establishConnection(self, featureset):
self.connection = BitBakeProcessServerConnection(self.serverImpl, self.ui_channel, self.event_queue)
_, error = self.connection.connection.runCommand(["setFeatures", featureset])
if error:
logger.error("Unable to set the cooker to the correct featureset: %s" % error)
raise BaseException(error)
def getEventHandle(self):
handle, error = self.runCommand(["getUIHandlerNum"])
if error:
logger.error("Unable to get UI Handler Number: %s" % error)
raise BaseException(error)
return handle
def terminateServer(self):
self.connection.send(['terminateServer'])
return
class BitBakeProcessServerConnection(object):
def __init__(self, ui_channel, recv, eq, sock):
self.connection = ServerCommunicator(ui_channel, recv)
self.events = eq
# Save sock so it doesn't get gc'd for the life of our connection
self.socket_connection = sock
def terminate(self):
self.socket_connection.close()
self.connection.connection.close()
self.connection.recv.close()
return
class BitBakeServer(object):
start_log_format = '--- Starting bitbake server pid %s at %s ---'
start_log_datetime_format = '%Y-%m-%d %H:%M:%S.%f'
def __init__(self, lock, sockname, configuration, featureset):
self.configuration = configuration
self.featureset = featureset
self.sockname = sockname
self.bitbake_lock = lock
self.readypipe, self.readypipein = os.pipe()
# Create server control socket
if os.path.exists(sockname):
os.unlink(sockname)
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# AF_UNIX has path length issues so chdir here to workaround
cwd = os.getcwd()
logfile = os.path.join(cwd, "bitbake-cookerdaemon.log")
try:
os.chdir(os.path.dirname(sockname))
self.sock.bind(os.path.basename(sockname))
finally:
os.chdir(cwd)
self.sock.listen(1)
os.set_inheritable(self.sock.fileno(), True)
startdatetime = datetime.datetime.now()
bb.daemonize.createDaemon(self._startServer, logfile)
self.sock.close()
self.bitbake_lock.close()
ready = ConnectionReader(self.readypipe)
r = ready.poll(5)
if not r:
bb.note("Bitbake server didn't start within 5 seconds, waiting for 90")
r = ready.poll(90)
if r:
r = ready.get()
if not r or r != "ready":
ready.close()
bb.error("Unable to start bitbake server")
if os.path.exists(logfile):
logstart_re = re.compile(self.start_log_format % ('([0-9]+)', '([0-9-]+ [0-9:.]+)'))
started = False
lines = []
lastlines = []
with open(logfile, "r") as f:
for line in f:
if started:
lines.append(line)
else:
lastlines.append(line)
res = logstart_re.match(line.rstrip())
if res:
ldatetime = datetime.datetime.strptime(res.group(2), self.start_log_datetime_format)
if ldatetime >= startdatetime:
started = True
lines.append(line)
if len(lastlines) > 60:
lastlines = lastlines[-60:]
if lines:
if len(lines) > 60:
bb.error("Last 60 lines of server log for this session (%s):\n%s" % (logfile, "".join(lines[-60:])))
else:
bb.error("Server log for this session (%s):\n%s" % (logfile, "".join(lines)))
elif lastlines:
bb.error("Server didn't start, last 60 loglines (%s):\n%s" % (logfile, "".join(lastlines)))
else:
bb.error("%s doesn't exist" % logfile)
raise SystemExit(1)
ready.close()
os.close(self.readypipein)
def _startServer(self):
print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
sys.stdout.flush()
server = ProcessServer(self.bitbake_lock, self.sock, self.sockname)
self.configuration.setServerRegIdleCallback(server.register_idle_function)
writer = ConnectionWriter(self.readypipein)
try:
self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset)
writer.send("ready")
except:
writer.send("fail")
raise
finally:
os.close(self.readypipein)
server.cooker = self.cooker
server.server_timeout = self.configuration.server_timeout
server.xmlrpcinterface = self.configuration.xmlrpcinterface
print("Started bitbake server pid %d" % os.getpid())
sys.stdout.flush()
server.start()
def connectProcessServer(sockname, featureset):
# Connect to socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# AF_UNIX has path length issues so chdir here to workaround
cwd = os.getcwd()
readfd = writefd = readfd1 = writefd1 = readfd2 = writefd2 = None
eq = command_chan_recv = command_chan = None
sock.settimeout(10)
try:
try:
os.chdir(os.path.dirname(sockname))
finished = False
while not finished:
try:
sock.connect(os.path.basename(sockname))
finished = True
except IOError as e:
if e.errno == errno.EWOULDBLOCK:
pass
finally:
os.chdir(cwd)
# Send an fd for the remote to write events to
readfd, writefd = os.pipe()
eq = BBUIEventQueue(readfd)
# Send an fd for the remote to recieve commands from
readfd1, writefd1 = os.pipe()
command_chan = ConnectionWriter(writefd1)
# Send an fd for the remote to write commands results to
readfd2, writefd2 = os.pipe()
command_chan_recv = ConnectionReader(readfd2)
sendfds(sock, [writefd, readfd1, writefd2])
server_connection = BitBakeProcessServerConnection(command_chan, command_chan_recv, eq, sock)
# Close the ends of the pipes we won't use
for i in [writefd, readfd1, writefd2]:
os.close(i)
server_connection.connection.updateFeatureSet(featureset)
except (Exception, SystemExit) as e:
if command_chan_recv:
command_chan_recv.close()
if command_chan:
command_chan.close()
for i in [writefd, readfd1, writefd2]:
try:
if i:
os.close(i)
except OSError:
pass
sock.close()
raise
return server_connection
def sendfds(sock, fds):
'''Send an array of fds over an AF_UNIX socket.'''
fds = array.array('i', fds)
msg = bytes([len(fds) % 256])
sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, fds)])
def recvfds(sock, size):
'''Receive an array of fds over an AF_UNIX socket.'''
a = array.array('i')
bytes_size = a.itemsize * size
msg, ancdata, flags, addr = sock.recvmsg(1, socket.CMSG_LEN(bytes_size))
if not msg and not ancdata:
raise EOFError
try:
if len(ancdata) != 1:
raise RuntimeError('received %d items of ancdata' %
len(ancdata))
cmsg_level, cmsg_type, cmsg_data = ancdata[0]
if (cmsg_level == socket.SOL_SOCKET and
cmsg_type == socket.SCM_RIGHTS):
if len(cmsg_data) % a.itemsize != 0:
raise ValueError
a.frombytes(cmsg_data)
assert len(a) % 256 == msg[0]
return list(a)
except (ValueError, IndexError):
pass
raise RuntimeError('Invalid data received')
class BBUIEventQueue:
def __init__(self, readfd):
self.eventQueue = []
self.eventQueueLock = threading.Lock()
self.eventQueueNotify = threading.Event()
self.reader = ConnectionReader(readfd)
self.t = threading.Thread()
self.t.setDaemon(True)
self.t.run = self.startCallbackHandler
self.t.start()
def getEvent(self):
self.eventQueueLock.acquire()
if len(self.eventQueue) == 0:
self.eventQueueLock.release()
return None
item = self.eventQueue.pop(0)
if len(self.eventQueue) == 0:
self.eventQueueNotify.clear()
self.eventQueueLock.release()
return item
def waitEvent(self, delay):
self.eventQueueNotify.wait(delay)
return self.getEvent()
def queue_event(self, event):
self.eventQueueLock.acquire()
self.eventQueue.append(event)
self.eventQueueNotify.set()
self.eventQueueLock.release()
def send_event(self, event):
self.queue_event(pickle.loads(event))
def startCallbackHandler(self):
bb.utils.set_process_name("UIEventQueue")
while True:
try:
self.reader.wait()
event = self.reader.get()
self.queue_event(event)
except EOFError:
# Easiest way to exit is to close the file descriptor to cause an exit
break
self.reader.close()
class ConnectionReader(object):
def __init__(self, fd):
self.reader = multiprocessing.connection.Connection(fd, writable=False)
self.rlock = multiprocessing.Lock()
def wait(self, timeout=None):
return multiprocessing.connection.wait([self.reader], timeout)
def poll(self, timeout=None):
return self.reader.poll(timeout)
def get(self):
with self.rlock:
res = self.reader.recv_bytes()
return multiprocessing.reduction.ForkingPickler.loads(res)
def fileno(self):
return self.reader.fileno()
def close(self):
return self.reader.close()
class ConnectionWriter(object):
def __init__(self, fd):
self.writer = multiprocessing.connection.Connection(fd, readable=False)
self.wlock = multiprocessing.Lock()
# Why bb.event needs this I have no idea
self.event = self
def send(self, obj):
obj = multiprocessing.reduction.ForkingPickler.dumps(obj)
with self.wlock:
self.writer.send_bytes(obj)
def fileno(self):
return self.writer.fileno()
def close(self):
return self.writer.close()
signal.signal(signal.SIGTERM, lambda i, s: self.connection.sigterm_terminate())
return self.connection

View File

@@ -0,0 +1,389 @@
#
# BitBake XMLRPC Server
#
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
This module implements an xmlrpc server for BitBake.
Use this by deriving a class from BitBakeXMLRPCServer and then adding
methods which you want to "export" via XMLRPC. If the methods have the
prefix xmlrpc_, then registering those function will happen automatically,
if not, you need to call register_function.
Use register_idle_function() to add a function which the xmlrpc server
calls from within server_forever when no requests are pending. Make sure
that those functions are non-blocking or else you will introduce latency
in the server's main loop.
"""
import bb
import xmlrpclib, sys
from bb import daemonize
from bb.ui import uievent
import hashlib, time
import socket
import os, signal
import threading
try:
import cPickle as pickle
except ImportError:
import pickle
DEBUG = False
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import inspect, select, httplib
from . import BitBakeBaseServer, BitBakeBaseServerConnection, BaseImplServer
class BBTransport(xmlrpclib.Transport):
def __init__(self, timeout):
self.timeout = timeout
self.connection_token = None
xmlrpclib.Transport.__init__(self)
# Modified from default to pass timeout to HTTPConnection
def make_connection(self, host):
#return an existing connection if possible. This allows
#HTTP/1.1 keep-alive.
if self._connection and host == self._connection[0]:
return self._connection[1]
# create a HTTP connection object from a host descriptor
chost, self._extra_headers, x509 = self.get_host_info(host)
#store the host argument along with the connection object
self._connection = host, httplib.HTTPConnection(chost, timeout=self.timeout)
return self._connection[1]
def set_connection_token(self, token):
self.connection_token = token
def send_content(self, h, body):
if self.connection_token:
h.putheader("Bitbake-token", self.connection_token)
xmlrpclib.Transport.send_content(self, h, body)
def _create_server(host, port, timeout = 60):
t = BBTransport(timeout)
s = xmlrpclib.ServerProxy("http://%s:%d/" % (host, port), transport=t, allow_none=True)
return s, t
class BitBakeServerCommands():
def __init__(self, server):
self.server = server
self.has_client = False
def registerEventHandler(self, host, port):
"""
Register a remote UI Event Handler
"""
s, t = _create_server(host, port)
# we don't allow connections if the cooker is running
if (self.cooker.state in [bb.cooker.state.parsing, bb.cooker.state.running]):
return None
self.event_handle = bb.event.register_UIHhandler(s)
return self.event_handle
def unregisterEventHandler(self, handlerNum):
"""
Unregister a remote UI Event Handler
"""
return bb.event.unregister_UIHhandler(handlerNum)
def runCommand(self, command):
"""
Run a cooker command on the server
"""
return self.cooker.command.runCommand(command, self.server.readonly)
def getEventHandle(self):
return self.event_handle
def terminateServer(self):
"""
Trigger the server to quit
"""
self.server.quit = True
print("Server (cooker) exiting")
return
def addClient(self):
if self.has_client:
return None
token = hashlib.md5(str(time.time())).hexdigest()
self.server.set_connection_token(token)
self.has_client = True
return token
def removeClient(self):
if self.has_client:
self.server.set_connection_token(None)
self.has_client = False
if self.server.single_use:
self.server.quit = True
# This request handler checks if the request has a "Bitbake-token" header
# field (this comes from the client side) and compares it with its internal
# "Bitbake-token" field (this comes from the server). If the two are not
# equal, it is assumed that a client is trying to connect to the server
# while another client is connected to the server. In this case, a 503 error
# ("service unavailable") is returned to the client.
class BitBakeXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
def __init__(self, request, client_address, server):
self.server = server
SimpleXMLRPCRequestHandler.__init__(self, request, client_address, server)
def do_POST(self):
try:
remote_token = self.headers["Bitbake-token"]
except:
remote_token = None
if remote_token != self.server.connection_token and remote_token != "observer":
self.report_503()
else:
if remote_token == "observer":
self.server.readonly = True
else:
self.server.readonly = False
SimpleXMLRPCRequestHandler.do_POST(self)
def report_503(self):
self.send_response(503)
response = 'No more client allowed'
self.send_header("Content-type", "text/plain")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
class XMLRPCProxyServer(BaseImplServer):
""" not a real working server, but a stub for a proxy server connection
"""
def __init__(self, host, port):
self.host = host
self.port = port
class XMLRPCServer(SimpleXMLRPCServer, BaseImplServer):
# remove this when you're done with debugging
# allow_reuse_address = True
def __init__(self, interface):
"""
Constructor
"""
BaseImplServer.__init__(self)
if (interface[1] == 0): # anonymous port, not getting reused
self.single_use = True
# Use auto port configuration
if (interface[1] == -1):
interface = (interface[0], 0)
SimpleXMLRPCServer.__init__(self, interface,
requestHandler=BitBakeXMLRPCRequestHandler,
logRequests=False, allow_none=True)
self.host, self.port = self.socket.getsockname()
self.connection_token = None
#self.register_introspection_functions()
self.commands = BitBakeServerCommands(self)
self.autoregister_all_functions(self.commands, "")
self.interface = interface
self.single_use = False
def addcooker(self, cooker):
BaseImplServer.addcooker(self, cooker)
self.commands.cooker = cooker
def autoregister_all_functions(self, context, prefix):
"""
Convenience method for registering all functions in the scope
of this class that start with a common prefix
"""
methodlist = inspect.getmembers(context, inspect.ismethod)
for name, method in methodlist:
if name.startswith(prefix):
self.register_function(method, name[len(prefix):])
def serve_forever(self):
# Start the actual XMLRPC server
bb.cooker.server_main(self.cooker, self._serve_forever)
def _serve_forever(self):
"""
Serve Requests. Overloaded to honor a quit command
"""
self.quit = False
while not self.quit:
fds = [self]
nextsleep = 0.1
for function, data in self._idlefuns.items():
retval = None
try:
retval = function(self, data, False)
if retval is False:
del self._idlefuns[function]
elif retval is True:
nextsleep = 0
elif isinstance(retval, float):
if (retval < nextsleep):
nextsleep = retval
else:
fds = fds + retval
except SystemExit:
raise
except:
import traceback
traceback.print_exc()
if retval == None:
# the function execute failed; delete it
del self._idlefuns[function]
pass
socktimeout = self.socket.gettimeout() or nextsleep
socktimeout = min(socktimeout, nextsleep)
# Mirror what BaseServer handle_request would do
try:
fd_sets = select.select(fds, [], [], socktimeout)
if fd_sets[0] and self in fd_sets[0]:
self._handle_request_noblock()
except IOError:
# we ignore interrupted calls
pass
# Tell idle functions we're exiting
for function, data in self._idlefuns.items():
try:
retval = function(self, data, True)
except:
pass
self.server_close()
return
def set_connection_token(self, token):
self.connection_token = token
class BitBakeXMLRPCServerConnection(BitBakeBaseServerConnection):
def __init__(self, serverImpl, clientinfo=("localhost", 0), observer_only = False, featureset = []):
self.connection, self.transport = _create_server(serverImpl.host, serverImpl.port)
self.clientinfo = clientinfo
self.serverImpl = serverImpl
self.observer_only = observer_only
self.featureset = featureset
def connect(self, token = None):
if token is None:
if self.observer_only:
token = "observer"
else:
token = self.connection.addClient()
if token is None:
return None
self.transport.set_connection_token(token)
self.events = uievent.BBUIEventQueue(self.connection, self.clientinfo)
for event in bb.event.ui_queue:
self.events.queue_event(event)
_, error = self.connection.runCommand(["setFeatures", self.featureset])
if error:
# disconnect the client, we can't make the setFeature work
self.connection.removeClient()
# no need to log it here, the error shall be sent to the client
raise BaseException(error)
return self
def removeClient(self):
if not self.observer_only:
self.connection.removeClient()
def terminate(self):
# Don't wait for server indefinitely
import socket
socket.setdefaulttimeout(2)
try:
self.events.system_quit()
except:
pass
try:
self.connection.removeClient()
except:
pass
class BitBakeServer(BitBakeBaseServer):
def initServer(self, interface = ("localhost", 0)):
self.interface = interface
self.serverImpl = XMLRPCServer(interface)
def detach(self):
daemonize.createDaemon(self.serverImpl.serve_forever, "bitbake-cookerdaemon.log")
del self.cooker
def establishConnection(self, featureset):
self.connection = BitBakeXMLRPCServerConnection(self.serverImpl, self.interface, False, featureset)
return self.connection.connect()
def set_connection_token(self, token):
self.connection.transport.set_connection_token(token)
class BitBakeXMLRPCClient(BitBakeBaseServer):
def __init__(self, observer_only = False, token = None):
self.token = token
self.observer_only = observer_only
# if we need extra caches, just tell the server to load them all
pass
def saveConnectionDetails(self, remote):
self.remote = remote
def establishConnection(self, featureset):
# The format of "remote" must be "server:port"
try:
[host, port] = self.remote.split(":")
port = int(port)
except Exception as e:
bb.warn("Failed to read remote definition (%s)" % str(e))
raise e
# We need our IP for the server connection. We get the IP
# by trying to connect with the server
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((host, port))
ip = s.getsockname()[0]
s.close()
except Exception as e:
bb.warn("Could not create socket for %s:%s (%s)" % (host, port, str(e)))
raise e
try:
self.serverImpl = XMLRPCProxyServer(host, port)
self.connection = BitBakeXMLRPCServerConnection(self.serverImpl, (ip, 0), self.observer_only, featureset)
return self.connection.connect(self.token)
except Exception as e:
bb.warn("Could not connect to server at %s:%s (%s)" % (host, port, str(e)))
raise e
def endSession(self):
self.connection.removeClient()

View File

@@ -1,154 +0,0 @@
#
# BitBake XMLRPC Client Interface
#
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import socket
import http.client
import xmlrpc.client
import bb
from bb.ui import uievent
class BBTransport(xmlrpc.client.Transport):
def __init__(self, timeout):
self.timeout = timeout
self.connection_token = None
xmlrpc.client.Transport.__init__(self)
# Modified from default to pass timeout to HTTPConnection
def make_connection(self, host):
#return an existing connection if possible. This allows
#HTTP/1.1 keep-alive.
if self._connection and host == self._connection[0]:
return self._connection[1]
# create a HTTP connection object from a host descriptor
chost, self._extra_headers, x509 = self.get_host_info(host)
#store the host argument along with the connection object
self._connection = host, http.client.HTTPConnection(chost, timeout=self.timeout)
return self._connection[1]
def set_connection_token(self, token):
self.connection_token = token
def send_content(self, h, body):
if self.connection_token:
h.putheader("Bitbake-token", self.connection_token)
xmlrpc.client.Transport.send_content(self, h, body)
def _create_server(host, port, timeout = 60):
t = BBTransport(timeout)
s = xmlrpc.client.ServerProxy("http://%s:%d/" % (host, port), transport=t, allow_none=True, use_builtin_types=True)
return s, t
def check_connection(remote, timeout):
try:
host, port = remote.split(":")
port = int(port)
except Exception as e:
bb.warn("Failed to read remote definition (%s)" % str(e))
raise e
server, _transport = _create_server(host, port, timeout)
try:
ret, err = server.runCommand(['getVariable', 'TOPDIR'])
if err or not ret:
return False
except ConnectionError:
return False
return True
class BitBakeXMLRPCServerConnection(object):
def __init__(self, host, port, clientinfo=("localhost", 0), observer_only = False, featureset = None):
self.connection, self.transport = _create_server(host, port)
self.clientinfo = clientinfo
self.observer_only = observer_only
if featureset:
self.featureset = featureset
else:
self.featureset = []
self.events = uievent.BBUIEventQueue(self.connection, self.clientinfo)
_, error = self.connection.runCommand(["setFeatures", self.featureset])
if error:
# disconnect the client, we can't make the setFeature work
self.connection.removeClient()
# no need to log it here, the error shall be sent to the client
raise BaseException(error)
def connect(self, token = None):
if token is None:
if self.observer_only:
token = "observer"
else:
token = self.connection.addClient()
if token is None:
return None
self.transport.set_connection_token(token)
return self
def removeClient(self):
if not self.observer_only:
self.connection.removeClient()
def terminate(self):
# Don't wait for server indefinitely
socket.setdefaulttimeout(2)
try:
self.events.system_quit()
except:
pass
try:
self.connection.removeClient()
except:
pass
def connectXMLRPC(remote, featureset, observer_only = False, token = None):
# The format of "remote" must be "server:port"
try:
[host, port] = remote.split(":")
port = int(port)
except Exception as e:
bb.warn("Failed to parse remote definition %s (%s)" % (remote, str(e)))
raise e
# We need our IP for the server connection. We get the IP
# by trying to connect with the server
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((host, port))
ip = s.getsockname()[0]
s.close()
except Exception as e:
bb.warn("Could not create socket for %s:%s (%s)" % (host, port, str(e)))
raise e
try:
connection = BitBakeXMLRPCServerConnection(host, port, (ip, 0), observer_only, featureset)
return connection.connect(token)
except Exception as e:
bb.warn("Could not connect to server at %s:%s (%s)" % (host, port, str(e)))
raise e

View File

@@ -1,158 +0,0 @@
#
# BitBake XMLRPC Server Interface
#
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import sys
import hashlib
import time
import inspect
from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import bb
# This request handler checks if the request has a "Bitbake-token" header
# field (this comes from the client side) and compares it with its internal
# "Bitbake-token" field (this comes from the server). If the two are not
# equal, it is assumed that a client is trying to connect to the server
# while another client is connected to the server. In this case, a 503 error
# ("service unavailable") is returned to the client.
class BitBakeXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
def __init__(self, request, client_address, server):
self.server = server
SimpleXMLRPCRequestHandler.__init__(self, request, client_address, server)
def do_POST(self):
try:
remote_token = self.headers["Bitbake-token"]
except:
remote_token = None
if 0 and remote_token != self.server.connection_token and remote_token != "observer":
self.report_503()
else:
if remote_token == "observer":
self.server.readonly = True
else:
self.server.readonly = False
SimpleXMLRPCRequestHandler.do_POST(self)
def report_503(self):
self.send_response(503)
response = 'No more client allowed'
self.send_header("Content-type", "text/plain")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(bytes(response, 'utf-8'))
class BitBakeXMLRPCServer(SimpleXMLRPCServer):
# remove this when you're done with debugging
# allow_reuse_address = True
def __init__(self, interface, cooker, parent):
# Use auto port configuration
if (interface[1] == -1):
interface = (interface[0], 0)
SimpleXMLRPCServer.__init__(self, interface,
requestHandler=BitBakeXMLRPCRequestHandler,
logRequests=False, allow_none=True)
self.host, self.port = self.socket.getsockname()
self.interface = interface
self.connection_token = None
self.commands = BitBakeXMLRPCServerCommands(self)
self.register_functions(self.commands, "")
self.cooker = cooker
self.parent = parent
def register_functions(self, context, prefix):
"""
Convenience method for registering all functions in the scope
of this class that start with a common prefix
"""
methodlist = inspect.getmembers(context, inspect.ismethod)
for name, method in methodlist:
if name.startswith(prefix):
self.register_function(method, name[len(prefix):])
def get_timeout(self, delay):
socktimeout = self.socket.gettimeout() or delay
return min(socktimeout, delay)
def handle_requests(self):
self._handle_request_noblock()
class BitBakeXMLRPCServerCommands():
def __init__(self, server):
self.server = server
self.has_client = False
def registerEventHandler(self, host, port):
"""
Register a remote UI Event Handler
"""
s, t = bb.server.xmlrpcclient._create_server(host, port)
# we don't allow connections if the cooker is running
if (self.server.cooker.state in [bb.cooker.state.parsing, bb.cooker.state.running]):
return None, "Cooker is busy: %s" % bb.cooker.state.get_name(self.server.cooker.state)
self.event_handle = bb.event.register_UIHhandler(s, True)
return self.event_handle, 'OK'
def unregisterEventHandler(self, handlerNum):
"""
Unregister a remote UI Event Handler
"""
ret = bb.event.unregister_UIHhandler(handlerNum, True)
self.event_handle = None
return ret
def runCommand(self, command):
"""
Run a cooker command on the server
"""
return self.server.cooker.command.runCommand(command, self.server.readonly)
def getEventHandle(self):
return self.event_handle
def terminateServer(self):
"""
Trigger the server to quit
"""
self.server.parent.quit = True
print("XMLRPC Server triggering exit")
return
def addClient(self):
if self.server.parent.haveui:
return None
token = hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()
self.server.connection_token = token
self.server.parent.haveui = True
return token
def removeClient(self):
if self.server.parent.haveui:
self.server.connection_token = None
self.server.parent.haveui = False

820
bitbake/lib/bb/shell.py Normal file
View File

@@ -0,0 +1,820 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
##########################################################################
#
# Copyright (C) 2005-2006 Michael 'Mickey' Lauer <mickey@Vanille.de>
# Copyright (C) 2005-2006 Vanille Media
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
##########################################################################
#
# Thanks to:
# * Holger Freyther <zecke@handhelds.org>
# * Justin Patrin <papercrane@reversefold.com>
#
##########################################################################
"""
BitBake Shell
IDEAS:
* list defined tasks per package
* list classes
* toggle force
* command to reparse just one (or more) bbfile(s)
* automatic check if reparsing is necessary (inotify?)
* frontend for bb file manipulation
* more shell-like features:
- output control, i.e. pipe output into grep, sort, etc.
- job control, i.e. bring running commands into background and foreground
* start parsing in background right after startup
* ncurses interface
PROBLEMS:
* force doesn't always work
* readline completion for commands with more than one parameters
"""
##########################################################################
# Import and setup global variables
##########################################################################
from __future__ import print_function
from functools import reduce
try:
set
except NameError:
from sets import Set as set
import sys, os, readline, socket, httplib, urllib, commands, popen2, shlex, Queue, fnmatch
from bb import data, parse, build, cache, taskdata, runqueue, providers as Providers
__version__ = "0.5.3.1"
__credits__ = """BitBake Shell Version %s (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
Type 'help' for more information, press CTRL-D to exit.""" % __version__
cmds = {}
leave_mainloop = False
last_exception = None
cooker = None
parsed = False
debug = os.environ.get( "BBSHELL_DEBUG", "" )
##########################################################################
# Class BitBakeShellCommands
##########################################################################
class BitBakeShellCommands:
"""This class contains the valid commands for the shell"""
def __init__( self, shell ):
"""Register all the commands"""
self._shell = shell
for attr in BitBakeShellCommands.__dict__:
if not attr.startswith( "_" ):
if attr.endswith( "_" ):
command = attr[:-1].lower()
else:
command = attr[:].lower()
method = getattr( BitBakeShellCommands, attr )
debugOut( "registering command '%s'" % command )
# scan number of arguments
usage = getattr( method, "usage", "" )
if usage != "<...>":
numArgs = len( usage.split() )
else:
numArgs = -1
shell.registerCommand( command, method, numArgs, "%s %s" % ( command, usage ), method.__doc__ )
def _checkParsed( self ):
if not parsed:
print("SHELL: This command needs to parse bbfiles...")
self.parse( None )
def _findProvider( self, item ):
self._checkParsed()
# Need to use taskData for this information
preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
if not preferred: preferred = item
try:
lv, lf, pv, pf = Providers.findBestProvider(preferred, cooker.configuration.data, cooker.status)
except KeyError:
if item in cooker.status.providers:
pf = cooker.status.providers[item][0]
else:
pf = None
return pf
def alias( self, params ):
"""Register a new name for a command"""
new, old = params
if not old in cmds:
print("ERROR: Command '%s' not known" % old)
else:
cmds[new] = cmds[old]
print("OK")
alias.usage = "<alias> <command>"
def buffer( self, params ):
"""Dump specified output buffer"""
index = params[0]
print(self._shell.myout.buffer( int( index ) ))
buffer.usage = "<index>"
def buffers( self, params ):
"""Show the available output buffers"""
commands = self._shell.myout.bufferedCommands()
if not commands:
print("SHELL: No buffered commands available yet. Start doing something.")
else:
print("="*35, "Available Output Buffers", "="*27)
for index, cmd in enumerate( commands ):
print("| %s %s" % ( str( index ).ljust( 3 ), cmd ))
print("="*88)
def build( self, params, cmd = "build" ):
"""Build a providee"""
global last_exception
globexpr = params[0]
self._checkParsed()
names = globfilter( cooker.status.pkg_pn, globexpr )
if len( names ) == 0: names = [ globexpr ]
print("SHELL: Building %s" % ' '.join( names ))
td = taskdata.TaskData(cooker.configuration.abort)
localdata = data.createCopy(cooker.configuration.data)
data.update_data(localdata)
data.expandKeys(localdata)
try:
tasks = []
for name in names:
td.add_provider(localdata, cooker.status, name)
providers = td.get_provider(name)
if len(providers) == 0:
raise Providers.NoProvider
tasks.append([name, "do_%s" % cmd])
td.add_unresolved(localdata, cooker.status)
rq = runqueue.RunQueue(cooker, localdata, cooker.status, td, tasks)
rq.prepare_runqueue()
rq.execute_runqueue()
except Providers.NoProvider:
print("ERROR: No Provider")
last_exception = Providers.NoProvider
except runqueue.TaskFailure as fnids:
last_exception = runqueue.TaskFailure
except build.FuncFailed as e:
print("ERROR: Couldn't build '%s'" % names)
last_exception = e
build.usage = "<providee>"
def clean( self, params ):
"""Clean a providee"""
self.build( params, "clean" )
clean.usage = "<providee>"
def compile( self, params ):
"""Execute 'compile' on a providee"""
self.build( params, "compile" )
compile.usage = "<providee>"
def configure( self, params ):
"""Execute 'configure' on a providee"""
self.build( params, "configure" )
configure.usage = "<providee>"
def install( self, params ):
"""Execute 'install' on a providee"""
self.build( params, "install" )
install.usage = "<providee>"
def edit( self, params ):
"""Call $EDITOR on a providee"""
name = params[0]
bbfile = self._findProvider( name )
if bbfile is not None:
os.system( "%s %s" % ( os.environ.get( "EDITOR", "vi" ), bbfile ) )
else:
print("ERROR: Nothing provides '%s'" % name)
edit.usage = "<providee>"
def environment( self, params ):
"""Dump out the outer BitBake environment"""
cooker.showEnvironment()
def exit_( self, params ):
"""Leave the BitBake Shell"""
debugOut( "setting leave_mainloop to true" )
global leave_mainloop
leave_mainloop = True
def fetch( self, params ):
"""Fetch a providee"""
self.build( params, "fetch" )
fetch.usage = "<providee>"
def fileBuild( self, params, cmd = "build" ):
"""Parse and build a .bb file"""
global last_exception
name = params[0]
bf = completeFilePath( name )
print("SHELL: Calling '%s' on '%s'" % ( cmd, bf ))
try:
cooker.buildFile(bf, cmd)
except parse.ParseError:
print("ERROR: Unable to open or parse '%s'" % bf)
except build.FuncFailed as e:
print("ERROR: Couldn't build '%s'" % name)
last_exception = e
fileBuild.usage = "<bbfile>"
def fileClean( self, params ):
"""Clean a .bb file"""
self.fileBuild( params, "clean" )
fileClean.usage = "<bbfile>"
def fileEdit( self, params ):
"""Call $EDITOR on a .bb file"""
name = params[0]
os.system( "%s %s" % ( os.environ.get( "EDITOR", "vi" ), completeFilePath( name ) ) )
fileEdit.usage = "<bbfile>"
def fileRebuild( self, params ):
"""Rebuild (clean & build) a .bb file"""
self.fileBuild( params, "rebuild" )
fileRebuild.usage = "<bbfile>"
def fileReparse( self, params ):
"""(re)Parse a bb file"""
bbfile = params[0]
print("SHELL: Parsing '%s'" % bbfile)
parse.update_mtime( bbfile )
cooker.parser.reparse(bbfile)
if False: #fromCache:
print("SHELL: File has not been updated, not reparsing")
else:
print("SHELL: Parsed")
fileReparse.usage = "<bbfile>"
def abort( self, params ):
"""Toggle abort task execution flag (see bitbake -k)"""
cooker.configuration.abort = not cooker.configuration.abort
print("SHELL: Abort Flag is now '%s'" % repr( cooker.configuration.abort ))
def force( self, params ):
"""Toggle force task execution flag (see bitbake -f)"""
cooker.configuration.force = not cooker.configuration.force
print("SHELL: Force Flag is now '%s'" % repr( cooker.configuration.force ))
def help( self, params ):
"""Show a comprehensive list of commands and their purpose"""
print("="*30, "Available Commands", "="*30)
for cmd in sorted(cmds):
function, numparams, usage, helptext = cmds[cmd]
print("| %s | %s" % (usage.ljust(30), helptext))
print("="*78)
def lastError( self, params ):
"""Show the reason or log that was produced by the last BitBake event exception"""
if last_exception is None:
print("SHELL: No Errors yet (Phew)...")
else:
reason, event = last_exception.args
print("SHELL: Reason for the last error: '%s'" % reason)
if ':' in reason:
msg, filename = reason.split( ':' )
filename = filename.strip()
print("SHELL: Dumping log file for last error:")
try:
print(open( filename ).read())
except IOError:
print("ERROR: Couldn't open '%s'" % filename)
def match( self, params ):
"""Dump all files or providers matching a glob expression"""
what, globexpr = params
if what == "files":
self._checkParsed()
for key in globfilter( cooker.status.pkg_fn, globexpr ): print(key)
elif what == "providers":
self._checkParsed()
for key in globfilter( cooker.status.pkg_pn, globexpr ): print(key)
else:
print("Usage: match %s" % self.print_.usage)
match.usage = "<files|providers> <glob>"
def new( self, params ):
"""Create a new .bb file and open the editor"""
dirname, filename = params
packages = '/'.join( data.getVar( "BBFILES", cooker.configuration.data, 1 ).split('/')[:-2] )
fulldirname = "%s/%s" % ( packages, dirname )
if not os.path.exists( fulldirname ):
print("SHELL: Creating '%s'" % fulldirname)
os.mkdir( fulldirname )
if os.path.exists( fulldirname ) and os.path.isdir( fulldirname ):
if os.path.exists( "%s/%s" % ( fulldirname, filename ) ):
print("SHELL: ERROR: %s/%s already exists" % ( fulldirname, filename ))
return False
print("SHELL: Creating '%s/%s'" % ( fulldirname, filename ))
newpackage = open( "%s/%s" % ( fulldirname, filename ), "w" )
print("""DESCRIPTION = ""
SECTION = ""
AUTHOR = ""
HOMEPAGE = ""
MAINTAINER = ""
LICENSE = "GPL"
PR = "r0"
SRC_URI = ""
#inherit base
#do_configure() {
#
#}
#do_compile() {
#
#}
#do_stage() {
#
#}
#do_install() {
#
#}
""", file=newpackage)
newpackage.close()
os.system( "%s %s/%s" % ( os.environ.get( "EDITOR" ), fulldirname, filename ) )
new.usage = "<directory> <filename>"
def package( self, params ):
"""Execute 'package' on a providee"""
self.build( params, "package" )
package.usage = "<providee>"
def pasteBin( self, params ):
"""Send a command + output buffer to the pastebin at http://rafb.net/paste"""
index = params[0]
contents = self._shell.myout.buffer( int( index ) )
sendToPastebin( "output of " + params[0], contents )
pasteBin.usage = "<index>"
def pasteLog( self, params ):
"""Send the last event exception error log (if there is one) to http://rafb.net/paste"""
if last_exception is None:
print("SHELL: No Errors yet (Phew)...")
else:
reason, event = last_exception.args
print("SHELL: Reason for the last error: '%s'" % reason)
if ':' in reason:
msg, filename = reason.split( ':' )
filename = filename.strip()
print("SHELL: Pasting log file to pastebin...")
file = open( filename ).read()
sendToPastebin( "contents of " + filename, file )
def patch( self, params ):
"""Execute 'patch' command on a providee"""
self.build( params, "patch" )
patch.usage = "<providee>"
def parse( self, params ):
"""(Re-)parse .bb files and calculate the dependency graph"""
cooker.status = cache.CacheData(cooker.caches_array)
ignore = data.getVar("ASSUME_PROVIDED", cooker.configuration.data, 1) or ""
cooker.status.ignored_dependencies = set( ignore.split() )
cooker.handleCollections( data.getVar("BBFILE_COLLECTIONS", cooker.configuration.data, 1) )
(filelist, masked) = cooker.collect_bbfiles()
cooker.parse_bbfiles(filelist, masked, cooker.myProgressCallback)
cooker.buildDepgraph()
global parsed
parsed = True
print()
def reparse( self, params ):
"""(re)Parse a providee's bb file"""
bbfile = self._findProvider( params[0] )
if bbfile is not None:
print("SHELL: Found bbfile '%s' for '%s'" % ( bbfile, params[0] ))
self.fileReparse( [ bbfile ] )
else:
print("ERROR: Nothing provides '%s'" % params[0])
reparse.usage = "<providee>"
def getvar( self, params ):
"""Dump the contents of an outer BitBake environment variable"""
var = params[0]
value = data.getVar( var, cooker.configuration.data, 1 )
print(value)
getvar.usage = "<variable>"
def peek( self, params ):
"""Dump contents of variable defined in providee's metadata"""
name, var = params
bbfile = self._findProvider( name )
if bbfile is not None:
the_data = cache.Cache.loadDataFull(bbfile, cooker.configuration.data)
value = the_data.getVar( var, 1 )
print(value)
else:
print("ERROR: Nothing provides '%s'" % name)
peek.usage = "<providee> <variable>"
def poke( self, params ):
"""Set contents of variable defined in providee's metadata"""
name, var, value = params
bbfile = self._findProvider( name )
if bbfile is not None:
print("ERROR: Sorry, this functionality is currently broken")
#d = cooker.pkgdata[bbfile]
#data.setVar( var, value, d )
# mark the change semi persistant
#cooker.pkgdata.setDirty(bbfile, d)
#print "OK"
else:
print("ERROR: Nothing provides '%s'" % name)
poke.usage = "<providee> <variable> <value>"
def print_( self, params ):
"""Dump all files or providers"""
what = params[0]
if what == "files":
self._checkParsed()
for key in cooker.status.pkg_fn: print(key)
elif what == "providers":
self._checkParsed()
for key in cooker.status.providers: print(key)
else:
print("Usage: print %s" % self.print_.usage)
print_.usage = "<files|providers>"
def python( self, params ):
"""Enter the expert mode - an interactive BitBake Python Interpreter"""
sys.ps1 = "EXPERT BB>>> "
sys.ps2 = "EXPERT BB... "
import code
interpreter = code.InteractiveConsole( dict( globals() ) )
interpreter.interact( "SHELL: Expert Mode - BitBake Python %s\nType 'help' for more information, press CTRL-D to switch back to BBSHELL." % sys.version )
def showdata( self, params ):
"""Execute 'showdata' on a providee"""
cooker.showEnvironment(None, params)
showdata.usage = "<providee>"
def setVar( self, params ):
"""Set an outer BitBake environment variable"""
var, value = params
data.setVar( var, value, cooker.configuration.data )
print("OK")
setVar.usage = "<variable> <value>"
def rebuild( self, params ):
"""Clean and rebuild a .bb file or a providee"""
self.build( params, "clean" )
self.build( params, "build" )
rebuild.usage = "<providee>"
def shell( self, params ):
"""Execute a shell command and dump the output"""
if params != "":
print(commands.getoutput( " ".join( params ) ))
shell.usage = "<...>"
def stage( self, params ):
"""Execute 'stage' on a providee"""
self.build( params, "populate_staging" )
stage.usage = "<providee>"
def status( self, params ):
"""<just for testing>"""
print("-" * 78)
print("building list = '%s'" % cooker.building_list)
print("build path = '%s'" % cooker.build_path)
print("consider_msgs_cache = '%s'" % cooker.consider_msgs_cache)
print("build stats = '%s'" % cooker.stats)
if last_exception is not None: print("last_exception = '%s'" % repr( last_exception.args ))
print("memory output contents = '%s'" % self._shell.myout._buffer)
def test( self, params ):
"""<just for testing>"""
print("testCommand called with '%s'" % params)
def unpack( self, params ):
"""Execute 'unpack' on a providee"""
self.build( params, "unpack" )
unpack.usage = "<providee>"
def which( self, params ):
"""Computes the providers for a given providee"""
# Need to use taskData for this information
item = params[0]
self._checkParsed()
preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
if not preferred: preferred = item
try:
lv, lf, pv, pf = Providers.findBestProvider(preferred, cooker.configuration.data, cooker.status)
except KeyError:
lv, lf, pv, pf = (None,)*4
try:
providers = cooker.status.providers[item]
except KeyError:
print("SHELL: ERROR: Nothing provides", preferred)
else:
for provider in providers:
if provider == pf: provider = " (***) %s" % provider
else: provider = " %s" % provider
print(provider)
which.usage = "<providee>"
##########################################################################
# Common helper functions
##########################################################################
def completeFilePath( bbfile ):
"""Get the complete bbfile path"""
if not cooker.status: return bbfile
if not cooker.status.pkg_fn: return bbfile
for key in cooker.status.pkg_fn:
if key.endswith( bbfile ):
return key
return bbfile
def sendToPastebin( desc, content ):
"""Send content to http://oe.pastebin.com"""
mydata = {}
mydata["lang"] = "Plain Text"
mydata["desc"] = desc
mydata["cvt_tabs"] = "No"
mydata["nick"] = "%s@%s" % ( os.environ.get( "USER", "unknown" ), socket.gethostname() or "unknown" )
mydata["text"] = content
params = urllib.urlencode( mydata )
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
host = "rafb.net"
conn = httplib.HTTPConnection( "%s:80" % host )
conn.request("POST", "/paste/paste.php", params, headers )
response = conn.getresponse()
conn.close()
if response.status == 302:
location = response.getheader( "location" ) or "unknown"
print("SHELL: Pasted to http://%s%s" % ( host, location ))
else:
print("ERROR: %s %s" % ( response.status, response.reason ))
def completer( text, state ):
"""Return a possible readline completion"""
debugOut( "completer called with text='%s', state='%d'" % ( text, state ) )
if state == 0:
line = readline.get_line_buffer()
if " " in line:
line = line.split()
# we are in second (or more) argument
if line[0] in cmds and hasattr( cmds[line[0]][0], "usage" ): # known command and usage
u = getattr( cmds[line[0]][0], "usage" ).split()[0]
if u == "<variable>":
allmatches = cooker.configuration.data.keys()
elif u == "<bbfile>":
if cooker.status.pkg_fn is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
else: allmatches = [ x.split("/")[-1] for x in cooker.status.pkg_fn ]
elif u == "<providee>":
if cooker.status.pkg_fn is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
else: allmatches = cooker.status.providers.iterkeys()
else: allmatches = [ "(No tab completion available for this command)" ]
else: allmatches = [ "(No tab completion available for this command)" ]
else:
# we are in first argument
allmatches = cmds.iterkeys()
completer.matches = [ x for x in allmatches if x[:len(text)] == text ]
#print "completer.matches = '%s'" % completer.matches
if len( completer.matches ) > state:
return completer.matches[state]
else:
return None
def debugOut( text ):
if debug:
sys.stderr.write( "( %s )\n" % text )
def columnize( alist, width = 80 ):
"""
A word-wrap function that preserves existing line breaks
and most spaces in the text. Expects that existing line
breaks are posix newlines (\n).
"""
return reduce(lambda line, word, width=width: '%s%s%s' %
(line,
' \n'[(len(line[line.rfind('\n')+1:])
+ len(word.split('\n', 1)[0]
) >= width)],
word),
alist
)
def globfilter( names, pattern ):
return fnmatch.filter( names, pattern )
##########################################################################
# Class MemoryOutput
##########################################################################
class MemoryOutput:
"""File-like output class buffering the output of the last 10 commands"""
def __init__( self, delegate ):
self.delegate = delegate
self._buffer = []
self.text = []
self._command = None
def startCommand( self, command ):
self._command = command
self.text = []
def endCommand( self ):
if self._command is not None:
if len( self._buffer ) == 10: del self._buffer[0]
self._buffer.append( ( self._command, self.text ) )
def removeLast( self ):
if self._buffer:
del self._buffer[ len( self._buffer ) - 1 ]
self.text = []
self._command = None
def lastBuffer( self ):
if self._buffer:
return self._buffer[ len( self._buffer ) -1 ][1]
def bufferedCommands( self ):
return [ cmd for cmd, output in self._buffer ]
def buffer( self, i ):
if i < len( self._buffer ):
return "BB>> %s\n%s" % ( self._buffer[i][0], "".join( self._buffer[i][1] ) )
else: return "ERROR: Invalid buffer number. Buffer needs to be in (0, %d)" % ( len( self._buffer ) - 1 )
def write( self, text ):
if self._command is not None and text != "BB>> ": self.text.append( text )
if self.delegate is not None: self.delegate.write( text )
def flush( self ):
return self.delegate.flush()
def fileno( self ):
return self.delegate.fileno()
def isatty( self ):
return self.delegate.isatty()
##########################################################################
# Class BitBakeShell
##########################################################################
class BitBakeShell:
def __init__( self ):
"""Register commands and set up readline"""
self.commandQ = Queue.Queue()
self.commands = BitBakeShellCommands( self )
self.myout = MemoryOutput( sys.stdout )
self.historyfilename = os.path.expanduser( "~/.bbsh_history" )
self.startupfilename = os.path.expanduser( "~/.bbsh_startup" )
readline.set_completer( completer )
readline.set_completer_delims( " " )
readline.parse_and_bind("tab: complete")
try:
readline.read_history_file( self.historyfilename )
except IOError:
pass # It doesn't exist yet.
print(__credits__)
def cleanup( self ):
"""Write readline history and clean up resources"""
debugOut( "writing command history" )
try:
readline.write_history_file( self.historyfilename )
except:
print("SHELL: Unable to save command history")
def registerCommand( self, command, function, numparams = 0, usage = "", helptext = "" ):
"""Register a command"""
if usage == "": usage = command
if helptext == "": helptext = function.__doc__ or "<not yet documented>"
cmds[command] = ( function, numparams, usage, helptext )
def processCommand( self, command, params ):
"""Process a command. Check number of params and print a usage string, if appropriate"""
debugOut( "processing command '%s'..." % command )
try:
function, numparams, usage, helptext = cmds[command]
except KeyError:
print("SHELL: ERROR: '%s' command is not a valid command." % command)
self.myout.removeLast()
else:
if (numparams != -1) and (not len( params ) == numparams):
print("Usage: '%s'" % usage)
return
result = function( self.commands, params )
debugOut( "result was '%s'" % result )
def processStartupFile( self ):
"""Read and execute all commands found in $HOME/.bbsh_startup"""
if os.path.exists( self.startupfilename ):
startupfile = open( self.startupfilename, "r" )
for cmdline in startupfile:
debugOut( "processing startup line '%s'" % cmdline )
if not cmdline:
continue
if "|" in cmdline:
print("ERROR: '|' in startup file is not allowed. Ignoring line")
continue
self.commandQ.put( cmdline.strip() )
def main( self ):
"""The main command loop"""
while not leave_mainloop:
try:
if self.commandQ.empty():
sys.stdout = self.myout.delegate
cmdline = raw_input( "BB>> " )
sys.stdout = self.myout
else:
cmdline = self.commandQ.get()
if cmdline:
allCommands = cmdline.split( ';' )
for command in allCommands:
pipecmd = None
#
# special case for expert mode
if command == 'python':
sys.stdout = self.myout.delegate
self.processCommand( command, "" )
sys.stdout = self.myout
else:
self.myout.startCommand( command )
if '|' in command: # disable output
command, pipecmd = command.split( '|' )
delegate = self.myout.delegate
self.myout.delegate = None
tokens = shlex.split( command, True )
self.processCommand( tokens[0], tokens[1:] or "" )
self.myout.endCommand()
if pipecmd is not None: # restore output
self.myout.delegate = delegate
pipe = popen2.Popen4( pipecmd )
pipe.tochild.write( "\n".join( self.myout.lastBuffer() ) )
pipe.tochild.close()
sys.stdout.write( pipe.fromchild.read() )
#
except EOFError:
print()
return
except KeyboardInterrupt:
print()
##########################################################################
# Start function - called from the BitBake command line utility
##########################################################################
def start( aCooker ):
global cooker
cooker = aCooker
bbshell = BitBakeShell()
bbshell.processStartupFile()
bbshell.main()
bbshell.cleanup()
if __name__ == "__main__":
print("SHELL: Sorry, this program should only be called by BitBake.")

View File

@@ -3,19 +3,21 @@ import logging
import os
import re
import tempfile
import pickle
import bb.data
import difflib
import simplediff
from bb.checksum import FileChecksumCache
logger = logging.getLogger('BitBake.SigGen')
try:
import cPickle as pickle
except ImportError:
import pickle
logger.info('Importing cPickle failed. Falling back to a very slow implementation.')
def init(d):
siggens = [obj for obj in globals().values()
siggens = [obj for obj in globals().itervalues()
if type(obj) is type and issubclass(obj, SignatureGenerator)]
desired = d.getVar("BB_SIGNATURE_HANDLER") or "noop"
desired = d.getVar("BB_SIGNATURE_HANDLER", True) or "noop"
for sg in siggens:
if desired == sg.name:
return sg(d)
@@ -32,11 +34,9 @@ class SignatureGenerator(object):
name = "noop"
def __init__(self, data):
self.basehash = {}
self.taskhash = {}
self.runtaskdeps = {}
self.file_checksum_values = {}
self.taints = {}
def finalise(self, fn, d, varient):
return
@@ -44,8 +44,7 @@ class SignatureGenerator(object):
def get_taskhash(self, fn, task, deps, dataCache):
return "0"
def writeout_file_checksum_cache(self):
"""Write/update the file checksum cache onto disk"""
def set_taskdata(self, hashes, deps, checksum):
return
def stampfile(self, stampbase, file_name, taskname, extrainfo):
@@ -64,13 +63,10 @@ class SignatureGenerator(object):
return
def get_taskdata(self):
return (self.runtaskdeps, self.taskhash, self.file_checksum_values, self.taints, self.basehash)
return (self.runtaskdeps, self.taskhash, self.file_checksum_values)
def set_taskdata(self, data):
self.runtaskdeps, self.taskhash, self.file_checksum_values, self.taints, self.basehash = data
def reset(self, data):
self.__init__(data)
self.runtaskdeps, self.taskhash, self.file_checksum_values = data
class SignatureGeneratorBasic(SignatureGenerator):
@@ -84,22 +80,15 @@ class SignatureGeneratorBasic(SignatureGenerator):
self.taskdeps = {}
self.runtaskdeps = {}
self.file_checksum_values = {}
self.taints = {}
self.gendeps = {}
self.lookupcache = {}
self.pkgnameextract = re.compile("(?P<fn>.*)\..*")
self.basewhitelist = set((data.getVar("BB_HASHBASE_WHITELIST") or "").split())
self.basewhitelist = set((data.getVar("BB_HASHBASE_WHITELIST", True) or "").split())
self.taskwhitelist = None
self.init_rundepcheck(data)
checksum_cache_file = data.getVar("BB_HASH_CHECKSUM_CACHE_FILE")
if checksum_cache_file:
self.checksum_cache = FileChecksumCache()
self.checksum_cache.init_cache(data, checksum_cache_file)
else:
self.checksum_cache = None
def init_rundepcheck(self, data):
self.taskwhitelist = data.getVar("BB_HASHTASK_WHITELIST") or None
self.taskwhitelist = data.getVar("BB_HASHTASK_WHITELIST", True) or None
if self.taskwhitelist:
self.twl = re.compile(self.taskwhitelist)
else:
@@ -107,7 +96,6 @@ class SignatureGeneratorBasic(SignatureGenerator):
def _build_data(self, fn, d):
ignore_mismatch = ((d.getVar("BB_HASH_IGNORE_MISMATCH") or '') == '1')
tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d)
taskdeps = {}
@@ -140,11 +128,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
var = lookupcache[dep]
if var is not None:
data = data + str(var)
datahash = hashlib.md5(data.encode("utf-8")).hexdigest()
k = fn + "." + task
if not ignore_mismatch and k in self.basehash and self.basehash[k] != datahash:
bb.error("When reparsing %s, the basehash value changed from %s to %s. The metadata is not deterministic and this needs to be fixed." % (k, self.basehash[k], datahash))
self.basehash[k] = datahash
self.basehash[fn + "." + task] = hashlib.md5(data).hexdigest()
taskdeps[task] = alldeps
self.taskdeps[fn] = taskdeps
@@ -155,21 +139,18 @@ class SignatureGeneratorBasic(SignatureGenerator):
def finalise(self, fn, d, variant):
mc = d.getVar("__BBMULTICONFIG", False) or ""
if variant or mc:
fn = bb.cache.realfn2virtual(fn, variant, mc)
if variant:
fn = "virtual:" + variant + ":" + fn
try:
taskdeps = self._build_data(fn, d)
except bb.parse.SkipRecipe:
raise
except:
bb.warn("Error during finalise of %s" % fn)
bb.note("Error during finalise of %s" % fn)
raise
#Slow but can be useful for debugging mismatched basehashes
#for task in self.taskdeps[fn]:
# self.dump_sigtask(fn, task, d.getVar("STAMP"), False)
# self.dump_sigtask(fn, task, d.getVar("STAMP", True), False)
for task in taskdeps:
d.setVar("BB_BASEHASH_task-%s" % task, self.basehash[fn + "." + task])
@@ -195,11 +176,9 @@ class SignatureGeneratorBasic(SignatureGenerator):
def get_taskhash(self, fn, task, deps, dataCache):
k = fn + "." + task
data = dataCache.basetaskhash[k]
self.basehash[k] = data
self.runtaskdeps[k] = []
self.file_checksum_values[k] = []
self.file_checksum_values[k] = {}
recipename = dataCache.pkg_fn[fn]
for dep in sorted(deps, key=clean_basepath):
depname = dataCache.pkg_fn[self.pkgnameextract.search(dep).group('fn')]
if not self.rundep_check(fn, recipename, task, dep, depname, dataCache):
@@ -210,12 +189,9 @@ class SignatureGeneratorBasic(SignatureGenerator):
self.runtaskdeps[k].append(dep)
if task in dataCache.file_checksums[fn]:
if self.checksum_cache:
checksums = self.checksum_cache.get_checksums(dataCache.file_checksums[fn][task], recipename)
else:
checksums = bb.fetch2.get_file_checksums(dataCache.file_checksums[fn][task], recipename)
checksums = bb.fetch2.get_file_checksums(dataCache.file_checksums[fn][task], recipename)
for (f,cs) in checksums:
self.file_checksum_values[k].append((f,cs))
self.file_checksum_values[k][f] = cs
if cs:
data = data + cs
@@ -223,37 +199,22 @@ class SignatureGeneratorBasic(SignatureGenerator):
if 'nostamp' in taskdep and task in taskdep['nostamp']:
# Nostamp tasks need an implicit taint so that they force any dependent tasks to run
import uuid
taint = str(uuid.uuid4())
data = data + taint
self.taints[k] = "nostamp:" + taint
data = data + str(uuid.uuid4())
taint = self.read_taint(fn, task, dataCache.stamp[fn])
if taint:
data = data + taint
self.taints[k] = taint
logger.warning("%s is tainted from a forced run" % k)
logger.warn("%s is tainted from a forced run" % k)
h = hashlib.md5(data.encode("utf-8")).hexdigest()
h = hashlib.md5(data).hexdigest()
self.taskhash[k] = h
#d.setVar("BB_TASKHASH_task-%s" % task, taskhash[task])
return h
def writeout_file_checksum_cache(self):
"""Write/update the file checksum cache onto disk"""
if self.checksum_cache:
self.checksum_cache.save_extras()
self.checksum_cache.save_merge()
else:
bb.fetch2.fetcher_parse_save()
bb.fetch2.fetcher_parse_done()
def dump_sigtask(self, fn, task, stampbase, runtime):
k = fn + "." + task
referencestamp = stampbase
if isinstance(runtime, str) and runtime.startswith("customfile"):
if runtime == "customfile":
sigfile = stampbase
referencestamp = runtime[11:]
elif runtime and k in self.taskhash:
sigfile = stampbase + "." + task + ".sigdata" + "." + self.taskhash[k]
else:
@@ -262,7 +223,6 @@ class SignatureGeneratorBasic(SignatureGenerator):
bb.utils.mkdirhier(os.path.dirname(sigfile))
data = {}
data['task'] = task
data['basewhitelist'] = self.basewhitelist
data['taskwhitelist'] = self.taskwhitelist
data['taskdeps'] = self.taskdeps[fn][task]
@@ -278,35 +238,21 @@ class SignatureGeneratorBasic(SignatureGenerator):
if runtime and k in self.taskhash:
data['runtaskdeps'] = self.runtaskdeps[k]
data['file_checksum_values'] = [(os.path.basename(f), cs) for f,cs in self.file_checksum_values[k]]
data['file_checksum_values'] = [(os.path.basename(f), cs) for f,cs in self.file_checksum_values[k].items()]
data['runtaskhashes'] = {}
for dep in data['runtaskdeps']:
data['runtaskhashes'][dep] = self.taskhash[dep]
data['taskhash'] = self.taskhash[k]
taint = self.read_taint(fn, task, referencestamp)
taint = self.read_taint(fn, task, stampbase)
if taint:
data['taint'] = taint
if runtime and k in self.taints:
if 'nostamp:' in self.taints[k]:
data['taint'] = self.taints[k]
computed_basehash = calc_basehash(data)
if computed_basehash != self.basehash[k]:
bb.error("Basehash mismatch %s versus %s for %s" % (computed_basehash, self.basehash[k], k))
if runtime and k in self.taskhash:
computed_taskhash = calc_taskhash(data)
if computed_taskhash != self.taskhash[k]:
bb.error("Taskhash mismatch %s versus %s for %s" % (computed_taskhash, self.taskhash[k], k))
sigfile = sigfile.replace(self.taskhash[k], computed_taskhash)
fd, tmpfile = tempfile.mkstemp(dir=os.path.dirname(sigfile), prefix="sigtask.")
try:
with os.fdopen(fd, "wb") as stream:
p = pickle.dump(data, stream, -1)
stream.flush()
os.chmod(tmpfile, 0o664)
os.chmod(tmpfile, 0664)
os.rename(tmpfile, sigfile)
except (OSError, IOError) as err:
try:
@@ -315,18 +261,16 @@ class SignatureGeneratorBasic(SignatureGenerator):
pass
raise err
def dump_sigfn(self, fn, dataCaches, options):
if fn in self.taskdeps:
def dump_sigs(self, dataCache, options):
for fn in self.taskdeps:
for task in self.taskdeps[fn]:
tid = fn + ":" + task
(mc, _, _) = bb.runqueue.split_tid(tid)
k = fn + "." + task
if k not in self.taskhash:
continue
if dataCaches[mc].basetaskhash[k] != self.basehash[k]:
if dataCache.basetaskhash[k] != self.basehash[k]:
bb.error("Bitbake's cached basehash does not match the one we just generated (%s)!" % k)
bb.error("The mismatched hashes were %s and %s" % (dataCaches[mc].basetaskhash[k], self.basehash[k]))
self.dump_sigtask(fn, task, dataCaches[mc].stamp[fn], True)
bb.error("The mismatched hashes were %s and %s" % (dataCache.basetaskhash[k], self.basehash[k]))
self.dump_sigtask(fn, task, dataCache.stamp[fn], True)
class SignatureGeneratorBasicHash(SignatureGeneratorBasic):
name = "basichash"
@@ -354,71 +298,14 @@ class SignatureGeneratorBasicHash(SignatureGeneratorBasic):
def dump_this_task(outfile, d):
import bb.parse
fn = d.getVar("BB_FILENAME")
task = "do_" + d.getVar("BB_CURRENTTASK")
referencestamp = bb.build.stamp_internal(task, d, None, True)
bb.parse.siggen.dump_sigtask(fn, task, outfile, "customfile:" + referencestamp)
def init_colors(enable_color):
"""Initialise colour dict for passing to compare_sigfiles()"""
# First set up the colours
colors = {'color_title': '\033[1;37;40m',
'color_default': '\033[0;37;40m',
'color_add': '\033[1;32;40m',
'color_remove': '\033[1;31;40m',
}
# Leave all keys present but clear the values
if not enable_color:
for k in colors.keys():
colors[k] = ''
return colors
def worddiff_str(oldstr, newstr, colors=None):
if not colors:
colors = init_colors(False)
diff = simplediff.diff(oldstr.split(' '), newstr.split(' '))
ret = []
for change, value in diff:
value = ' '.join(value)
if change == '=':
ret.append(value)
elif change == '+':
item = '{color_add}{{+{value}+}}{color_default}'.format(value=value, **colors)
ret.append(item)
elif change == '-':
item = '{color_remove}[-{value}-]{color_default}'.format(value=value, **colors)
ret.append(item)
whitespace_note = ''
if oldstr != newstr and ' '.join(oldstr.split()) == ' '.join(newstr.split()):
whitespace_note = ' (whitespace changed)'
return '"%s"%s' % (' '.join(ret), whitespace_note)
def list_inline_diff(oldlist, newlist, colors=None):
if not colors:
colors = init_colors(False)
diff = simplediff.diff(oldlist, newlist)
ret = []
for change, value in diff:
value = ' '.join(value)
if change == '=':
ret.append("'%s'" % value)
elif change == '+':
item = '{color_add}+{value}{color_default}'.format(value=value, **colors)
ret.append(item)
elif change == '-':
item = '{color_remove}-{value}{color_default}'.format(value=value, **colors)
ret.append(item)
return '[%s]' % (', '.join(ret))
fn = d.getVar("BB_FILENAME", True)
task = "do_" + d.getVar("BB_CURRENTTASK", True)
bb.parse.siggen.dump_sigtask(fn, task, outfile, "customfile")
def clean_basepath(a):
mc = None
if a.startswith("multiconfig:"):
_, mc, a = a.split(":", 2)
b = a.rsplit("/", 2)[1] + '/' + a.rsplit("/", 2)[2]
b = a.rsplit("/", 2)[1] + a.rsplit("/", 2)[2]
if a.startswith("virtual:"):
b = b + ":" + a.rsplit(":", 1)[0]
if mc:
b = b + ":multiconfig:" + mc
return b
def clean_basepaths(a):
@@ -433,32 +320,13 @@ def clean_basepaths_list(a):
b.append(clean_basepath(x))
return b
def compare_sigfiles(a, b, recursecb=None, color=False, collapsed=False):
def compare_sigfiles(a, b, recursecb = None):
output = []
colors = init_colors(color)
def color_format(formatstr, **values):
"""
Return colour formatted string.
NOTE: call with the format string, not an already formatted string
containing values (otherwise you could have trouble with { and }
characters)
"""
if not formatstr.endswith('{color_default}'):
formatstr += '{color_default}'
# In newer python 3 versions you can pass both of these directly,
# but we only require 3.4 at the moment
formatparams = {}
formatparams.update(colors)
formatparams.update(values)
return formatstr.format(**formatparams)
with open(a, 'rb') as f:
p1 = pickle.Unpickler(f)
a_data = p1.load()
with open(b, 'rb') as f:
p2 = pickle.Unpickler(f)
b_data = p2.load()
p1 = pickle.Unpickler(open(a, "rb"))
a_data = p1.load()
p2 = pickle.Unpickler(open(b, "rb"))
b_data = p2.load()
def dict_diff(a, b, whitelist=set()):
sa = set(a.keys())
@@ -506,100 +374,61 @@ def compare_sigfiles(a, b, recursecb=None, color=False, collapsed=False):
return changed, added, removed
if 'basewhitelist' in a_data and a_data['basewhitelist'] != b_data['basewhitelist']:
output.append(color_format("{color_title}basewhitelist changed{color_default} from '%s' to '%s'") % (a_data['basewhitelist'], b_data['basewhitelist']))
output.append("basewhitelist changed from '%s' to '%s'" % (a_data['basewhitelist'], b_data['basewhitelist']))
if a_data['basewhitelist'] and b_data['basewhitelist']:
output.append("changed items: %s" % a_data['basewhitelist'].symmetric_difference(b_data['basewhitelist']))
if 'taskwhitelist' in a_data and a_data['taskwhitelist'] != b_data['taskwhitelist']:
output.append(color_format("{color_title}taskwhitelist changed{color_default} from '%s' to '%s'") % (a_data['taskwhitelist'], b_data['taskwhitelist']))
output.append("taskwhitelist changed from '%s' to '%s'" % (a_data['taskwhitelist'], b_data['taskwhitelist']))
if a_data['taskwhitelist'] and b_data['taskwhitelist']:
output.append("changed items: %s" % a_data['taskwhitelist'].symmetric_difference(b_data['taskwhitelist']))
if a_data['taskdeps'] != b_data['taskdeps']:
output.append(color_format("{color_title}Task dependencies changed{color_default} from:\n%s\nto:\n%s") % (sorted(a_data['taskdeps']), sorted(b_data['taskdeps'])))
output.append("Task dependencies changed from:\n%s\nto:\n%s" % (sorted(a_data['taskdeps']), sorted(b_data['taskdeps'])))
if a_data['basehash'] != b_data['basehash'] and not collapsed:
output.append(color_format("{color_title}basehash changed{color_default} from %s to %s") % (a_data['basehash'], b_data['basehash']))
if a_data['basehash'] != b_data['basehash']:
output.append("basehash changed from %s to %s" % (a_data['basehash'], b_data['basehash']))
changed, added, removed = dict_diff(a_data['gendeps'], b_data['gendeps'], a_data['basewhitelist'] & b_data['basewhitelist'])
if changed:
for dep in changed:
output.append(color_format("{color_title}List of dependencies for variable %s changed from '{color_default}%s{color_title}' to '{color_default}%s{color_title}'") % (dep, a_data['gendeps'][dep], b_data['gendeps'][dep]))
output.append("List of dependencies for variable %s changed from '%s' to '%s'" % (dep, a_data['gendeps'][dep], b_data['gendeps'][dep]))
if a_data['gendeps'][dep] and b_data['gendeps'][dep]:
output.append("changed items: %s" % a_data['gendeps'][dep].symmetric_difference(b_data['gendeps'][dep]))
if added:
for dep in added:
output.append(color_format("{color_title}Dependency on variable %s was added") % (dep))
output.append("Dependency on variable %s was added" % (dep))
if removed:
for dep in removed:
output.append(color_format("{color_title}Dependency on Variable %s was removed") % (dep))
output.append("Dependency on Variable %s was removed" % (dep))
changed, added, removed = dict_diff(a_data['varvals'], b_data['varvals'])
if changed:
for dep in changed:
oldval = a_data['varvals'][dep]
newval = b_data['varvals'][dep]
if newval and oldval and ('\n' in oldval or '\n' in newval):
diff = difflib.unified_diff(oldval.splitlines(), newval.splitlines(), lineterm='')
# Cut off the first two lines, since we aren't interested in
# the old/new filename (they are blank anyway in this case)
difflines = list(diff)[2:]
if color:
# Add colour to diff output
for i, line in enumerate(difflines):
if line.startswith('+'):
line = color_format('{color_add}{line}', line=line)
difflines[i] = line
elif line.startswith('-'):
line = color_format('{color_remove}{line}', line=line)
difflines[i] = line
output.append(color_format("{color_title}Variable {var} value changed:{color_default}\n{diff}", var=dep, diff='\n'.join(difflines)))
elif newval and oldval and (' ' in oldval or ' ' in newval):
output.append(color_format("{color_title}Variable {var} value changed:{color_default}\n{diff}", var=dep, diff=worddiff_str(oldval, newval, colors)))
else:
output.append(color_format("{color_title}Variable {var} value changed from '{color_default}{oldval}{color_title}' to '{color_default}{newval}{color_title}'{color_default}", var=dep, oldval=oldval, newval=newval))
if not 'file_checksum_values' in a_data:
a_data['file_checksum_values'] = {}
if not 'file_checksum_values' in b_data:
b_data['file_checksum_values'] = {}
output.append("Variable %s value changed from '%s' to '%s'" % (dep, a_data['varvals'][dep], b_data['varvals'][dep]))
changed, added, removed = file_checksums_diff(a_data['file_checksum_values'], b_data['file_checksum_values'])
if changed:
for f, old, new in changed:
output.append(color_format("{color_title}Checksum for file %s changed{color_default} from %s to %s") % (f, old, new))
output.append("Checksum for file %s changed from %s to %s" % (f, old, new))
if added:
for f in added:
output.append(color_format("{color_title}Dependency on checksum of file %s was added") % (f))
output.append("Dependency on checksum of file %s was added" % (f))
if removed:
for f in removed:
output.append(color_format("{color_title}Dependency on checksum of file %s was removed") % (f))
output.append("Dependency on checksum of file %s was removed" % (f))
if not 'runtaskdeps' in a_data:
a_data['runtaskdeps'] = {}
if not 'runtaskdeps' in b_data:
b_data['runtaskdeps'] = {}
changed = []
for idx, task in enumerate(a_data['runtaskdeps']):
a = a_data['runtaskdeps'][idx]
b = b_data['runtaskdeps'][idx]
if a_data['runtaskhashes'][a] != b_data['runtaskhashes'][b]:
changed.append("%s with hash %s\n changed to\n%s with hash %s" % (a, a_data['runtaskhashes'][a], b, b_data['runtaskhashes'][b]))
if not collapsed:
if len(a_data['runtaskdeps']) != len(b_data['runtaskdeps']):
changed = ["Number of task dependencies changed"]
else:
changed = []
for idx, task in enumerate(a_data['runtaskdeps']):
a = a_data['runtaskdeps'][idx]
b = b_data['runtaskdeps'][idx]
if a_data['runtaskhashes'][a] != b_data['runtaskhashes'][b] and not collapsed:
changed.append("%s with hash %s\n changed to\n%s with hash %s" % (clean_basepath(a), a_data['runtaskhashes'][a], clean_basepath(b), b_data['runtaskhashes'][b]))
if changed:
clean_a = clean_basepaths_list(a_data['runtaskdeps'])
clean_b = clean_basepaths_list(b_data['runtaskdeps'])
if clean_a != clean_b:
output.append(color_format("{color_title}runtaskdeps changed:{color_default}\n%s") % list_inline_diff(clean_a, clean_b, colors))
else:
output.append(color_format("{color_title}runtaskdeps changed:"))
output.append("\n".join(changed))
if changed:
output.append("runtaskdeps changed from %s to %s" % (clean_basepaths_list(a_data['runtaskdeps']), clean_basepaths_list(b_data['runtaskdeps'])))
output.append("\n".join(changed))
if 'runtaskhashes' in a_data and 'runtaskhashes' in b_data:
@@ -615,7 +444,7 @@ def compare_sigfiles(a, b, recursecb=None, color=False, collapsed=False):
#output.append("Dependency on task %s was replaced by %s with same hash" % (dep, bdep))
bdep_found = True
if not bdep_found:
output.append(color_format("{color_title}Dependency on task %s was added{color_default} with hash %s") % (clean_basepath(dep), b[dep]))
output.append("Dependency on task %s was added with hash %s" % (clean_basepath(dep), b[dep]))
if removed:
for dep in removed:
adep_found = False
@@ -625,70 +454,30 @@ def compare_sigfiles(a, b, recursecb=None, color=False, collapsed=False):
#output.append("Dependency on task %s was replaced by %s with same hash" % (adep, dep))
adep_found = True
if not adep_found:
output.append(color_format("{color_title}Dependency on task %s was removed{color_default} with hash %s") % (clean_basepath(dep), a[dep]))
output.append("Dependency on task %s was removed with hash %s" % (clean_basepath(dep), a[dep]))
if changed:
for dep in changed:
if not collapsed:
output.append(color_format("{color_title}Hash for dependent task %s changed{color_default} from %s to %s") % (clean_basepath(dep), a[dep], b[dep]))
output.append("Hash for dependent task %s changed from %s to %s" % (clean_basepath(dep), a[dep], b[dep]))
if callable(recursecb):
# If a dependent hash changed, might as well print the line above and then defer to the changes in
# that hash since in all likelyhood, they're the same changes this task also saw.
recout = recursecb(dep, a[dep], b[dep])
if recout:
if collapsed:
output.extend(recout)
else:
# If a dependent hash changed, might as well print the line above and then defer to the changes in
# that hash since in all likelyhood, they're the same changes this task also saw.
output = [output[-1]] + recout
output = [output[-1]] + recout
a_taint = a_data.get('taint', None)
b_taint = b_data.get('taint', None)
if a_taint != b_taint:
output.append(color_format("{color_title}Taint (by forced/invalidated task) changed{color_default} from %s to %s") % (a_taint, b_taint))
output.append("Taint (by forced/invalidated task) changed from %s to %s" % (a_taint, b_taint))
return output
def calc_basehash(sigdata):
task = sigdata['task']
basedata = sigdata['varvals'][task]
if basedata is None:
basedata = ''
alldeps = sigdata['taskdeps']
for dep in alldeps:
basedata = basedata + dep
val = sigdata['varvals'][dep]
if val is not None:
basedata = basedata + str(val)
return hashlib.md5(basedata.encode("utf-8")).hexdigest()
def calc_taskhash(sigdata):
data = sigdata['basehash']
for dep in sigdata['runtaskdeps']:
data = data + sigdata['runtaskhashes'][dep]
for c in sigdata['file_checksum_values']:
if c[1]:
data = data + c[1]
if 'taint' in sigdata:
if 'nostamp:' in sigdata['taint']:
data = data + sigdata['taint'][8:]
else:
data = data + sigdata['taint']
return hashlib.md5(data.encode("utf-8")).hexdigest()
def dump_sigfile(a):
output = []
with open(a, 'rb') as f:
p1 = pickle.Unpickler(f)
a_data = p1.load()
p1 = pickle.Unpickler(open(a, "rb"))
a_data = p1.load()
output.append("basewhitelist: %s" % (a_data['basewhitelist']))
@@ -717,13 +506,17 @@ def dump_sigfile(a):
if 'taint' in a_data:
output.append("Tainted (by forced/invalidated task): %s" % a_data['taint'])
if 'task' in a_data:
computed_basehash = calc_basehash(a_data)
output.append("Computed base hash is %s and from file %s" % (computed_basehash, a_data['basehash']))
else:
output.append("Unable to compute base hash")
data = a_data['basehash']
for dep in a_data['runtaskdeps']:
data = data + a_data['runtaskhashes'][dep]
computed_taskhash = calc_taskhash(a_data)
output.append("Computed task hash is %s" % computed_taskhash)
for c in a_data['file_checksum_values']:
data = data + c[1]
if 'taint' in a_data:
data = data + a_data['taint']
h = hashlib.md5(data).hexdigest()
output.append("Computed Hash is %s" % h)
return output

View File

@@ -37,24 +37,27 @@ def re_match_strings(target, strings):
return any(name == target or re.match(name, target)
for name in strings)
class TaskEntry:
def __init__(self):
self.tdepends = []
self.idepends = []
self.irdepends = []
class TaskData:
"""
BitBake Task Data implementation
"""
def __init__(self, abort = True, skiplist = None, allowincomplete = False):
def __init__(self, abort = True, tryaltconfigs = False, skiplist = None):
self.build_names_index = []
self.run_names_index = []
self.fn_index = []
self.build_targets = {}
self.run_targets = {}
self.external_targets = []
self.seenfns = []
self.taskentries = {}
self.tasks_fnid = []
self.tasks_name = []
self.tasks_tdepends = []
self.tasks_idepends = []
self.tasks_irdepends = []
# Cache to speed up task ID lookups
self.tasks_lookup = {}
self.depids = {}
self.rdepids = {}
@@ -63,13 +66,95 @@ class TaskData:
self.failed_deps = []
self.failed_rdeps = []
self.failed_fns = []
self.failed_fnids = []
self.abort = abort
self.allowincomplete = allowincomplete
self.tryaltconfigs = tryaltconfigs
self.skiplist = skiplist
def getbuild_id(self, name):
"""
Return an ID number for the build target name.
If it doesn't exist, create one.
"""
if not name in self.build_names_index:
self.build_names_index.append(name)
return len(self.build_names_index) - 1
return self.build_names_index.index(name)
def getrun_id(self, name):
"""
Return an ID number for the run target name.
If it doesn't exist, create one.
"""
if not name in self.run_names_index:
self.run_names_index.append(name)
return len(self.run_names_index) - 1
return self.run_names_index.index(name)
def getfn_id(self, name):
"""
Return an ID number for the filename.
If it doesn't exist, create one.
"""
if not name in self.fn_index:
self.fn_index.append(name)
return len(self.fn_index) - 1
return self.fn_index.index(name)
def gettask_ids(self, fnid):
"""
Return an array of the ID numbers matching a given fnid.
"""
ids = []
if fnid in self.tasks_lookup:
for task in self.tasks_lookup[fnid]:
ids.append(self.tasks_lookup[fnid][task])
return ids
def gettask_id_fromfnid(self, fnid, task):
"""
Return an ID number for the task matching fnid and task.
"""
if fnid in self.tasks_lookup:
if task in self.tasks_lookup[fnid]:
return self.tasks_lookup[fnid][task]
return None
def gettask_id(self, fn, task, create = True):
"""
Return an ID number for the task matching fn and task.
If it doesn't exist, create one by default.
Optionally return None instead.
"""
fnid = self.getfn_id(fn)
if fnid in self.tasks_lookup:
if task in self.tasks_lookup[fnid]:
return self.tasks_lookup[fnid][task]
if not create:
return None
self.tasks_name.append(task)
self.tasks_fnid.append(fnid)
self.tasks_tdepends.append([])
self.tasks_idepends.append([])
self.tasks_irdepends.append([])
listid = len(self.tasks_name) - 1
if fnid not in self.tasks_lookup:
self.tasks_lookup[fnid] = {}
self.tasks_lookup[fnid][task] = listid
return listid
def add_tasks(self, fn, dataCache):
"""
Add tasks for a given fn to the database
@@ -77,60 +162,58 @@ class TaskData:
task_deps = dataCache.task_deps[fn]
if fn in self.failed_fns:
fnid = self.getfn_id(fn)
if fnid in self.failed_fnids:
bb.msg.fatal("TaskData", "Trying to re-add a failed file? Something is broken...")
# Check if we've already seen this fn
if fn in self.seenfns:
if fnid in self.tasks_fnid:
return
self.seenfns.append(fn)
self.add_extra_deps(fn, dataCache)
# Common code for dep_name/depends = 'depends'/idepends and 'rdepends'/irdepends
def handle_deps(task, dep_name, depends, seen):
if dep_name in task_deps and task in task_deps[dep_name]:
ids = []
for dep in task_deps[dep_name][task].split():
if dep:
parts = dep.split(":")
if len(parts) != 2:
bb.msg.fatal("TaskData", "Error for %s:%s[%s], dependency %s in '%s' does not contain exactly one ':' character.\n Task '%s' should be specified in the form 'packagename:task'" % (fn, task, dep_name, dep, task_deps[dep_name][task], dep_name))
ids.append((parts[0], parts[1]))
seen(parts[0])
depends.extend(ids)
for task in task_deps['tasks']:
tid = "%s:%s" % (fn, task)
self.taskentries[tid] = TaskEntry()
# Work out task dependencies
parentids = []
for dep in task_deps['parents'][task]:
if dep not in task_deps['tasks']:
bb.debug(2, "Not adding dependeny of %s on %s since %s does not exist" % (task, dep, dep))
continue
parentid = "%s:%s" % (fn, dep)
parentid = self.gettask_id(fn, dep)
parentids.append(parentid)
self.taskentries[tid].tdepends.extend(parentids)
taskid = self.gettask_id(fn, task)
self.tasks_tdepends[taskid].extend(parentids)
# Touch all intertask dependencies
handle_deps(task, 'depends', self.taskentries[tid].idepends, self.seen_build_target)
handle_deps(task, 'rdepends', self.taskentries[tid].irdepends, self.seen_run_target)
if 'depends' in task_deps and task in task_deps['depends']:
ids = []
for dep in task_deps['depends'][task].split():
if dep:
if ":" not in dep:
bb.msg.fatal("TaskData", "Error for %s, dependency %s does not contain ':' character\n. Task 'depends' should be specified in the form 'packagename:task'" % (fn, dep))
ids.append(((self.getbuild_id(dep.split(":")[0])), dep.split(":")[1]))
self.tasks_idepends[taskid].extend(ids)
if 'rdepends' in task_deps and task in task_deps['rdepends']:
ids = []
for dep in task_deps['rdepends'][task].split():
if dep:
if ":" not in dep:
bb.msg.fatal("TaskData", "Error for %s, dependency %s does not contain ':' character\n. Task 'rdepends' should be specified in the form 'packagename:task'" % (fn, dep))
ids.append(((self.getrun_id(dep.split(":")[0])), dep.split(":")[1]))
self.tasks_irdepends[taskid].extend(ids)
# Work out build dependencies
if not fn in self.depids:
dependids = set()
if not fnid in self.depids:
dependids = {}
for depend in dataCache.deps[fn]:
dependids.add(depend)
self.depids[fn] = list(dependids)
dependids[self.getbuild_id(depend)] = None
self.depids[fnid] = dependids.keys()
logger.debug(2, "Added dependencies %s for %s", str(dataCache.deps[fn]), fn)
# Work out runtime dependencies
if not fn in self.rdepids:
rdependids = set()
if not fnid in self.rdepids:
rdependids = {}
rdepends = dataCache.rundeps[fn]
rrecs = dataCache.runrecs[fn]
rdependlist = []
@@ -138,48 +221,33 @@ class TaskData:
for package in rdepends:
for rdepend in rdepends[package]:
rdependlist.append(rdepend)
rdependids.add(rdepend)
rdependids[self.getrun_id(rdepend)] = None
for package in rrecs:
for rdepend in rrecs[package]:
rreclist.append(rdepend)
rdependids.add(rdepend)
rdependids[self.getrun_id(rdepend)] = None
if rdependlist:
logger.debug(2, "Added runtime dependencies %s for %s", str(rdependlist), fn)
if rreclist:
logger.debug(2, "Added runtime recommendations %s for %s", str(rreclist), fn)
self.rdepids[fn] = list(rdependids)
self.rdepids[fnid] = rdependids.keys()
for dep in self.depids[fn]:
self.seen_build_target(dep)
for dep in self.depids[fnid]:
if dep in self.failed_deps:
self.fail_fn(fn)
self.fail_fnid(fnid)
return
for dep in self.rdepids[fn]:
self.seen_run_target(dep)
for dep in self.rdepids[fnid]:
if dep in self.failed_rdeps:
self.fail_fn(fn)
self.fail_fnid(fnid)
return
def add_extra_deps(self, fn, dataCache):
func = dataCache.extradepsfunc.get(fn, None)
if func:
bb.providers.buildWorldTargetList(dataCache)
pn = dataCache.pkg_fn[fn]
params = {'deps': dataCache.deps[fn],
'world_target': dataCache.world_target,
'pkg_pn': dataCache.pkg_pn,
'self_pn': pn}
funcname = '_%s_calculate_extra_depends' % pn.replace('-', '_')
paramlist = ','.join(params.keys())
func = 'def %s(%s):\n%s\n\n%s(%s)' % (funcname, paramlist, func, funcname, paramlist)
bb.utils.better_exec(func, params)
def have_build_target(self, target):
"""
Have we a build target matching this name?
"""
if target in self.build_targets and self.build_targets[target]:
targetid = self.getbuild_id(target)
if targetid in self.build_targets:
return True
return False
@@ -187,54 +255,50 @@ class TaskData:
"""
Have we a runtime target matching this name?
"""
if target in self.run_targets and self.run_targets[target]:
targetid = self.getrun_id(target)
if targetid in self.run_targets:
return True
return False
def seen_build_target(self, name):
"""
Maintain a list of build targets
"""
if name not in self.build_targets:
self.build_targets[name] = []
def add_build_target(self, fn, item):
"""
Add a build target.
If already present, append the provider fn to the list
"""
if item in self.build_targets:
if fn in self.build_targets[item]:
return
self.build_targets[item].append(fn)
return
self.build_targets[item] = [fn]
targetid = self.getbuild_id(item)
fnid = self.getfn_id(fn)
def seen_run_target(self, name):
"""
Maintain a list of runtime build targets
"""
if name not in self.run_targets:
self.run_targets[name] = []
if targetid in self.build_targets:
if fnid in self.build_targets[targetid]:
return
self.build_targets[targetid].append(fnid)
return
self.build_targets[targetid] = [fnid]
def add_runtime_target(self, fn, item):
"""
Add a runtime target.
If already present, append the provider fn to the list
"""
if item in self.run_targets:
if fn in self.run_targets[item]:
return
self.run_targets[item].append(fn)
return
self.run_targets[item] = [fn]
targetid = self.getrun_id(item)
fnid = self.getfn_id(fn)
def mark_external_target(self, target):
if targetid in self.run_targets:
if fnid in self.run_targets[targetid]:
return
self.run_targets[targetid].append(fnid)
return
self.run_targets[targetid] = [fnid]
def mark_external_target(self, item):
"""
Mark a build target as being externally requested
"""
if target not in self.external_targets:
self.external_targets.append(target)
targetid = self.getbuild_id(item)
if targetid not in self.external_targets:
self.external_targets.append(targetid)
def get_unresolved_build_targets(self, dataCache):
"""
@@ -242,12 +306,12 @@ class TaskData:
are unknown.
"""
unresolved = []
for target in self.build_targets:
for target in self.build_names_index:
if re_match_strings(target, dataCache.ignored_dependencies):
continue
if target in self.failed_deps:
if self.build_names_index.index(target) in self.failed_deps:
continue
if not self.build_targets[target]:
if not self.have_build_target(target):
unresolved.append(target)
return unresolved
@@ -257,12 +321,12 @@ class TaskData:
are unknown.
"""
unresolved = []
for target in self.run_targets:
for target in self.run_names_index:
if re_match_strings(target, dataCache.ignored_dependencies):
continue
if target in self.failed_rdeps:
if self.run_names_index.index(target) in self.failed_rdeps:
continue
if not self.run_targets[target]:
if not self.have_runtime_target(target):
unresolved.append(target)
return unresolved
@@ -270,26 +334,50 @@ class TaskData:
"""
Return a list of providers of item
"""
return self.build_targets[item]
targetid = self.getbuild_id(item)
def get_dependees(self, item):
return self.build_targets[targetid]
def get_dependees(self, itemid):
"""
Return a list of targets which depend on item
"""
dependees = []
for fn in self.depids:
if item in self.depids[fn]:
dependees.append(fn)
for fnid in self.depids:
if itemid in self.depids[fnid]:
dependees.append(fnid)
return dependees
def get_rdependees(self, item):
def get_dependees_str(self, item):
"""
Return a list of targets which depend on item as a user readable string
"""
itemid = self.getbuild_id(item)
dependees = []
for fnid in self.depids:
if itemid in self.depids[fnid]:
dependees.append(self.fn_index[fnid])
return dependees
def get_rdependees(self, itemid):
"""
Return a list of targets which depend on runtime item
"""
dependees = []
for fn in self.rdepids:
if item in self.rdepids[fn]:
dependees.append(fn)
for fnid in self.rdepids:
if itemid in self.rdepids[fnid]:
dependees.append(fnid)
return dependees
def get_rdependees_str(self, item):
"""
Return a list of targets which depend on runtime item as a user readable string
"""
itemid = self.getrun_id(item)
dependees = []
for fnid in self.rdepids:
if itemid in self.rdepids[fnid]:
dependees.append(self.fn_index[fnid])
return dependees
def get_reasons(self, item, runtime=False):
@@ -325,7 +413,7 @@ class TaskData:
except bb.providers.NoProvider:
if self.abort:
raise
self.remove_buildtarget(item)
self.remove_buildtarget(self.getbuild_id(item))
self.mark_external_target(item)
@@ -340,14 +428,7 @@ class TaskData:
return
if not item in dataCache.providers:
close_matches = self.get_close_matches(item, list(dataCache.providers.keys()))
# Is it in RuntimeProviders ?
all_p = bb.providers.getRuntimeProviders(dataCache, item)
for fn in all_p:
new = dataCache.pkg_fn[fn] + " RPROVIDES " + item
if new not in close_matches:
close_matches.append(new)
bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees(item), reasons=self.get_reasons(item), close_matches=close_matches), cfgData)
bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item), reasons=self.get_reasons(item), close_matches=self.get_close_matches(item, dataCache.providers.keys())), cfgData)
raise bb.providers.NoProvider(item)
if self.have_build_target(item):
@@ -356,10 +437,10 @@ class TaskData:
all_p = dataCache.providers[item]
eligible, foundUnique = bb.providers.filterProviders(all_p, item, cfgData, dataCache)
eligible = [p for p in eligible if not p in self.failed_fns]
eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids]
if not eligible:
bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees(item), reasons=["No eligible PROVIDERs exist for '%s'" % item]), cfgData)
bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees_str(item), reasons=["No eligible PROVIDERs exist for '%s'" % item]), cfgData)
raise bb.providers.NoProvider(item)
if len(eligible) > 1 and foundUnique == False:
@@ -371,7 +452,8 @@ class TaskData:
self.consider_msgs_cache.append(item)
for fn in eligible:
if fn in self.failed_fns:
fnid = self.getfn_id(fn)
if fnid in self.failed_fnids:
continue
logger.debug(2, "adding %s to satisfy %s", fn, item)
self.add_build_target(fn, item)
@@ -395,14 +477,14 @@ class TaskData:
all_p = bb.providers.getRuntimeProviders(dataCache, item)
if not all_p:
bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees(item), reasons=self.get_reasons(item, True)), cfgData)
bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item), reasons=self.get_reasons(item, True)), cfgData)
raise bb.providers.NoRProvider(item)
eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache)
eligible = [p for p in eligible if not p in self.failed_fns]
eligible = [p for p in eligible if not self.getfn_id(p) in self.failed_fnids]
if not eligible:
bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees(item), reasons=["No eligible RPROVIDERs exist for '%s'" % item]), cfgData)
bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees_str(item), reasons=["No eligible RPROVIDERs exist for '%s'" % item]), cfgData)
raise bb.providers.NoRProvider(item)
if len(eligible) > 1 and numberPreferred == 0:
@@ -424,80 +506,80 @@ class TaskData:
# run through the list until we find one that we can build
for fn in eligible:
if fn in self.failed_fns:
fnid = self.getfn_id(fn)
if fnid in self.failed_fnids:
continue
logger.debug(2, "adding '%s' to satisfy runtime '%s'", fn, item)
self.add_runtime_target(fn, item)
self.add_tasks(fn, dataCache)
def fail_fn(self, fn, missing_list=None):
def fail_fnid(self, fnid, missing_list = []):
"""
Mark a file as failed (unbuildable)
Remove any references from build and runtime provider lists
missing_list, A list of missing requirements for this target
"""
if fn in self.failed_fns:
if fnid in self.failed_fnids:
return
if not missing_list:
missing_list = []
logger.debug(1, "File '%s' is unbuildable, removing...", fn)
self.failed_fns.append(fn)
logger.debug(1, "File '%s' is unbuildable, removing...", self.fn_index[fnid])
self.failed_fnids.append(fnid)
for target in self.build_targets:
if fn in self.build_targets[target]:
self.build_targets[target].remove(fn)
if fnid in self.build_targets[target]:
self.build_targets[target].remove(fnid)
if len(self.build_targets[target]) == 0:
self.remove_buildtarget(target, missing_list)
for target in self.run_targets:
if fn in self.run_targets[target]:
self.run_targets[target].remove(fn)
if fnid in self.run_targets[target]:
self.run_targets[target].remove(fnid)
if len(self.run_targets[target]) == 0:
self.remove_runtarget(target, missing_list)
def remove_buildtarget(self, target, missing_list=None):
def remove_buildtarget(self, targetid, missing_list = []):
"""
Mark a build target as failed (unbuildable)
Trigger removal of any files that have this as a dependency
"""
if not missing_list:
missing_list = [target]
missing_list = [self.build_names_index[targetid]]
else:
missing_list = [target] + missing_list
logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
self.failed_deps.append(target)
dependees = self.get_dependees(target)
for fn in dependees:
self.fail_fn(fn, missing_list)
for tid in self.taskentries:
for (idepend, idependtask) in self.taskentries[tid].idepends:
if idepend == target:
fn = tid.rsplit(":",1)[0]
self.fail_fn(fn, missing_list)
missing_list = [self.build_names_index[targetid]] + missing_list
logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", self.build_names_index[targetid], missing_list)
self.failed_deps.append(targetid)
dependees = self.get_dependees(targetid)
for fnid in dependees:
self.fail_fnid(fnid, missing_list)
for taskid in xrange(len(self.tasks_idepends)):
idepends = self.tasks_idepends[taskid]
for (idependid, idependtask) in idepends:
if idependid == targetid:
self.fail_fnid(self.tasks_fnid[taskid], missing_list)
if self.abort and target in self.external_targets:
if self.abort and targetid in self.external_targets:
target = self.build_names_index[targetid]
logger.error("Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s", target, missing_list)
raise bb.providers.NoProvider(target)
def remove_runtarget(self, target, missing_list=None):
def remove_runtarget(self, targetid, missing_list = []):
"""
Mark a run target as failed (unbuildable)
Trigger removal of any files that have this as a dependency
"""
if not missing_list:
missing_list = [target]
missing_list = [self.run_names_index[targetid]]
else:
missing_list = [target] + missing_list
missing_list = [self.run_names_index[targetid]] + missing_list
logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
self.failed_rdeps.append(target)
dependees = self.get_rdependees(target)
for fn in dependees:
self.fail_fn(fn, missing_list)
for tid in self.taskentries:
for (idepend, idependtask) in self.taskentries[tid].irdepends:
if idepend == target:
fn = tid.rsplit(":",1)[0]
self.fail_fn(fn, missing_list)
logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", self.run_names_index[targetid], missing_list)
self.failed_rdeps.append(targetid)
dependees = self.get_rdependees(targetid)
for fnid in dependees:
self.fail_fnid(fnid, missing_list)
for taskid in xrange(len(self.tasks_irdepends)):
irdepends = self.tasks_irdepends[taskid]
for (idependid, idependtask) in irdepends:
if idependid == targetid:
self.fail_fnid(self.tasks_fnid[taskid], missing_list)
def add_unresolved(self, cfgData, dataCache):
"""
@@ -511,68 +593,59 @@ class TaskData:
self.add_provider_internal(cfgData, dataCache, target)
added = added + 1
except bb.providers.NoProvider:
if self.abort and target in self.external_targets and not self.allowincomplete:
targetid = self.getbuild_id(target)
if self.abort and targetid in self.external_targets:
raise
if not self.allowincomplete:
self.remove_buildtarget(target)
self.remove_buildtarget(targetid)
for target in self.get_unresolved_run_targets(dataCache):
try:
self.add_rprovider(cfgData, dataCache, target)
added = added + 1
except (bb.providers.NoRProvider, bb.providers.MultipleRProvider):
self.remove_runtarget(target)
self.remove_runtarget(self.getrun_id(target))
logger.debug(1, "Resolved " + str(added) + " extra dependencies")
if added == 0:
break
# self.dump_data()
def get_providermap(self, prefix=None):
provmap = {}
for name in self.build_targets:
if prefix and not name.startswith(prefix):
continue
if self.have_build_target(name):
provider = self.get_provider(name)
if provider:
provmap[name] = provider[0]
return provmap
def dump_data(self):
"""
Dump some debug information on the internal data structures
"""
logger.debug(3, "build_names:")
logger.debug(3, ", ".join(self.build_targets))
logger.debug(3, ", ".join(self.build_names_index))
logger.debug(3, "run_names:")
logger.debug(3, ", ".join(self.run_targets))
logger.debug(3, ", ".join(self.run_names_index))
logger.debug(3, "build_targets:")
for target in self.build_targets:
for buildid in xrange(len(self.build_names_index)):
target = self.build_names_index[buildid]
targets = "None"
if target in self.build_targets:
targets = self.build_targets[target]
logger.debug(3, " %s: %s", target, targets)
if buildid in self.build_targets:
targets = self.build_targets[buildid]
logger.debug(3, " (%s)%s: %s", buildid, target, targets)
logger.debug(3, "run_targets:")
for target in self.run_targets:
for runid in xrange(len(self.run_names_index)):
target = self.run_names_index[runid]
targets = "None"
if target in self.run_targets:
targets = self.run_targets[target]
logger.debug(3, " %s: %s", target, targets)
if runid in self.run_targets:
targets = self.run_targets[runid]
logger.debug(3, " (%s)%s: %s", runid, target, targets)
logger.debug(3, "tasks:")
for tid in self.taskentries:
logger.debug(3, " %s: %s %s %s",
tid,
self.taskentries[tid].idepends,
self.taskentries[tid].irdepends,
self.taskentries[tid].tdepends)
for task in xrange(len(self.tasks_name)):
logger.debug(3, " (%s)%s - %s: %s",
task,
self.fn_index[self.tasks_fnid[task]],
self.tasks_name[task],
self.tasks_tdepends[task])
logger.debug(3, "dependency ids (per fn):")
for fn in self.depids:
logger.debug(3, " %s: %s", fn, self.depids[fn])
for fnid in self.depids:
logger.debug(3, " %s %s: %s", fnid, self.fn_index[fnid], self.depids[fnid])
logger.debug(3, "runtime dependency ids (per fn):")
for fn in self.rdepids:
logger.debug(3, " %s: %s", fn, self.rdepids[fn])
for fnid in self.rdepids:
logger.debug(3, " %s %s: %s", fnid, self.fn_index[fnid], self.rdepids[fnid])

View File

@@ -49,9 +49,6 @@ class ReferenceTest(unittest.TestCase):
def assertExecs(self, execs):
self.assertEqual(self.execs, execs)
def assertContains(self, contains):
self.assertEqual(self.contains, contains)
class VariableReferenceTest(ReferenceTest):
def parseExpression(self, exp):
@@ -71,7 +68,7 @@ class VariableReferenceTest(ReferenceTest):
def test_python_reference(self):
self.setEmptyVars(["BAR"])
self.parseExpression("${@d.getVar('BAR') + 'foo'}")
self.parseExpression("${@bb.data.getVar('BAR', d, True) + 'foo'}")
self.assertReferences(set(["BAR"]))
class ShellReferenceTest(ReferenceTest):
@@ -194,8 +191,8 @@ class PythonReferenceTest(ReferenceTest):
if hasattr(bb.utils, "_context"):
self.context = bb.utils._context
else:
import builtins
self.context = builtins.__dict__
import __builtin__
self.context = __builtin__.__dict__
def parseExpression(self, exp):
parsedvar = self.d.expandWithRefs(exp, None)
@@ -204,7 +201,6 @@ class PythonReferenceTest(ReferenceTest):
self.references = parsedvar.references | parser.references
self.execs = parser.execs
self.contains = parser.contains
@staticmethod
def indent(value):
@@ -213,17 +209,17 @@ be. These unit tests are testing snippets."""
return " " + value
def test_getvar_reference(self):
self.parseExpression("d.getVar('foo')")
self.parseExpression("bb.data.getVar('foo', d, True)")
self.assertReferences(set(["foo"]))
self.assertExecs(set())
def test_getvar_computed_reference(self):
self.parseExpression("d.getVar('f' + 'o' + 'o')")
self.parseExpression("bb.data.getVar('f' + 'o' + 'o', d, True)")
self.assertReferences(set())
self.assertExecs(set())
def test_getvar_exec_reference(self):
self.parseExpression("eval('d.getVar(\"foo\")')")
self.parseExpression("eval('bb.data.getVar(\"foo\", d, True)')")
self.assertReferences(set())
self.assertExecs(set(["eval"]))
@@ -269,35 +265,15 @@ be. These unit tests are testing snippets."""
self.assertExecs(set(["testget"]))
del self.context["testget"]
def test_contains(self):
self.parseExpression('bb.utils.contains("TESTVAR", "one", "true", "false", d)')
self.assertContains({'TESTVAR': {'one'}})
def test_contains_multi(self):
self.parseExpression('bb.utils.contains("TESTVAR", "one two", "true", "false", d)')
self.assertContains({'TESTVAR': {'one two'}})
def test_contains_any(self):
self.parseExpression('bb.utils.contains_any("TESTVAR", "hello", "true", "false", d)')
self.assertContains({'TESTVAR': {'hello'}})
def test_contains_any_multi(self):
self.parseExpression('bb.utils.contains_any("TESTVAR", "one two three", "true", "false", d)')
self.assertContains({'TESTVAR': {'one', 'two', 'three'}})
def test_contains_filter(self):
self.parseExpression('bb.utils.filter("TESTVAR", "hello there world", d)')
self.assertContains({'TESTVAR': {'hello', 'there', 'world'}})
class DependencyReferenceTest(ReferenceTest):
pydata = """
d.getVar('somevar')
bb.data.getVar('somevar', d, True)
def test(d):
foo = 'bar %s' % 'foo'
def test2(d):
d.getVar(foo)
d.getVar(foo, True)
d.getVar('bar', False)
test2(d)
@@ -309,24 +285,19 @@ def a():
test(d)
d.expand(d.getVar("something", False))
d.expand("${inexpand} somethingelse")
d.getVar(a(), False)
bb.data.expand(bb.data.getVar("something", False, d), d)
bb.data.expand("${inexpand} somethingelse", d)
bb.data.getVar(a(), d, False)
"""
def test_python(self):
self.d.setVar("FOO", self.pydata)
self.setEmptyVars(["inexpand", "a", "test2", "test"])
self.d.setVarFlags("FOO", {
"func": True,
"python": True,
"lineno": 1,
"filename": "example.bb",
})
self.d.setVarFlags("FOO", {"func": True, "python": True})
deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
self.assertEqual(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"]))
self.assertEquals(deps, set(["somevar", "bar", "something", "inexpand", "test", "test2", "a"]))
shelldata = """
@@ -373,7 +344,7 @@ esac
deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
self.assertEqual(deps, set(["somevar", "inverted"] + execs))
self.assertEquals(deps, set(["somevar", "inverted"] + execs))
def test_vardeps(self):
@@ -383,7 +354,7 @@ esac
deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
self.assertEqual(deps, set(["oe_libinstall"]))
self.assertEquals(deps, set(["oe_libinstall"]))
def test_vardeps_expand(self):
self.d.setVar("oe_libinstall", "echo test")
@@ -392,31 +363,7 @@ esac
deps, values = bb.data.build_dependencies("FOO", set(self.d.keys()), set(), set(), self.d)
self.assertEqual(deps, set(["oe_libinstall"]))
def test_contains_vardeps(self):
expr = '${@bb.utils.filter("TESTVAR", "somevalue anothervalue", d)} \
${@bb.utils.contains("TESTVAR", "testval testval2", "yetanothervalue", "", d)} \
${@bb.utils.contains("TESTVAR", "testval2 testval3", "blah", "", d)} \
${@bb.utils.contains_any("TESTVAR", "testval2 testval3", "lastone", "", d)}'
parsedvar = self.d.expandWithRefs(expr, None)
# Check contains
self.assertEqual(parsedvar.contains, {'TESTVAR': {'testval2 testval3', 'anothervalue', 'somevalue', 'testval testval2', 'testval2', 'testval3'}})
# Check dependencies
self.d.setVar('ANOTHERVAR', expr)
self.d.setVar('TESTVAR', 'anothervalue testval testval2')
deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), self.d)
self.assertEqual(sorted(values.splitlines()),
sorted([expr,
'TESTVAR{anothervalue} = Set',
'TESTVAR{somevalue} = Unset',
'TESTVAR{testval testval2} = Set',
'TESTVAR{testval2 testval3} = Unset',
'TESTVAR{testval2} = Set',
'TESTVAR{testval3} = Unset'
]))
# Check final value
self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['anothervalue', 'yetanothervalue', 'lastone'])
self.assertEquals(deps, set(["oe_libinstall"]))
#Currently no wildcard support
#def test_vardeps_wildcards(self):

View File

@@ -34,14 +34,14 @@ class COWTestCase(unittest.TestCase):
from bb.COW import COWDictBase
a = COWDictBase.copy()
self.assertEqual(False, 'a' in a)
self.assertEquals(False, a.has_key('a'))
a['a'] = 'a'
a['b'] = 'b'
self.assertEqual(True, 'a' in a)
self.assertEqual(True, 'b' in a)
self.assertEqual('a', a['a'] )
self.assertEqual('b', a['b'] )
self.assertEquals(True, a.has_key('a'))
self.assertEquals(True, a.has_key('b'))
self.assertEquals('a', a['a'] )
self.assertEquals('b', a['b'] )
def testCopyCopy(self):
"""
@@ -60,31 +60,31 @@ class COWTestCase(unittest.TestCase):
c['a'] = 30
# test separation of the two instances
self.assertEqual(False, 'c' in c)
self.assertEqual(30, c['a'])
self.assertEqual(10, b['a'])
self.assertEquals(False, c.has_key('c'))
self.assertEquals(30, c['a'])
self.assertEquals(10, b['a'])
# test copy
b_2 = b.copy()
c_2 = c.copy()
self.assertEqual(False, 'c' in c_2)
self.assertEqual(10, b_2['a'])
self.assertEquals(False, c_2.has_key('c'))
self.assertEquals(10, b_2['a'])
b_2['d'] = 40
self.assertEqual(False, 'd' in c_2)
self.assertEqual(True, 'd' in b_2)
self.assertEqual(40, b_2['d'])
self.assertEqual(False, 'd' in b)
self.assertEqual(False, 'd' in c)
self.assertEquals(False, c_2.has_key('d'))
self.assertEquals(True, b_2.has_key('d'))
self.assertEquals(40, b_2['d'])
self.assertEquals(False, b.has_key('d'))
self.assertEquals(False, c.has_key('d'))
c_2['d'] = 30
self.assertEqual(True, 'd' in c_2)
self.assertEqual(True, 'd' in b_2)
self.assertEqual(30, c_2['d'])
self.assertEqual(40, b_2['d'])
self.assertEqual(False, 'd' in b)
self.assertEqual(False, 'd' in c)
self.assertEquals(True, c_2.has_key('d'))
self.assertEquals(True, b_2.has_key('d'))
self.assertEquals(30, c_2['d'])
self.assertEquals(40, b_2['d'])
self.assertEquals(False, b.has_key('d'))
self.assertEquals(False, c.has_key('d'))
# test copy of the copy
c_3 = c_2.copy()
@@ -92,19 +92,19 @@ class COWTestCase(unittest.TestCase):
b_3_2 = b_2.copy()
c_3['e'] = 4711
self.assertEqual(4711, c_3['e'])
self.assertEqual(False, 'e' in c_2)
self.assertEqual(False, 'e' in b_3)
self.assertEqual(False, 'e' in b_3_2)
self.assertEqual(False, 'e' in b_2)
self.assertEquals(4711, c_3['e'])
self.assertEquals(False, c_2.has_key('e'))
self.assertEquals(False, b_3.has_key('e'))
self.assertEquals(False, b_3_2.has_key('e'))
self.assertEquals(False, b_2.has_key('e'))
b_3['e'] = 'viel'
self.assertEqual('viel', b_3['e'])
self.assertEqual(4711, c_3['e'])
self.assertEqual(False, 'e' in c_2)
self.assertEqual(True, 'e' in b_3)
self.assertEqual(False, 'e' in b_3_2)
self.assertEqual(False, 'e' in b_2)
self.assertEquals('viel', b_3['e'])
self.assertEquals(4711, c_3['e'])
self.assertEquals(False, c_2.has_key('e'))
self.assertEquals(True, b_3.has_key('e'))
self.assertEquals(False, b_3_2.has_key('e'))
self.assertEquals(False, b_2.has_key('e'))
def testCow(self):
from bb.COW import COWDictBase
@@ -115,12 +115,12 @@ class COWTestCase(unittest.TestCase):
copy = c.copy()
self.assertEqual(1027, c['123'])
self.assertEqual(4711, c['other'])
self.assertEqual({'abc':10, 'bcd':20}, c['d'])
self.assertEqual(1027, copy['123'])
self.assertEqual(4711, copy['other'])
self.assertEqual({'abc':10, 'bcd':20}, copy['d'])
self.assertEquals(1027, c['123'])
self.assertEquals(4711, c['other'])
self.assertEquals({'abc':10, 'bcd':20}, c['d'])
self.assertEquals(1027, copy['123'])
self.assertEquals(4711, copy['other'])
self.assertEquals({'abc':10, 'bcd':20}, copy['d'])
# cow it now
copy['123'] = 1028
@@ -128,9 +128,9 @@ class COWTestCase(unittest.TestCase):
copy['d']['abc'] = 20
self.assertEqual(1027, c['123'])
self.assertEqual(4711, c['other'])
self.assertEqual({'abc':10, 'bcd':20}, c['d'])
self.assertEqual(1028, copy['123'])
self.assertEqual(4712, copy['other'])
self.assertEqual({'abc':20, 'bcd':20}, copy['d'])
self.assertEquals(1027, c['123'])
self.assertEquals(4711, c['other'])
self.assertEquals({'abc':10, 'bcd':20}, c['d'])
self.assertEquals(1028, copy['123'])
self.assertEquals(4712, copy['other'])
self.assertEquals({'abc':20, 'bcd':20}, copy['d'])

View File

@@ -24,30 +24,6 @@ import unittest
import bb
import bb.data
import bb.parse
import logging
class LogRecord():
def __enter__(self):
logs = []
class LogHandler(logging.Handler):
def emit(self, record):
logs.append(record)
logger = logging.getLogger("BitBake")
handler = LogHandler()
self.handler = handler
logger.addHandler(handler)
return logs
def __exit__(self, type, value, traceback):
logger = logging.getLogger("BitBake")
logger.removeHandler(self.handler)
return
def logContains(item, logs):
for l in logs:
m = l.getMessage()
if item in m:
return True
return False
class DataExpansions(unittest.TestCase):
def setUp(self):
@@ -77,14 +53,9 @@ class DataExpansions(unittest.TestCase):
self.assertEqual(str(val), "boo value_of_foo")
def test_python_snippet_getvar(self):
val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
val = self.d.expand("${@d.getVar('foo', True) + ' ${bar}'}")
self.assertEqual(str(val), "value_of_foo value_of_bar")
def test_python_unexpanded(self):
self.d.setVar("bar", "${unsetvar}")
val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
self.assertEqual(str(val), "${@d.getVar('foo') + ' ${unsetvar}'}")
def test_python_snippet_syntax_error(self):
self.d.setVar("FOO", "${@foo = 5}")
self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
@@ -99,7 +70,7 @@ class DataExpansions(unittest.TestCase):
self.assertRaises(bb.data_smart.ExpansionError, self.d.getVar, "FOO", True)
def test_value_containing_value(self):
val = self.d.expand("${@d.getVar('foo') + ' ${bar}'}")
val = self.d.expand("${@d.getVar('foo', True) + ' ${bar}'}")
self.assertEqual(str(val), "value_of_foo value_of_bar")
def test_reference_undefined_var(self):
@@ -109,7 +80,7 @@ class DataExpansions(unittest.TestCase):
def test_double_reference(self):
self.d.setVar("BAR", "bar value")
self.d.setVar("FOO", "${BAR} foo ${BAR}")
val = self.d.getVar("FOO")
val = self.d.getVar("FOO", True)
self.assertEqual(str(val), "bar value foo bar value")
def test_direct_recursion(self):
@@ -129,32 +100,32 @@ class DataExpansions(unittest.TestCase):
def test_incomplete_varexp_single_quotes(self):
self.d.setVar("FOO", "sed -i -e 's:IP{:I${:g' $pc")
val = self.d.getVar("FOO")
val = self.d.getVar("FOO", True)
self.assertEqual(str(val), "sed -i -e 's:IP{:I${:g' $pc")
def test_nonstring(self):
self.d.setVar("TEST", 5)
val = self.d.getVar("TEST")
val = self.d.getVar("TEST", True)
self.assertEqual(str(val), "5")
def test_rename(self):
self.d.renameVar("foo", "newfoo")
self.assertEqual(self.d.getVar("newfoo", False), "value_of_foo")
self.assertEqual(self.d.getVar("foo", False), None)
self.assertEqual(self.d.getVar("newfoo"), "value_of_foo")
self.assertEqual(self.d.getVar("foo"), None)
def test_deletion(self):
self.d.delVar("foo")
self.assertEqual(self.d.getVar("foo", False), None)
self.assertEqual(self.d.getVar("foo"), None)
def test_keys(self):
keys = list(self.d.keys())
self.assertCountEqual(keys, ['value_of_foo', 'foo', 'bar'])
keys = self.d.keys()
self.assertEqual(keys, ['value_of_foo', 'foo', 'bar'])
def test_keys_deletion(self):
newd = bb.data.createCopy(self.d)
newd.delVar("bar")
keys = list(newd.keys())
self.assertCountEqual(keys, ['value_of_foo', 'foo'])
keys = newd.keys()
self.assertEqual(keys, ['value_of_foo', 'foo'])
class TestNestedExpansions(unittest.TestCase):
def setUp(self):
@@ -201,28 +172,28 @@ class TestMemoize(unittest.TestCase):
def test_memoized(self):
d = bb.data.init()
d.setVar("FOO", "bar")
self.assertTrue(d.getVar("FOO", False) is d.getVar("FOO", False))
self.assertTrue(d.getVar("FOO") is d.getVar("FOO"))
def test_not_memoized(self):
d1 = bb.data.init()
d2 = bb.data.init()
d1.setVar("FOO", "bar")
d2.setVar("FOO", "bar2")
self.assertTrue(d1.getVar("FOO", False) is not d2.getVar("FOO", False))
self.assertTrue(d1.getVar("FOO") is not d2.getVar("FOO"))
def test_changed_after_memoized(self):
d = bb.data.init()
d.setVar("foo", "value of foo")
self.assertEqual(str(d.getVar("foo", False)), "value of foo")
self.assertEqual(str(d.getVar("foo")), "value of foo")
d.setVar("foo", "second value of foo")
self.assertEqual(str(d.getVar("foo", False)), "second value of foo")
self.assertEqual(str(d.getVar("foo")), "second value of foo")
def test_same_value(self):
d = bb.data.init()
d.setVar("foo", "value of")
d.setVar("bar", "value of")
self.assertEqual(d.getVar("foo", False),
d.getVar("bar", False))
self.assertEqual(d.getVar("foo"),
d.getVar("bar"))
class TestConcat(unittest.TestCase):
def setUp(self):
@@ -234,19 +205,19 @@ class TestConcat(unittest.TestCase):
def test_prepend(self):
self.d.setVar("TEST", "${VAL}")
self.d.prependVar("TEST", "${FOO}:")
self.assertEqual(self.d.getVar("TEST"), "foo:val")
self.assertEqual(self.d.getVar("TEST", True), "foo:val")
def test_append(self):
self.d.setVar("TEST", "${VAL}")
self.d.appendVar("TEST", ":${BAR}")
self.assertEqual(self.d.getVar("TEST"), "val:bar")
self.assertEqual(self.d.getVar("TEST", True), "val:bar")
def test_multiple_append(self):
self.d.setVar("TEST", "${VAL}")
self.d.prependVar("TEST", "${FOO}:")
self.d.appendVar("TEST", ":val2")
self.d.appendVar("TEST", ":${BAR}")
self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
self.assertEqual(self.d.getVar("TEST", True), "foo:val:val2:bar")
class TestConcatOverride(unittest.TestCase):
def setUp(self):
@@ -258,66 +229,55 @@ class TestConcatOverride(unittest.TestCase):
def test_prepend(self):
self.d.setVar("TEST", "${VAL}")
self.d.setVar("TEST_prepend", "${FOO}:")
self.assertEqual(self.d.getVar("TEST"), "foo:val")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "foo:val")
def test_append(self):
self.d.setVar("TEST", "${VAL}")
self.d.setVar("TEST_append", ":${BAR}")
self.assertEqual(self.d.getVar("TEST"), "val:bar")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "val:bar")
def test_multiple_append(self):
self.d.setVar("TEST", "${VAL}")
self.d.setVar("TEST_prepend", "${FOO}:")
self.d.setVar("TEST_append", ":val2")
self.d.setVar("TEST_append", ":${BAR}")
self.assertEqual(self.d.getVar("TEST"), "foo:val:val2:bar")
def test_append_unset(self):
self.d.setVar("TEST_prepend", "${FOO}:")
self.d.setVar("TEST_append", ":val2")
self.d.setVar("TEST_append", ":${BAR}")
self.assertEqual(self.d.getVar("TEST"), "foo::val2:bar")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "foo:val:val2:bar")
def test_remove(self):
self.d.setVar("TEST", "${VAL} ${BAR}")
self.d.setVar("TEST_remove", "val")
self.assertEqual(self.d.getVar("TEST"), "bar")
def test_remove_cleared(self):
self.d.setVar("TEST", "${VAL} ${BAR}")
self.d.setVar("TEST_remove", "val")
self.d.setVar("TEST", "${VAL} ${BAR}")
self.assertEqual(self.d.getVar("TEST"), "val bar")
# Ensure the value is unchanged if we have an inactive remove override
# (including that whitespace is preserved)
def test_remove_inactive_override(self):
self.d.setVar("TEST", "${VAL} ${BAR} 123")
self.d.setVar("TEST_remove_inactiveoverride", "val")
self.assertEqual(self.d.getVar("TEST"), "val bar 123")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "bar")
def test_doubleref_remove(self):
self.d.setVar("TEST", "${VAL} ${BAR}")
self.d.setVar("TEST_remove", "val")
self.d.setVar("TEST_TEST", "${TEST} ${TEST}")
self.assertEqual(self.d.getVar("TEST_TEST"), "bar bar")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST_TEST", True), "bar bar")
def test_empty_remove(self):
self.d.setVar("TEST", "")
self.d.setVar("TEST_remove", "val")
self.assertEqual(self.d.getVar("TEST"), "")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "")
def test_remove_expansion(self):
self.d.setVar("BAR", "Z")
self.d.setVar("TEST", "${BAR}/X Y")
self.d.setVar("TEST_remove", "${BAR}/X")
self.assertEqual(self.d.getVar("TEST"), "Y")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "Y")
def test_remove_expansion_items(self):
self.d.setVar("TEST", "A B C D")
self.d.setVar("BAR", "B D")
self.d.setVar("TEST_remove", "${BAR}")
self.assertEqual(self.d.getVar("TEST"), "A C")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "A C")
class TestOverrides(unittest.TestCase):
def setUp(self):
@@ -326,67 +286,21 @@ class TestOverrides(unittest.TestCase):
self.d.setVar("TEST", "testvalue")
def test_no_override(self):
self.assertEqual(self.d.getVar("TEST"), "testvalue")
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "testvalue")
def test_one_override(self):
self.d.setVar("TEST_bar", "testvalue2")
self.assertEqual(self.d.getVar("TEST"), "testvalue2")
def test_one_override_unset(self):
self.d.setVar("TEST2_bar", "testvalue2")
self.assertEqual(self.d.getVar("TEST2"), "testvalue2")
self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST2', 'OVERRIDES', 'TEST2_bar'])
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "testvalue2")
def test_multiple_override(self):
self.d.setVar("TEST_bar", "testvalue2")
self.d.setVar("TEST_local", "testvalue3")
self.d.setVar("TEST_foo", "testvalue4")
self.assertEqual(self.d.getVar("TEST"), "testvalue3")
self.assertCountEqual(list(self.d.keys()), ['TEST', 'TEST_foo', 'OVERRIDES', 'TEST_bar', 'TEST_local'])
bb.data.update_data(self.d)
self.assertEqual(self.d.getVar("TEST", True), "testvalue3")
def test_multiple_combined_overrides(self):
self.d.setVar("TEST_local_foo_bar", "testvalue3")
self.assertEqual(self.d.getVar("TEST"), "testvalue3")
def test_multiple_overrides_unset(self):
self.d.setVar("TEST2_local_foo_bar", "testvalue3")
self.assertEqual(self.d.getVar("TEST2"), "testvalue3")
def test_keyexpansion_override(self):
self.d.setVar("LOCAL", "local")
self.d.setVar("TEST_bar", "testvalue2")
self.d.setVar("TEST_${LOCAL}", "testvalue3")
self.d.setVar("TEST_foo", "testvalue4")
bb.data.expandKeys(self.d)
self.assertEqual(self.d.getVar("TEST"), "testvalue3")
def test_rename_override(self):
self.d.setVar("ALTERNATIVE_ncurses-tools_class-target", "a")
self.d.setVar("OVERRIDES", "class-target")
self.d.renameVar("ALTERNATIVE_ncurses-tools", "ALTERNATIVE_lib32-ncurses-tools")
self.assertEqual(self.d.getVar("ALTERNATIVE_lib32-ncurses-tools"), "a")
def test_underscore_override(self):
self.d.setVar("TEST_bar", "testvalue2")
self.d.setVar("TEST_some_val", "testvalue3")
self.d.setVar("TEST_foo", "testvalue4")
self.d.setVar("OVERRIDES", "foo:bar:some_val")
self.assertEqual(self.d.getVar("TEST"), "testvalue3")
class TestKeyExpansion(unittest.TestCase):
def setUp(self):
self.d = bb.data.init()
self.d.setVar("FOO", "foo")
self.d.setVar("BAR", "foo")
def test_keyexpand(self):
self.d.setVar("VAL_${FOO}", "A")
self.d.setVar("VAL_${BAR}", "B")
with LogRecord() as logs:
bb.data.expandKeys(self.d)
self.assertTrue(logContains("Variable key VAL_${FOO} (A) replaces original key VAL_foo (B)", logs))
self.assertEqual(self.d.getVar("VAL_foo"), "A")
class TestFlags(unittest.TestCase):
def setUp(self):
@@ -396,13 +310,13 @@ class TestFlags(unittest.TestCase):
self.d.setVarFlag("foo", "flag2", "value of flag2")
def test_setflag(self):
self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
self.assertEqual(self.d.getVarFlag("foo", "flag2", False), "value of flag2")
self.assertEqual(self.d.getVarFlag("foo", "flag1"), "value of flag1")
self.assertEqual(self.d.getVarFlag("foo", "flag2"), "value of flag2")
def test_delflag(self):
self.d.delVarFlag("foo", "flag2")
self.assertEqual(self.d.getVarFlag("foo", "flag1", False), "value of flag1")
self.assertEqual(self.d.getVarFlag("foo", "flag2", False), None)
self.assertEqual(self.d.getVarFlag("foo", "flag1"), "value of flag1")
self.assertEqual(self.d.getVarFlag("foo", "flag2"), None)
class Contains(unittest.TestCase):
@@ -441,167 +355,3 @@ class Contains(unittest.TestCase):
self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x", True, False, self.d))
self.assertFalse(bb.utils.contains_any("SOMEFLAG", "x y z", True, False, self.d))
class Serialize(unittest.TestCase):
def test_serialize(self):
import tempfile
import pickle
d = bb.data.init()
d.enableTracking()
d.setVar('HELLO', 'world')
d.setVarFlag('HELLO', 'other', 'planet')
with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
tmpfilename = tmpfile.name
pickle.dump(d, tmpfile)
with open(tmpfilename, 'rb') as f:
newd = pickle.load(f)
os.remove(tmpfilename)
self.assertEqual(d, newd)
self.assertEqual(newd.getVar('HELLO'), 'world')
self.assertEqual(newd.getVarFlag('HELLO', 'other'), 'planet')
# Remote datastore tests
# These really only test the interface, since in actual usage we have a
# tinfoil connector that does everything over RPC, and this doesn't test
# that.
class TestConnector:
d = None
def __init__(self, d):
self.d = d
def getVar(self, name):
return self.d._findVar(name)
def getKeys(self):
return set(self.d.keys())
def getVarHistory(self, name):
return self.d.varhistory.variable(name)
def expandPythonRef(self, varname, expr, d):
localdata = self.d.createCopy()
for key in d.localkeys():
localdata.setVar(d.getVar(key))
varparse = bb.data_smart.VariableParse(varname, localdata)
return varparse.python_sub(expr)
def setVar(self, name, value):
self.d.setVar(name, value)
def setVarFlag(self, name, flag, value):
self.d.setVarFlag(name, flag, value)
def delVar(self, name):
self.d.delVar(name)
return False
def delVarFlag(self, name, flag):
self.d.delVarFlag(name, flag)
return False
def renameVar(self, name, newname):
self.d.renameVar(name, newname)
return False
class Remote(unittest.TestCase):
def test_remote(self):
d1 = bb.data.init()
d1.enableTracking()
d2 = bb.data.init()
d2.enableTracking()
connector = TestConnector(d1)
d2.setVar('_remote_data', connector)
d1.setVar('HELLO', 'world')
d1.setVarFlag('OTHER', 'flagname', 'flagvalue')
self.assertEqual(d2.getVar('HELLO'), 'world')
self.assertEqual(d2.expand('${HELLO}'), 'world')
self.assertEqual(d2.expand('${@d.getVar("HELLO")}'), 'world')
self.assertIn('flagname', d2.getVarFlags('OTHER'))
self.assertEqual(d2.getVarFlag('OTHER', 'flagname'), 'flagvalue')
self.assertEqual(d1.varhistory.variable('HELLO'), d2.varhistory.variable('HELLO'))
# Test setVar on client side affects server
d2.setVar('HELLO', 'other-world')
self.assertEqual(d1.getVar('HELLO'), 'other-world')
# Test setVarFlag on client side affects server
d2.setVarFlag('HELLO', 'flagname', 'flagvalue')
self.assertEqual(d1.getVarFlag('HELLO', 'flagname'), 'flagvalue')
# Test client side data is incorporated in python expansion (which is done on server)
d2.setVar('FOO', 'bar')
self.assertEqual(d2.expand('${@d.getVar("FOO")}'), 'bar')
# Test overrides work
d1.setVar('FOO_test', 'baz')
d1.appendVar('OVERRIDES', ':test')
self.assertEqual(d2.getVar('FOO'), 'baz')
# Remote equivalents of local test classes
# Note that these aren't perfect since we only test in one direction
class RemoteDataExpansions(DataExpansions):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1["foo"] = "value_of_foo"
self.d1["bar"] = "value_of_bar"
self.d1["value_of_foo"] = "value_of_'value_of_foo'"
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteNestedExpansions(TestNestedExpansions):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1["foo"] = "foo"
self.d1["bar"] = "bar"
self.d1["value_of_foobar"] = "187"
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteConcat(TestConcat):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1.setVar("FOO", "foo")
self.d1.setVar("VAL", "val")
self.d1.setVar("BAR", "bar")
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteConcatOverride(TestConcatOverride):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1.setVar("FOO", "foo")
self.d1.setVar("VAL", "val")
self.d1.setVar("BAR", "bar")
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteOverrides(TestOverrides):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1.setVar("OVERRIDES", "foo:bar:local")
self.d1.setVar("TEST", "testvalue")
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteKeyExpansion(TestKeyExpansion):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1.setVar("FOO", "foo")
self.d1.setVar("BAR", "foo")
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)
class TestRemoteFlags(TestFlags):
def setUp(self):
self.d1 = bb.data.init()
self.d = bb.data.init()
self.d1.setVar("foo", "value of foo")
self.d1.setVarFlag("foo", "flag1", "value of flag1")
self.d1.setVarFlag("foo", "flag2", "value of flag2")
connector = TestConnector(self.d1)
self.d.setVar('_remote_data', connector)

View File

@@ -1,986 +0,0 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for the Event implementation (event.py)
#
# Copyright (C) 2017 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
import unittest
import bb
import logging
import bb.compat
import bb.event
import importlib
import threading
import time
import pickle
from unittest.mock import Mock
from unittest.mock import call
from bb.msg import BBLogFormatter
class EventQueueStubBase(object):
""" Base class for EventQueueStub classes """
def __init__(self):
self.event_calls = []
return
def _store_event_data_string(self, event):
if isinstance(event, logging.LogRecord):
formatter = BBLogFormatter("%(levelname)s: %(message)s")
self.event_calls.append(formatter.format(event))
else:
self.event_calls.append(bb.event.getName(event))
return
class EventQueueStub(EventQueueStubBase):
""" Class used as specification for UI event handler queue stub objects """
def __init__(self):
super(EventQueueStub, self).__init__()
def send(self, event):
super(EventQueueStub, self)._store_event_data_string(event)
class PickleEventQueueStub(EventQueueStubBase):
""" Class used as specification for UI event handler queue stub objects
with sendpickle method """
def __init__(self):
super(PickleEventQueueStub, self).__init__()
def sendpickle(self, pickled_event):
event = pickle.loads(pickled_event)
super(PickleEventQueueStub, self)._store_event_data_string(event)
class UIClientStub(object):
""" Class used as specification for UI event handler stub objects """
def __init__(self):
self.event = None
class EventHandlingTest(unittest.TestCase):
""" Event handling test class """
def setUp(self):
self._test_process = Mock()
ui_client1 = UIClientStub()
ui_client2 = UIClientStub()
self._test_ui1 = Mock(wraps=ui_client1)
self._test_ui2 = Mock(wraps=ui_client2)
importlib.reload(bb.event)
def _create_test_handlers(self):
""" Method used to create a test handler ordered dictionary """
test_handlers = bb.compat.OrderedDict()
test_handlers["handler1"] = self._test_process.handler1
test_handlers["handler2"] = self._test_process.handler2
return test_handlers
def test_class_handlers(self):
""" Test set_class_handlers and get_class_handlers methods """
test_handlers = self._create_test_handlers()
bb.event.set_class_handlers(test_handlers)
self.assertEqual(test_handlers,
bb.event.get_class_handlers())
def test_handlers(self):
""" Test set_handlers and get_handlers """
test_handlers = self._create_test_handlers()
bb.event.set_handlers(test_handlers)
self.assertEqual(test_handlers,
bb.event.get_handlers())
def test_clean_class_handlers(self):
""" Test clean_class_handlers method """
cleanDict = bb.compat.OrderedDict()
self.assertEqual(cleanDict,
bb.event.clean_class_handlers())
def test_register(self):
""" Test register method for class handlers """
result = bb.event.register("handler", self._test_process.handler)
self.assertEqual(result, bb.event.Registered)
handlers_dict = bb.event.get_class_handlers()
self.assertIn("handler", handlers_dict)
def test_already_registered(self):
""" Test detection of an already registed class handler """
bb.event.register("handler", self._test_process.handler)
handlers_dict = bb.event.get_class_handlers()
self.assertIn("handler", handlers_dict)
result = bb.event.register("handler", self._test_process.handler)
self.assertEqual(result, bb.event.AlreadyRegistered)
def test_register_from_string(self):
""" Test register method receiving code in string """
result = bb.event.register("string_handler", " return True")
self.assertEqual(result, bb.event.Registered)
handlers_dict = bb.event.get_class_handlers()
self.assertIn("string_handler", handlers_dict)
def test_register_with_mask(self):
""" Test register method with event masking """
mask = ["bb.event.OperationStarted",
"bb.event.OperationCompleted"]
result = bb.event.register("event_handler",
self._test_process.event_handler,
mask)
self.assertEqual(result, bb.event.Registered)
handlers_dict = bb.event.get_class_handlers()
self.assertIn("event_handler", handlers_dict)
def test_remove(self):
""" Test remove method for class handlers """
test_handlers = self._create_test_handlers()
bb.event.set_class_handlers(test_handlers)
count = len(test_handlers)
bb.event.remove("handler1", None)
test_handlers = bb.event.get_class_handlers()
self.assertEqual(len(test_handlers), count - 1)
with self.assertRaises(KeyError):
bb.event.remove("handler1", None)
def test_execute_handler(self):
""" Test execute_handler method for class handlers """
mask = ["bb.event.OperationProgress"]
result = bb.event.register("event_handler",
self._test_process.event_handler,
mask)
self.assertEqual(result, bb.event.Registered)
event = bb.event.OperationProgress(current=10, total=100)
bb.event.execute_handler("event_handler",
self._test_process.event_handler,
event,
None)
self._test_process.event_handler.assert_called_once_with(event)
def test_fire_class_handlers(self):
""" Test fire_class_handlers method """
mask = ["bb.event.OperationStarted"]
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
mask)
self.assertEqual(result, bb.event.Registered)
result = bb.event.register("event_handler2",
self._test_process.event_handler2,
"*")
self.assertEqual(result, bb.event.Registered)
event1 = bb.event.OperationStarted()
event2 = bb.event.OperationCompleted(total=123)
bb.event.fire_class_handlers(event1, None)
bb.event.fire_class_handlers(event2, None)
bb.event.fire_class_handlers(event2, None)
expected_event_handler1 = [call(event1)]
expected_event_handler2 = [call(event1),
call(event2),
call(event2)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected_event_handler1)
self.assertEqual(self._test_process.event_handler2.call_args_list,
expected_event_handler2)
def test_class_handler_filters(self):
""" Test filters for class handlers """
mask = ["bb.event.OperationStarted"]
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
mask)
self.assertEqual(result, bb.event.Registered)
result = bb.event.register("event_handler2",
self._test_process.event_handler2,
"*")
self.assertEqual(result, bb.event.Registered)
bb.event.set_eventfilter(
lambda name, handler, event, d :
name == 'event_handler2' and
bb.event.getName(event) == "OperationStarted")
event1 = bb.event.OperationStarted()
event2 = bb.event.OperationCompleted(total=123)
bb.event.fire_class_handlers(event1, None)
bb.event.fire_class_handlers(event2, None)
bb.event.fire_class_handlers(event2, None)
expected_event_handler1 = []
expected_event_handler2 = [call(event1)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected_event_handler1)
self.assertEqual(self._test_process.event_handler2.call_args_list,
expected_event_handler2)
def test_change_handler_event_mapping(self):
""" Test changing the event mapping for class handlers """
event1 = bb.event.OperationStarted()
event2 = bb.event.OperationCompleted(total=123)
# register handler for all events
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
"*")
self.assertEqual(result, bb.event.Registered)
bb.event.fire_class_handlers(event1, None)
bb.event.fire_class_handlers(event2, None)
expected = [call(event1), call(event2)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected)
# unregister handler and register it only for OperationStarted
bb.event.remove("event_handler1",
self._test_process.event_handler1)
mask = ["bb.event.OperationStarted"]
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
mask)
self.assertEqual(result, bb.event.Registered)
bb.event.fire_class_handlers(event1, None)
bb.event.fire_class_handlers(event2, None)
expected = [call(event1), call(event2), call(event1)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected)
# unregister handler and register it only for OperationCompleted
bb.event.remove("event_handler1",
self._test_process.event_handler1)
mask = ["bb.event.OperationCompleted"]
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
mask)
self.assertEqual(result, bb.event.Registered)
bb.event.fire_class_handlers(event1, None)
bb.event.fire_class_handlers(event2, None)
expected = [call(event1), call(event2), call(event1), call(event2)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected)
def test_register_UIHhandler(self):
""" Test register_UIHhandler method """
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
def test_UIHhandler_already_registered(self):
""" Test registering an UIHhandler already existing """
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 2)
def test_unregister_UIHhandler(self):
""" Test unregister_UIHhandler method """
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
result = bb.event.unregister_UIHhandler(1)
self.assertIs(result, None)
def test_fire_ui_handlers(self):
""" Test fire_ui_handlers method """
self._test_ui1.event = Mock(spec_set=EventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
self._test_ui2.event = Mock(spec_set=PickleEventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
self.assertEqual(result, 2)
event1 = bb.event.OperationStarted()
bb.event.fire_ui_handlers(event1, None)
expected = [call(event1)]
self.assertEqual(self._test_ui1.event.send.call_args_list,
expected)
expected = [call(pickle.dumps(event1))]
self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
expected)
def test_ui_handler_mask_filter(self):
""" Test filters for UI handlers """
mask = ["bb.event.OperationStarted"]
debug_domains = {}
self._test_ui1.event = Mock(spec_set=EventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
self._test_ui2.event = Mock(spec_set=PickleEventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
event1 = bb.event.OperationStarted()
event2 = bb.event.OperationCompleted(total=1)
bb.event.fire_ui_handlers(event1, None)
bb.event.fire_ui_handlers(event2, None)
expected = [call(event1)]
self.assertEqual(self._test_ui1.event.send.call_args_list,
expected)
expected = [call(pickle.dumps(event1))]
self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
expected)
def test_ui_handler_log_filter(self):
""" Test log filters for UI handlers """
mask = ["*"]
debug_domains = {'BitBake.Foo': logging.WARNING}
self._test_ui1.event = EventQueueStub()
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
self._test_ui2.event = PickleEventQueueStub()
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
event1 = bb.event.OperationStarted()
bb.event.fire_ui_handlers(event1, None) # All events match
event_log_handler = bb.event.LogHandler()
logger = logging.getLogger("BitBake")
logger.addHandler(event_log_handler)
logger1 = logging.getLogger("BitBake.Foo")
logger1.warning("Test warning LogRecord1") # Matches debug_domains level
logger1.info("Test info LogRecord") # Filtered out
logger2 = logging.getLogger("BitBake.Bar")
logger2.error("Test error LogRecord") # Matches filter base level
logger2.warning("Test warning LogRecord2") # Filtered out
logger.removeHandler(event_log_handler)
expected = ['OperationStarted',
'WARNING: Test warning LogRecord1',
'ERROR: Test error LogRecord']
self.assertEqual(self._test_ui1.event.event_calls, expected)
self.assertEqual(self._test_ui2.event.event_calls, expected)
def test_fire(self):
""" Test fire method used to trigger class and ui event handlers """
mask = ["bb.event.ConfigParsed"]
result = bb.event.register("event_handler1",
self._test_process.event_handler1,
mask)
self._test_ui1.event = Mock(spec_set=EventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
event1 = bb.event.ConfigParsed()
bb.event.fire(event1, None)
expected = [call(event1)]
self.assertEqual(self._test_process.event_handler1.call_args_list,
expected)
self.assertEqual(self._test_ui1.event.send.call_args_list,
expected)
def test_fire_from_worker(self):
""" Test fire_from_worker method """
self._test_ui1.event = Mock(spec_set=EventQueueStub)
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
event1 = bb.event.ConfigParsed()
bb.event.fire_from_worker(event1, None)
expected = [call(event1)]
self.assertEqual(self._test_ui1.event.send.call_args_list,
expected)
def test_worker_fire(self):
""" Test the triggering of bb.event.worker_fire callback """
bb.event.worker_fire = Mock()
event = bb.event.Event()
bb.event.fire(event, None)
expected = [call(event, None)]
self.assertEqual(bb.event.worker_fire.call_args_list, expected)
def test_print_ui_queue(self):
""" Test print_ui_queue method """
event1 = bb.event.OperationStarted()
event2 = bb.event.OperationCompleted(total=123)
bb.event.fire(event1, None)
bb.event.fire(event2, None)
event_log_handler = bb.event.LogHandler()
logger = logging.getLogger("BitBake")
logger.addHandler(event_log_handler)
logger.info("Test info LogRecord")
logger.warning("Test warning LogRecord")
with self.assertLogs("BitBake", level="INFO") as cm:
bb.event.print_ui_queue()
logger.removeHandler(event_log_handler)
self.assertEqual(cm.output,
["INFO:BitBake:Test info LogRecord",
"WARNING:BitBake:Test warning LogRecord"])
def _set_threadlock_test_mockups(self):
""" Create UI event handler mockups used in enable and disable
threadlock tests """
def ui1_event_send(event):
if type(event) is bb.event.ConfigParsed:
self._threadlock_test_calls.append("w1_ui1")
if type(event) is bb.event.OperationStarted:
self._threadlock_test_calls.append("w2_ui1")
time.sleep(2)
def ui2_event_send(event):
if type(event) is bb.event.ConfigParsed:
self._threadlock_test_calls.append("w1_ui2")
if type(event) is bb.event.OperationStarted:
self._threadlock_test_calls.append("w2_ui2")
time.sleep(2)
self._threadlock_test_calls = []
self._test_ui1.event = EventQueueStub()
self._test_ui1.event.send = ui1_event_send
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
self.assertEqual(result, 1)
self._test_ui2.event = EventQueueStub()
self._test_ui2.event.send = ui2_event_send
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
self.assertEqual(result, 2)
def _set_and_run_threadlock_test_workers(self):
""" Create and run the workers used to trigger events in enable and
disable threadlock tests """
worker1 = threading.Thread(target=self._thread_lock_test_worker1)
worker2 = threading.Thread(target=self._thread_lock_test_worker2)
worker1.start()
time.sleep(1)
worker2.start()
worker1.join()
worker2.join()
def _thread_lock_test_worker1(self):
""" First worker used to fire the ConfigParsed event for enable and
disable threadlocks tests """
bb.event.fire(bb.event.ConfigParsed(), None)
def _thread_lock_test_worker2(self):
""" Second worker used to fire the OperationStarted event for enable
and disable threadlocks tests """
bb.event.fire(bb.event.OperationStarted(), None)
def test_enable_threadlock(self):
""" Test enable_threadlock method """
self._set_threadlock_test_mockups()
bb.event.enable_threadlock()
self._set_and_run_threadlock_test_workers()
# Calls to UI handlers should be in order as all the registered
# handlers for the event coming from the first worker should be
# called before processing the event from the second worker.
self.assertEqual(self._threadlock_test_calls,
["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"])
def test_disable_threadlock(self):
""" Test disable_threadlock method """
self._set_threadlock_test_mockups()
bb.event.disable_threadlock()
self._set_and_run_threadlock_test_workers()
# Calls to UI handlers should be intertwined together. Thanks to the
# delay in the registered handlers for the event coming from the first
# worker, the event coming from the second worker starts being
# processed before finishing handling the first worker event.
self.assertEqual(self._threadlock_test_calls,
["w1_ui1", "w2_ui1", "w1_ui2", "w2_ui2"])
class EventClassesTest(unittest.TestCase):
""" Event classes test class """
_worker_pid = 54321
def setUp(self):
bb.event.worker_pid = EventClassesTest._worker_pid
def test_Event(self):
""" Test the Event base class """
event = bb.event.Event()
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_HeartbeatEvent(self):
""" Test the HeartbeatEvent class """
time = 10
event = bb.event.HeartbeatEvent(time)
self.assertEqual(event.time, time)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_OperationStarted(self):
""" Test OperationStarted event class """
msg = "Foo Bar"
event = bb.event.OperationStarted(msg)
self.assertEqual(event.msg, msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_OperationCompleted(self):
""" Test OperationCompleted event class """
msg = "Foo Bar"
total = 123
event = bb.event.OperationCompleted(total, msg)
self.assertEqual(event.msg, msg)
self.assertEqual(event.total, total)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_OperationProgress(self):
""" Test OperationProgress event class """
msg = "Foo Bar"
total = 123
current = 111
event = bb.event.OperationProgress(current, total, msg)
self.assertEqual(event.msg, msg + ": %s/%s" % (current, total))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ConfigParsed(self):
""" Test the ConfigParsed class """
event = bb.event.ConfigParsed()
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_MultiConfigParsed(self):
""" Test MultiConfigParsed event class """
mcdata = {"foobar": "Foo Bar"}
event = bb.event.MultiConfigParsed(mcdata)
self.assertEqual(event.mcdata, mcdata)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_RecipeEvent(self):
""" Test RecipeEvent event base class """
callback = lambda a: 2 * a
event = bb.event.RecipeEvent(callback)
self.assertEqual(event.fn(1), callback(1))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_RecipePreFinalise(self):
""" Test RecipePreFinalise event class """
callback = lambda a: 2 * a
event = bb.event.RecipePreFinalise(callback)
self.assertEqual(event.fn(1), callback(1))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_RecipeTaskPreProcess(self):
""" Test RecipeTaskPreProcess event class """
callback = lambda a: 2 * a
tasklist = [("foobar", callback)]
event = bb.event.RecipeTaskPreProcess(callback, tasklist)
self.assertEqual(event.fn(1), callback(1))
self.assertEqual(event.tasklist, tasklist)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_RecipeParsed(self):
""" Test RecipeParsed event base class """
callback = lambda a: 2 * a
event = bb.event.RecipeParsed(callback)
self.assertEqual(event.fn(1), callback(1))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_StampUpdate(self):
targets = ["foo", "bar"]
stampfns = [lambda:"foobar"]
event = bb.event.StampUpdate(targets, stampfns)
self.assertEqual(event.targets, targets)
self.assertEqual(event.stampPrefix, stampfns)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_BuildBase(self):
""" Test base class for bitbake build events """
name = "foo"
pkgs = ["bar"]
failures = 123
event = bb.event.BuildBase(name, pkgs, failures)
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), failures)
name = event.name = "bar"
pkgs = event.pkgs = ["foo"]
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), failures)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_BuildInit(self):
""" Test class for bitbake build invocation events """
event = bb.event.BuildInit()
self.assertEqual(event.name, None)
self.assertEqual(event.pkgs, [])
self.assertEqual(event.getFailures(), 0)
name = event.name = "bar"
pkgs = event.pkgs = ["foo"]
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), 0)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_BuildStarted(self):
""" Test class for build started events """
name = "foo"
pkgs = ["bar"]
failures = 123
event = bb.event.BuildStarted(name, pkgs, failures)
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), failures)
self.assertEqual(event.msg, "Building Started")
name = event.name = "bar"
pkgs = event.pkgs = ["foo"]
msg = event.msg = "foobar"
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), failures)
self.assertEqual(event.msg, msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_BuildCompleted(self):
""" Test class for build completed events """
total = 1000
name = "foo"
pkgs = ["bar"]
failures = 123
interrupted = 1
event = bb.event.BuildCompleted(total, name, pkgs, failures,
interrupted)
self.assertEqual(event.name, name)
self.assertEqual(event.pkgs, pkgs)
self.assertEqual(event.getFailures(), failures)
self.assertEqual(event.msg, "Building Failed")
event2 = bb.event.BuildCompleted(total, name, pkgs)
self.assertEqual(event2.name, name)
self.assertEqual(event2.pkgs, pkgs)
self.assertEqual(event2.getFailures(), 0)
self.assertEqual(event2.msg, "Building Succeeded")
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
def test_DiskFull(self):
""" Test DiskFull event class """
dev = "/dev/foo"
type = "ext4"
freespace = "104M"
mountpoint = "/"
event = bb.event.DiskFull(dev, type, freespace, mountpoint)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_MonitorDiskEvent(self):
""" Test MonitorDiskEvent class """
available_bytes = 10000000
free_bytes = 90000000
total_bytes = 1000000000
du = bb.event.DiskUsageSample(available_bytes, free_bytes,
total_bytes)
event = bb.event.MonitorDiskEvent(du)
self.assertEqual(event.disk_usage.available_bytes, available_bytes)
self.assertEqual(event.disk_usage.free_bytes, free_bytes)
self.assertEqual(event.disk_usage.total_bytes, total_bytes)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_NoProvider(self):
""" Test NoProvider event class """
item = "foobar"
event1 = bb.event.NoProvider(item)
self.assertEqual(event1.getItem(), item)
self.assertEqual(event1.isRuntime(), False)
self.assertEqual(str(event1), "Nothing PROVIDES 'foobar'")
runtime = True
dependees = ["foo", "bar"]
reasons = None
close_matches = ["foibar", "footbar"]
event2 = bb.event.NoProvider(item, runtime, dependees, reasons,
close_matches)
self.assertEqual(event2.isRuntime(), True)
expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
" on or otherwise requires it). Close matches:\n"
" foibar\n"
" footbar")
self.assertEqual(str(event2), expected)
reasons = ["Item does not exist on database"]
close_matches = ["foibar", "footbar"]
event3 = bb.event.NoProvider(item, runtime, dependees, reasons,
close_matches)
expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
" on or otherwise requires it)\n"
"Item does not exist on database")
self.assertEqual(str(event3), expected)
self.assertEqual(event3.pid, EventClassesTest._worker_pid)
def test_MultipleProviders(self):
""" Test MultipleProviders event class """
item = "foobar"
candidates = ["foobarv1", "foobars"]
event1 = bb.event.MultipleProviders(item, candidates)
self.assertEqual(event1.isRuntime(), False)
self.assertEqual(event1.getItem(), item)
self.assertEqual(event1.getCandidates(), candidates)
expected = ("Multiple providers are available for foobar (foobarv1,"
" foobars)\n"
"Consider defining a PREFERRED_PROVIDER entry to match "
"foobar")
self.assertEqual(str(event1), expected)
runtime = True
event2 = bb.event.MultipleProviders(item, candidates, runtime)
self.assertEqual(event2.isRuntime(), runtime)
expected = ("Multiple providers are available for runtime foobar "
"(foobarv1, foobars)\n"
"Consider defining a PREFERRED_RPROVIDER entry to match "
"foobar")
self.assertEqual(str(event2), expected)
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
def test_ParseStarted(self):
""" Test ParseStarted event class """
total = 123
event = bb.event.ParseStarted(total)
self.assertEqual(event.msg, "Recipe parsing Started")
self.assertEqual(event.total, total)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ParseCompleted(self):
""" Test ParseCompleted event class """
cached = 10
parsed = 13
skipped = 7
virtuals = 2
masked = 1
errors = 0
total = 23
event = bb.event.ParseCompleted(cached, parsed, skipped, masked,
virtuals, errors, total)
self.assertEqual(event.msg, "Recipe parsing Completed")
expected = [cached, parsed, skipped, virtuals, masked, errors,
cached + parsed, total]
actual = [event.cached, event.parsed, event.skipped, event.virtuals,
event.masked, event.errors, event.sofar, event.total]
self.assertEqual(str(actual), str(expected))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ParseProgress(self):
""" Test ParseProgress event class """
current = 10
total = 100
event = bb.event.ParseProgress(current, total)
self.assertEqual(event.msg,
"Recipe parsing" + ": %s/%s" % (current, total))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_CacheLoadStarted(self):
""" Test CacheLoadStarted event class """
total = 123
event = bb.event.CacheLoadStarted(total)
self.assertEqual(event.msg, "Loading cache Started")
self.assertEqual(event.total, total)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_CacheLoadProgress(self):
""" Test CacheLoadProgress event class """
current = 10
total = 100
event = bb.event.CacheLoadProgress(current, total)
self.assertEqual(event.msg,
"Loading cache" + ": %s/%s" % (current, total))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_CacheLoadCompleted(self):
""" Test CacheLoadCompleted event class """
total = 23
num_entries = 12
event = bb.event.CacheLoadCompleted(total, num_entries)
self.assertEqual(event.msg, "Loading cache Completed")
expected = [total, num_entries]
actual = [event.total, event.num_entries]
self.assertEqual(str(actual), str(expected))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_TreeDataPreparationStarted(self):
""" Test TreeDataPreparationStarted event class """
event = bb.event.TreeDataPreparationStarted()
self.assertEqual(event.msg, "Preparing tree data Started")
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_TreeDataPreparationProgress(self):
""" Test TreeDataPreparationProgress event class """
current = 10
total = 100
event = bb.event.TreeDataPreparationProgress(current, total)
self.assertEqual(event.msg,
"Preparing tree data" + ": %s/%s" % (current, total))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_TreeDataPreparationCompleted(self):
""" Test TreeDataPreparationCompleted event class """
total = 23
event = bb.event.TreeDataPreparationCompleted(total)
self.assertEqual(event.msg, "Preparing tree data Completed")
self.assertEqual(event.total, total)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_DepTreeGenerated(self):
""" Test DepTreeGenerated event class """
depgraph = Mock()
event = bb.event.DepTreeGenerated(depgraph)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_TargetsTreeGenerated(self):
""" Test TargetsTreeGenerated event class """
model = Mock()
event = bb.event.TargetsTreeGenerated(model)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ReachableStamps(self):
""" Test ReachableStamps event class """
stamps = [Mock(), Mock()]
event = bb.event.ReachableStamps(stamps)
self.assertEqual(event.stamps, stamps)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_FilesMatchingFound(self):
""" Test FilesMatchingFound event class """
pattern = "foo.*bar"
matches = ["foobar"]
event = bb.event.FilesMatchingFound(pattern, matches)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ConfigFilesFound(self):
""" Test ConfigFilesFound event class """
variable = "FOO_BAR"
values = ["foo", "bar"]
event = bb.event.ConfigFilesFound(variable, values)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ConfigFilePathFound(self):
""" Test ConfigFilePathFound event class """
path = "/foo/bar"
event = bb.event.ConfigFilePathFound(path)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_message_classes(self):
""" Test message event classes """
msg = "foobar foo bar"
event = bb.event.MsgBase(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgDebug(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgNote(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgWarn(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgError(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgFatal(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
event = bb.event.MsgPlain(msg)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_LogExecTTY(self):
""" Test LogExecTTY event class """
msg = "foo bar"
prog = "foo.sh"
sleep_delay = 10
retries = 3
event = bb.event.LogExecTTY(msg, prog, sleep_delay, retries)
self.assertEqual(event.msg, msg)
self.assertEqual(event.prog, prog)
self.assertEqual(event.sleep_delay, sleep_delay)
self.assertEqual(event.retries, retries)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def _throw_zero_division_exception(self):
a = 1 / 0
return
def _worker_handler(self, event, d):
self._returned_event = event
return
def test_LogHandler(self):
""" Test LogHandler class """
logger = logging.getLogger("TestEventClasses")
logger.propagate = False
handler = bb.event.LogHandler(logging.INFO)
logger.addHandler(handler)
bb.event.worker_fire = self._worker_handler
try:
self._throw_zero_division_exception()
except ZeroDivisionError as ex:
logger.exception(ex)
event = self._returned_event
try:
pe = pickle.dumps(event)
newevent = pickle.loads(pe)
except:
self.fail('Logged event is not serializable')
self.assertEqual(event.taskpid, EventClassesTest._worker_pid)
def test_MetadataEvent(self):
""" Test MetadataEvent class """
eventtype = "footype"
eventdata = {"foo": "bar"}
event = bb.event.MetadataEvent(eventtype, eventdata)
self.assertEqual(event.type, eventtype)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ProcessStarted(self):
""" Test ProcessStarted class """
processname = "foo"
total = 9783128974
event = bb.event.ProcessStarted(processname, total)
self.assertEqual(event.processname, processname)
self.assertEqual(event.total, total)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ProcessProgress(self):
""" Test ProcessProgress class """
processname = "foo"
progress = 243224
event = bb.event.ProcessProgress(processname, progress)
self.assertEqual(event.processname, processname)
self.assertEqual(event.progress, progress)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_ProcessFinished(self):
""" Test ProcessFinished class """
processname = "foo"
total = 1242342344
event = bb.event.ProcessFinished(processname)
self.assertEqual(event.processname, processname)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_SanityCheck(self):
""" Test SanityCheck class """
event1 = bb.event.SanityCheck()
self.assertEqual(event1.generateevents, True)
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
generateevents = False
event2 = bb.event.SanityCheck(generateevents)
self.assertEqual(event2.generateevents, generateevents)
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
def test_SanityCheckPassed(self):
""" Test SanityCheckPassed class """
event = bb.event.SanityCheckPassed()
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_SanityCheckFailed(self):
""" Test SanityCheckFailed class """
msg = "The sanity test failed."
event1 = bb.event.SanityCheckFailed(msg)
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
network_error = True
event2 = bb.event.SanityCheckFailed(msg, network_error)
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
def test_network_event_classes(self):
""" Test network event classes """
event1 = bb.event.NetworkTest()
generateevents = False
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
event2 = bb.event.NetworkTest(generateevents)
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
event3 = bb.event.NetworkTestPassed()
self.assertEqual(event3.pid, EventClassesTest._worker_pid)
event4 = bb.event.NetworkTestFailed()
self.assertEqual(event4.pid, EventClassesTest._worker_pid)
def test_FindSigInfoResult(self):
""" Test FindSigInfoResult event class """
result = [Mock()]
event = bb.event.FindSigInfoResult(result)
self.assertEqual(event.result, result)
self.assertEqual(event.pid, EventClassesTest._worker_pid)

File diff suppressed because it is too large Load Diff

View File

@@ -1,185 +0,0 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Test for lib/bb/parse/
#
# Copyright (C) 2015 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
import unittest
import tempfile
import logging
import bb
import os
logger = logging.getLogger('BitBake.TestParse')
import bb.parse
import bb.data
import bb.siggen
class ParseTest(unittest.TestCase):
testfile = """
A = "1"
B = "2"
do_install() {
echo "hello"
}
C = "3"
"""
def setUp(self):
self.d = bb.data.init()
bb.parse.siggen = bb.siggen.init(self.d)
def parsehelper(self, content, suffix = ".bb"):
f = tempfile.NamedTemporaryFile(suffix = suffix)
f.write(bytes(content, "utf-8"))
f.flush()
os.chdir(os.path.dirname(f.name))
return f
def test_parse_simple(self):
f = self.parsehelper(self.testfile)
d = bb.parse.handle(f.name, self.d)['']
self.assertEqual(d.getVar("A"), "1")
self.assertEqual(d.getVar("B"), "2")
self.assertEqual(d.getVar("C"), "3")
def test_parse_incomplete_function(self):
testfileB = self.testfile.replace("}", "")
f = self.parsehelper(testfileB)
with self.assertRaises(bb.parse.ParseError):
d = bb.parse.handle(f.name, self.d)['']
unsettest = """
A = "1"
B = "2"
B[flag] = "3"
unset A
unset B[flag]
"""
def test_parse_unset(self):
f = self.parsehelper(self.unsettest)
d = bb.parse.handle(f.name, self.d)['']
self.assertEqual(d.getVar("A"), None)
self.assertEqual(d.getVarFlag("A","flag"), None)
self.assertEqual(d.getVar("B"), "2")
exporttest = """
A = "a"
export B = "b"
export C
exportD = "d"
"""
def test_parse_exports(self):
f = self.parsehelper(self.exporttest)
d = bb.parse.handle(f.name, self.d)['']
self.assertEqual(d.getVar("A"), "a")
self.assertIsNone(d.getVarFlag("A", "export"))
self.assertEqual(d.getVar("B"), "b")
self.assertEqual(d.getVarFlag("B", "export"), 1)
self.assertIsNone(d.getVar("C"))
self.assertEqual(d.getVarFlag("C", "export"), 1)
self.assertIsNone(d.getVar("D"))
self.assertIsNone(d.getVarFlag("D", "export"))
self.assertEqual(d.getVar("exportD"), "d")
self.assertIsNone(d.getVarFlag("exportD", "export"))
overridetest = """
RRECOMMENDS_${PN} = "a"
RRECOMMENDS_${PN}_libc = "b"
OVERRIDES = "libc:${PN}"
PN = "gtk+"
"""
def test_parse_overrides(self):
f = self.parsehelper(self.overridetest)
d = bb.parse.handle(f.name, self.d)['']
self.assertEqual(d.getVar("RRECOMMENDS"), "b")
bb.data.expandKeys(d)
self.assertEqual(d.getVar("RRECOMMENDS"), "b")
d.setVar("RRECOMMENDS_gtk+", "c")
self.assertEqual(d.getVar("RRECOMMENDS"), "c")
overridetest2 = """
EXTRA_OECONF = ""
EXTRA_OECONF_class-target = "b"
EXTRA_OECONF_append = " c"
"""
def test_parse_overrides(self):
f = self.parsehelper(self.overridetest2)
d = bb.parse.handle(f.name, self.d)['']
d.appendVar("EXTRA_OECONF", " d")
d.setVar("OVERRIDES", "class-target")
self.assertEqual(d.getVar("EXTRA_OECONF"), "b c d")
overridetest3 = """
DESCRIPTION = "A"
DESCRIPTION_${PN}-dev = "${DESCRIPTION} B"
PN = "bc"
"""
def test_parse_combinations(self):
f = self.parsehelper(self.overridetest3)
d = bb.parse.handle(f.name, self.d)['']
bb.data.expandKeys(d)
self.assertEqual(d.getVar("DESCRIPTION_bc-dev"), "A B")
d.setVar("DESCRIPTION", "E")
d.setVar("DESCRIPTION_bc-dev", "C D")
d.setVar("OVERRIDES", "bc-dev")
self.assertEqual(d.getVar("DESCRIPTION"), "C D")
classextend = """
VAR_var_override1 = "B"
EXTRA = ":override1"
OVERRIDES = "nothing${EXTRA}"
BBCLASSEXTEND = "###CLASS###"
"""
classextend_bbclass = """
EXTRA = ""
python () {
d.renameVar("VAR_var", "VAR_var2")
}
"""
#
# Test based upon a real world data corruption issue. One
# data store changing a variable poked through into a different data
# store. This test case replicates that issue where the value 'B' would
# become unset/disappear.
#
def test_parse_classextend_contamination(self):
cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
#clsname = os.path.basename(cls.name).replace(".bbclass", "")
self.classextend = self.classextend.replace("###CLASS###", cls.name)
f = self.parsehelper(self.classextend)
alldata = bb.parse.handle(f.name, self.d)
d1 = alldata['']
d2 = alldata[cls.name]
self.assertEqual(d1.getVar("VAR_var"), "B")
self.assertEqual(d2.getVar("VAR_var"), None)

View File

@@ -22,8 +22,6 @@
import unittest
import bb
import os
import tempfile
import re
class VerCmpString(unittest.TestCase):
@@ -107,497 +105,3 @@ class Path(unittest.TestCase):
for arg1, correctresult in checkitems:
result = bb.utils._check_unsafe_delete_path(arg1)
self.assertEqual(result, correctresult, '_check_unsafe_delete_path("%s") != %s' % (arg1, correctresult))
class EditMetadataFile(unittest.TestCase):
_origfile = """
# A comment
HELLO = "oldvalue"
THIS = "that"
# Another comment
NOCHANGE = "samevalue"
OTHER = 'anothervalue'
MULTILINE = "a1 \\
a2 \\
a3"
MULTILINE2 := " \\
b1 \\
b2 \\
b3 \\
"
MULTILINE3 = " \\
c1 \\
c2 \\
c3 \\
"
do_functionname() {
command1 ${VAL1} ${VAL2}
command2 ${VAL3} ${VAL4}
}
"""
def _testeditfile(self, varvalues, compareto, dummyvars=None):
if dummyvars is None:
dummyvars = []
with tempfile.NamedTemporaryFile('w', delete=False) as tf:
tf.write(self._origfile)
tf.close()
try:
varcalls = []
def handle_file(varname, origvalue, op, newlines):
self.assertIn(varname, varvalues, 'Callback called for variable %s not in the list!' % varname)
self.assertNotIn(varname, dummyvars, 'Callback called for variable %s in dummy list!' % varname)
varcalls.append(varname)
return varvalues[varname]
bb.utils.edit_metadata_file(tf.name, varvalues.keys(), handle_file)
with open(tf.name) as f:
modfile = f.readlines()
# Ensure the output matches the expected output
self.assertEqual(compareto.splitlines(True), modfile)
# Ensure the callback function was called for every variable we asked for
# (plus allow testing behaviour when a requested variable is not present)
self.assertEqual(sorted(varvalues.keys()), sorted(varcalls + dummyvars))
finally:
os.remove(tf.name)
def test_edit_metadata_file_nochange(self):
# Test file doesn't get modified with nothing to do
self._testeditfile({}, self._origfile)
# Test file doesn't get modified with only dummy variables
self._testeditfile({'DUMMY1': ('should_not_set', None, 0, True),
'DUMMY2': ('should_not_set_again', None, 0, True)}, self._origfile, dummyvars=['DUMMY1', 'DUMMY2'])
# Test file doesn't get modified with some the same values
self._testeditfile({'THIS': ('that', None, 0, True),
'OTHER': ('anothervalue', None, 0, True),
'MULTILINE3': (' c1 c2 c3 ', None, 4, False)}, self._origfile)
def test_edit_metadata_file_1(self):
newfile1 = """
# A comment
HELLO = "newvalue"
THIS = "that"
# Another comment
NOCHANGE = "samevalue"
OTHER = 'anothervalue'
MULTILINE = "a1 \\
a2 \\
a3"
MULTILINE2 := " \\
b1 \\
b2 \\
b3 \\
"
MULTILINE3 = " \\
c1 \\
c2 \\
c3 \\
"
do_functionname() {
command1 ${VAL1} ${VAL2}
command2 ${VAL3} ${VAL4}
}
"""
self._testeditfile({'HELLO': ('newvalue', None, 4, True)}, newfile1)
def test_edit_metadata_file_2(self):
newfile2 = """
# A comment
HELLO = "oldvalue"
THIS = "that"
# Another comment
NOCHANGE = "samevalue"
OTHER = 'anothervalue'
MULTILINE = " \\
d1 \\
d2 \\
d3 \\
"
MULTILINE2 := " \\
b1 \\
b2 \\
b3 \\
"
MULTILINE3 = "nowsingle"
do_functionname() {
command1 ${VAL1} ${VAL2}
command2 ${VAL3} ${VAL4}
}
"""
self._testeditfile({'MULTILINE': (['d1','d2','d3'], None, 4, False),
'MULTILINE3': ('nowsingle', None, 4, True),
'NOTPRESENT': (['a', 'b'], None, 4, False)}, newfile2, dummyvars=['NOTPRESENT'])
def test_edit_metadata_file_3(self):
newfile3 = """
# A comment
HELLO = "oldvalue"
# Another comment
NOCHANGE = "samevalue"
OTHER = "yetanothervalue"
MULTILINE = "e1 \\
e2 \\
e3 \\
"
MULTILINE2 := "f1 \\
\tf2 \\
\t"
MULTILINE3 = " \\
c1 \\
c2 \\
c3 \\
"
do_functionname() {
othercommand_one a b c
othercommand_two d e f
}
"""
self._testeditfile({'do_functionname()': (['othercommand_one a b c', 'othercommand_two d e f'], None, 4, False),
'MULTILINE2': (['f1', 'f2'], None, '\t', True),
'MULTILINE': (['e1', 'e2', 'e3'], None, -1, True),
'THIS': (None, None, 0, False),
'OTHER': ('yetanothervalue', None, 0, True)}, newfile3)
def test_edit_metadata_file_4(self):
newfile4 = """
# A comment
HELLO = "oldvalue"
THIS = "that"
# Another comment
OTHER = 'anothervalue'
MULTILINE = "a1 \\
a2 \\
a3"
MULTILINE2 := " \\
b1 \\
b2 \\
b3 \\
"
"""
self._testeditfile({'NOCHANGE': (None, None, 0, False),
'MULTILINE3': (None, None, 0, False),
'THIS': ('that', None, 0, False),
'do_functionname()': (None, None, 0, False)}, newfile4)
def test_edit_metadata(self):
newfile5 = """
# A comment
HELLO = "hithere"
# A new comment
THIS += "that"
# Another comment
NOCHANGE = "samevalue"
OTHER = 'anothervalue'
MULTILINE = "a1 \\
a2 \\
a3"
MULTILINE2 := " \\
b1 \\
b2 \\
b3 \\
"
MULTILINE3 = " \\
c1 \\
c2 \\
c3 \\
"
NEWVAR = "value"
do_functionname() {
command1 ${VAL1} ${VAL2}
command2 ${VAL3} ${VAL4}
}
"""
def handle_var(varname, origvalue, op, newlines):
if varname == 'THIS':
newlines.append('# A new comment\n')
elif varname == 'do_functionname()':
newlines.append('NEWVAR = "value"\n')
newlines.append('\n')
valueitem = varvalues.get(varname, None)
if valueitem:
return valueitem
else:
return (origvalue, op, 0, True)
varvalues = {'HELLO': ('hithere', None, 0, True), 'THIS': ('that', '+=', 0, True)}
varlist = ['HELLO', 'THIS', 'do_functionname()']
(updated, newlines) = bb.utils.edit_metadata(self._origfile.splitlines(True), varlist, handle_var)
self.assertTrue(updated, 'List should be updated but isn\'t')
self.assertEqual(newlines, newfile5.splitlines(True))
# Make sure the orig value matches what we expect it to be
def test_edit_metadata_origvalue(self):
origfile = """
MULTILINE = " stuff \\
morestuff"
"""
expected_value = "stuff morestuff"
global value_in_callback
value_in_callback = ""
def handle_var(varname, origvalue, op, newlines):
global value_in_callback
value_in_callback = origvalue
return (origvalue, op, -1, False)
bb.utils.edit_metadata(origfile.splitlines(True),
['MULTILINE'],
handle_var)
testvalue = re.sub('\s+', ' ', value_in_callback.strip())
self.assertEqual(expected_value, testvalue)
class EditBbLayersConf(unittest.TestCase):
def _test_bblayers_edit(self, before, after, add, remove, notadded, notremoved):
with tempfile.NamedTemporaryFile('w', delete=False) as tf:
tf.write(before)
tf.close()
try:
actual_notadded, actual_notremoved = bb.utils.edit_bblayers_conf(tf.name, add, remove)
with open(tf.name) as f:
actual_after = f.readlines()
self.assertEqual(after.splitlines(True), actual_after)
self.assertEqual(notadded, actual_notadded)
self.assertEqual(notremoved, actual_notremoved)
finally:
os.remove(tf.name)
def test_bblayers_remove(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/subpath/layer3 \
/home/user/path/layer4 \
"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/subpath/layer3 \
/home/user/path/layer4 \
"
"""
self._test_bblayers_edit(before, after,
None,
'/home/user/path/layer2',
[],
[])
def test_bblayers_add(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/subpath/layer3 \
/home/user/path/layer4 \
"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/subpath/layer3 \
/home/user/path/layer4 \
/other/path/to/layer5 \
"
"""
self._test_bblayers_edit(before, after,
'/other/path/to/layer5/',
None,
[],
[])
def test_bblayers_add_remove(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/subpath/layer3 \
/home/user/path/layer4 \
"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/layer4 \
/other/path/to/layer5 \
"
"""
self._test_bblayers_edit(before, after,
['/other/path/to/layer5', '/home/user/path/layer2/'], '/home/user/path/subpath/layer3/',
['/home/user/path/layer2'],
[])
def test_bblayers_add_remove_home(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
~/path/layer1 \
~/path/layer2 \
~/otherpath/layer3 \
~/path/layer4 \
"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = " \
~/path/layer2 \
~/path/layer4 \
~/path2/layer5 \
"
"""
self._test_bblayers_edit(before, after,
[os.environ['HOME'] + '/path/layer4', '~/path2/layer5'],
[os.environ['HOME'] + '/otherpath/layer3', '~/path/layer1', '~/path/notinlist'],
[os.environ['HOME'] + '/path/layer4'],
['~/path/notinlist'])
def test_bblayers_add_remove_plusequals(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS += " \
/home/user/path/layer1 \
/home/user/path/layer2 \
"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS += " \
/home/user/path/layer2 \
/home/user/path/layer3 \
"
"""
self._test_bblayers_edit(before, after,
'/home/user/path/layer3',
'/home/user/path/layer1',
[],
[])
def test_bblayers_add_remove_plusequals2(self):
before = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS += " \
/home/user/path/layer1 \
/home/user/path/layer2 \
/home/user/path/layer3 \
"
BBLAYERS += "/home/user/path/layer4"
BBLAYERS += "/home/user/path/layer5"
"""
after = r"""
# A comment
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS += " \
/home/user/path/layer2 \
/home/user/path/layer3 \
"
BBLAYERS += "/home/user/path/layer5"
BBLAYERS += "/home/user/otherpath/layer6"
"""
self._test_bblayers_edit(before, after,
['/home/user/otherpath/layer6', '/home/user/path/layer3'], ['/home/user/path/layer1', '/home/user/path/layer4', '/home/user/path/layer7'],
['/home/user/path/layer3'],
['/home/user/path/layer7'])

View File

@@ -1,8 +1,7 @@
# tinfoil: a simple wrapper around cooker for bitbake-based command-line utilities
#
# Copyright (C) 2012-2017 Intel Corporation
# Copyright (C) 2012 Intel Corporation
# Copyright (C) 2011 Mentor Graphics Corporation
# Copyright (C) 2006-2012 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -18,883 +17,88 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import logging
import warnings
import os
import sys
import atexit
import re
from collections import OrderedDict, defaultdict
import bb.cache
import bb.cooker
import bb.providers
import bb.taskdata
import bb.utils
import bb.command
import bb.remotedata
from bb.cooker import state, BBCooker, CookerFeatures
from bb.cookerdata import CookerConfiguration, ConfigParameters
from bb.main import setup_bitbake, BitBakeConfigParameters, BBMainException
import bb.fetch2
# We need this in order to shut down the connection to the bitbake server,
# otherwise the process will never properly exit
_server_connections = []
def _terminate_connections():
for connection in _server_connections:
connection.terminate()
atexit.register(_terminate_connections)
class TinfoilUIException(Exception):
"""Exception raised when the UI returns non-zero from its main function"""
def __init__(self, returncode):
self.returncode = returncode
def __repr__(self):
return 'UI module main returned %d' % self.returncode
class TinfoilCommandFailed(Exception):
"""Exception raised when run_command fails"""
class TinfoilDataStoreConnector:
"""Connector object used to enable access to datastore objects via tinfoil"""
def __init__(self, tinfoil, dsindex):
self.tinfoil = tinfoil
self.dsindex = dsindex
def getVar(self, name):
value = self.tinfoil.run_command('dataStoreConnectorFindVar', self.dsindex, name)
overrides = None
if isinstance(value, dict):
if '_connector_origtype' in value:
value['_content'] = self.tinfoil._reconvert_type(value['_content'], value['_connector_origtype'])
del value['_connector_origtype']
if '_connector_overrides' in value:
overrides = value['_connector_overrides']
del value['_connector_overrides']
return value, overrides
def getKeys(self):
return set(self.tinfoil.run_command('dataStoreConnectorGetKeys', self.dsindex))
def getVarHistory(self, name):
return self.tinfoil.run_command('dataStoreConnectorGetVarHistory', self.dsindex, name)
def expandPythonRef(self, varname, expr, d):
ds = bb.remotedata.RemoteDatastores.transmit_datastore(d)
ret = self.tinfoil.run_command('dataStoreConnectorExpandPythonRef', ds, varname, expr)
return ret
def setVar(self, varname, value):
if self.dsindex is None:
self.tinfoil.run_command('setVariable', varname, value)
else:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
def setVarFlag(self, varname, flagname, value):
if self.dsindex is None:
self.tinfoil.run_command('dataStoreConnectorSetVarFlag', self.dsindex, varname, flagname, value)
else:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
def delVar(self, varname):
if self.dsindex is None:
self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname)
else:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
def delVarFlag(self, varname, flagname):
if self.dsindex is None:
self.tinfoil.run_command('dataStoreConnectorDelVar', self.dsindex, varname, flagname)
else:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
def renameVar(self, name, newname):
if self.dsindex is None:
self.tinfoil.run_command('dataStoreConnectorRenameVar', self.dsindex, name, newname)
else:
# Not currently implemented - indicate that setting should
# be redirected to local side
return True
class TinfoilCookerAdapter:
"""
Provide an adapter for existing code that expects to access a cooker object via Tinfoil,
since now Tinfoil is on the client side it no longer has direct access.
"""
class TinfoilCookerCollectionAdapter:
""" cooker.collection adapter """
def __init__(self, tinfoil):
self.tinfoil = tinfoil
def get_file_appends(self, fn):
return self.tinfoil.get_file_appends(fn)
def __getattr__(self, name):
if name == 'overlayed':
return self.tinfoil.get_overlayed_recipes()
elif name == 'bbappends':
return self.tinfoil.run_command('getAllAppends')
else:
raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, name))
class TinfoilRecipeCacheAdapter:
""" cooker.recipecache adapter """
def __init__(self, tinfoil):
self.tinfoil = tinfoil
self._cache = {}
def get_pkg_pn_fn(self):
pkg_pn = defaultdict(list, self.tinfoil.run_command('getRecipes') or [])
pkg_fn = {}
for pn, fnlist in pkg_pn.items():
for fn in fnlist:
pkg_fn[fn] = pn
self._cache['pkg_pn'] = pkg_pn
self._cache['pkg_fn'] = pkg_fn
def __getattr__(self, name):
# Grab these only when they are requested since they aren't always used
if name in self._cache:
return self._cache[name]
elif name == 'pkg_pn':
self.get_pkg_pn_fn()
return self._cache[name]
elif name == 'pkg_fn':
self.get_pkg_pn_fn()
return self._cache[name]
elif name == 'deps':
attrvalue = defaultdict(list, self.tinfoil.run_command('getRecipeDepends') or [])
elif name == 'rundeps':
attrvalue = defaultdict(lambda: defaultdict(list), self.tinfoil.run_command('getRuntimeDepends') or [])
elif name == 'runrecs':
attrvalue = defaultdict(lambda: defaultdict(list), self.tinfoil.run_command('getRuntimeRecommends') or [])
elif name == 'pkg_pepvpr':
attrvalue = self.tinfoil.run_command('getRecipeVersions') or {}
elif name == 'inherits':
attrvalue = self.tinfoil.run_command('getRecipeInherits') or {}
elif name == 'bbfile_priority':
attrvalue = self.tinfoil.run_command('getBbFilePriority') or {}
elif name == 'pkg_dp':
attrvalue = self.tinfoil.run_command('getDefaultPreference') or {}
elif name == 'fn_provides':
attrvalue = self.tinfoil.run_command('getRecipeProvides') or {}
elif name == 'packages':
attrvalue = self.tinfoil.run_command('getRecipePackages') or {}
elif name == 'packages_dynamic':
attrvalue = self.tinfoil.run_command('getRecipePackagesDynamic') or {}
elif name == 'rproviders':
attrvalue = self.tinfoil.run_command('getRProviders') or {}
else:
raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, name))
self._cache[name] = attrvalue
return attrvalue
def __init__(self, tinfoil):
self.tinfoil = tinfoil
self.collection = self.TinfoilCookerCollectionAdapter(tinfoil)
self.recipecaches = {}
# FIXME all machines
self.recipecaches[''] = self.TinfoilRecipeCacheAdapter(tinfoil)
self._cache = {}
def __getattr__(self, name):
# Grab these only when they are requested since they aren't always used
if name in self._cache:
return self._cache[name]
elif name == 'skiplist':
attrvalue = self.tinfoil.get_skipped_recipes()
elif name == 'bbfile_config_priorities':
ret = self.tinfoil.run_command('getLayerPriorities')
bbfile_config_priorities = []
for collection, pattern, regex, pri in ret:
bbfile_config_priorities.append((collection, pattern, re.compile(regex), pri))
attrvalue = bbfile_config_priorities
else:
raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, name))
self._cache[name] = attrvalue
return attrvalue
def findBestProvider(self, pn):
return self.tinfoil.find_best_provider(pn)
class TinfoilRecipeInfo:
"""
Provides a convenient representation of the cached information for a single recipe.
Some attributes are set on construction, others are read on-demand (which internally
may result in a remote procedure call to the bitbake server the first time).
Note that only information which is cached is available through this object - if
you need other variable values you will need to parse the recipe using
Tinfoil.parse_recipe().
"""
def __init__(self, recipecache, d, pn, fn, fns):
self._recipecache = recipecache
self._d = d
self.pn = pn
self.fn = fn
self.fns = fns
self.inherit_files = recipecache.inherits[fn]
self.depends = recipecache.deps[fn]
(self.pe, self.pv, self.pr) = recipecache.pkg_pepvpr[fn]
self._cached_packages = None
self._cached_rprovides = None
self._cached_packages_dynamic = None
def __getattr__(self, name):
if name == 'alternates':
return [x for x in self.fns if x != self.fn]
elif name == 'rdepends':
return self._recipecache.rundeps[self.fn]
elif name == 'rrecommends':
return self._recipecache.runrecs[self.fn]
elif name == 'provides':
return self._recipecache.fn_provides[self.fn]
elif name == 'packages':
if self._cached_packages is None:
self._cached_packages = []
for pkg, fns in self._recipecache.packages.items():
if self.fn in fns:
self._cached_packages.append(pkg)
return self._cached_packages
elif name == 'packages_dynamic':
if self._cached_packages_dynamic is None:
self._cached_packages_dynamic = []
for pkg, fns in self._recipecache.packages_dynamic.items():
if self.fn in fns:
self._cached_packages_dynamic.append(pkg)
return self._cached_packages_dynamic
elif name == 'rprovides':
if self._cached_rprovides is None:
self._cached_rprovides = []
for pkg, fns in self._recipecache.rproviders.items():
if self.fn in fns:
self._cached_rprovides.append(pkg)
return self._cached_rprovides
else:
raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, name))
def inherits(self, only_recipe=False):
"""
Get the inherited classes for a recipe. Returns the class names only.
Parameters:
only_recipe: True to return only the classes inherited by the recipe
itself, False to return all classes inherited within
the context for the recipe (which includes globally
inherited classes).
"""
if only_recipe:
global_inherit = [x for x in (self._d.getVar('BBINCLUDED') or '').split() if x.endswith('.bbclass')]
else:
global_inherit = []
for clsfile in self.inherit_files:
if only_recipe and clsfile in global_inherit:
continue
clsname = os.path.splitext(os.path.basename(clsfile))[0]
yield clsname
def __str__(self):
return '%s' % self.pn
class Tinfoil:
"""
Tinfoil - an API for scripts and utilities to query
BitBake internals and perform build operations.
"""
def __init__(self, output=sys.stdout, tracking=False):
# Needed to avoid deprecation warnings with python 2.6
warnings.filterwarnings("ignore", category=DeprecationWarning)
def __init__(self, output=sys.stdout, tracking=False, setup_logging=True):
"""
Create a new tinfoil object.
Parameters:
output: specifies where console output should be sent. Defaults
to sys.stdout.
tracking: True to enable variable history tracking, False to
disable it (default). Enabling this has a minor
performance impact so typically it isn't enabled
unless you need to query variable history.
setup_logging: True to setup a logger so that things like
bb.warn() will work immediately and timeout warnings
are visible; False to let BitBake do this itself.
"""
# Set up logging
self.logger = logging.getLogger('BitBake')
self.config_data = None
self.cooker = None
self.tracking = tracking
self.ui_module = None
self.server_connection = None
self.recipes_parsed = False
self.quiet = 0
self.oldhandlers = self.logger.handlers[:]
if setup_logging:
# This is the *client-side* logger, nothing to do with
# logging messages from the server
bb.msg.logger_create('BitBake', output)
self.localhandlers = []
for handler in self.logger.handlers:
if handler not in self.oldhandlers:
self.localhandlers.append(handler)
console = logging.StreamHandler(output)
bb.msg.addDefaultlogFilter(console)
format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
if output.isatty():
format.enable_color()
console.setFormatter(format)
self.logger.addHandler(console)
def __enter__(self):
return self
self.config = CookerConfiguration()
configparams = TinfoilConfigParameters(parse_only=True)
self.config.setConfigParameters(configparams)
self.config.setServerRegIdleCallback(self.register_idle_function)
features = []
if tracking:
features.append(CookerFeatures.BASEDATASTORE_TRACKING)
self.cooker = BBCooker(self.config, features)
self.config_data = self.cooker.data
bb.providers.logger.setLevel(logging.ERROR)
self.cooker_data = None
def __exit__(self, type, value, traceback):
self.shutdown()
def prepare(self, config_only=False, config_params=None, quiet=0, extra_features=None):
"""
Prepares the underlying BitBake system to be used via tinfoil.
This function must be called prior to calling any of the other
functions in the API.
NOTE: if you call prepare() you must absolutely call shutdown()
before your code terminates. You can use a "with" block to ensure
this happens e.g.
with bb.tinfoil.Tinfoil() as tinfoil:
tinfoil.prepare()
...
Parameters:
config_only: True to read only the configuration and not load
the cache / parse recipes. This is useful if you just
want to query the value of a variable at the global
level or you want to do anything else that doesn't
involve knowing anything about the recipes in the
current configuration. False loads the cache / parses
recipes.
config_params: optionally specify your own configuration
parameters. If not specified an instance of
TinfoilConfigParameters will be created internally.
quiet: quiet level controlling console output - equivalent
to bitbake's -q/--quiet option. Default of 0 gives
the same output level as normal bitbake execution.
extra_features: extra features to be added to the feature
set requested from the server. See
CookerFeatures._feature_list for possible
features.
"""
self.quiet = quiet
if self.tracking:
extrafeatures = [bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING]
else:
extrafeatures = []
if extra_features:
extrafeatures += extra_features
if not config_params:
config_params = TinfoilConfigParameters(config_only=config_only, quiet=quiet)
cookerconfig = CookerConfiguration()
cookerconfig.setConfigParameters(config_params)
if not config_only:
# Disable local loggers because the UI module is going to set up its own
for handler in self.localhandlers:
self.logger.handlers.remove(handler)
self.localhandlers = []
self.server_connection, ui_module = setup_bitbake(config_params,
cookerconfig,
extrafeatures)
self.ui_module = ui_module
# Ensure the path to bitbake's bin directory is in PATH so that things like
# bitbake-worker can be run (usually this is the case, but it doesn't have to be)
path = os.getenv('PATH').split(':')
bitbakebinpath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', 'bin'))
for entry in path:
if entry.endswith(os.sep):
entry = entry[:-1]
if os.path.abspath(entry) == bitbakebinpath:
break
else:
path.insert(0, bitbakebinpath)
os.environ['PATH'] = ':'.join(path)
if self.server_connection:
_server_connections.append(self.server_connection)
if config_only:
config_params.updateToServer(self.server_connection.connection, os.environ.copy())
self.run_command('parseConfiguration')
else:
self.run_actions(config_params)
self.recipes_parsed = True
self.config_data = bb.data.init()
connector = TinfoilDataStoreConnector(self, None)
self.config_data.setVar('_remote_data', connector)
self.cooker = TinfoilCookerAdapter(self)
self.cooker_data = self.cooker.recipecaches['']
else:
raise Exception('Failed to start bitbake server')
def run_actions(self, config_params):
"""
Run the actions specified in config_params through the UI.
"""
ret = self.ui_module.main(self.server_connection.connection, self.server_connection.events, config_params)
if ret:
raise TinfoilUIException(ret)
def register_idle_function(self, function, data):
pass
def parseRecipes(self):
"""
Legacy function - use parse_recipes() instead.
"""
self.parse_recipes()
sys.stderr.write("Parsing recipes..")
self.logger.setLevel(logging.WARNING)
def parse_recipes(self):
"""
Load information on all recipes. Normally you should specify
config_only=False when calling prepare() instead of using this
function; this function is designed for situations where you need
to initialise Tinfoil and use it with config_only=True first and
then conditionally call this function to parse recipes later.
"""
config_params = TinfoilConfigParameters(config_only=False)
self.run_actions(config_params)
self.recipes_parsed = True
def run_command(self, command, *params):
"""
Run a command on the server (as implemented in bb.command).
Note that there are two types of command - synchronous and
asynchronous; in order to receive the results of asynchronous
commands you will need to set an appropriate event mask
using set_event_mask() and listen for the result using
wait_event() - with the correct event mask you'll at least get
bb.command.CommandCompleted and possibly other events before
that depending on the command.
"""
if not self.server_connection:
raise Exception('Not connected to server (did you call .prepare()?)')
commandline = [command]
if params:
commandline.extend(params)
result = self.server_connection.connection.runCommand(commandline)
if result[1]:
raise TinfoilCommandFailed(result[1])
return result[0]
def set_event_mask(self, eventlist):
"""Set the event mask which will be applied within wait_event()"""
if not self.server_connection:
raise Exception('Not connected to server (did you call .prepare()?)')
llevel, debug_domains = bb.msg.constructLogOptions()
ret = self.run_command('setEventMask', self.server_connection.connection.getEventHandle(), llevel, debug_domains, eventlist)
if not ret:
raise Exception('setEventMask failed')
def wait_event(self, timeout=0):
"""
Wait for an event from the server for the specified time.
A timeout of 0 means don't wait if there are no events in the queue.
Returns the next event in the queue or None if the timeout was
reached. Note that in order to recieve any events you will
first need to set the internal event mask using set_event_mask()
(otherwise whatever event mask the UI set up will be in effect).
"""
if not self.server_connection:
raise Exception('Not connected to server (did you call .prepare()?)')
return self.server_connection.events.waitEvent(timeout)
def get_overlayed_recipes(self):
"""
Find recipes which are overlayed (i.e. where recipes exist in multiple layers)
"""
return defaultdict(list, self.run_command('getOverlayedRecipes'))
def get_skipped_recipes(self):
"""
Find recipes which were skipped (i.e. SkipRecipe was raised
during parsing).
"""
return OrderedDict(self.run_command('getSkippedRecipes'))
def get_all_providers(self):
return defaultdict(list, self.run_command('allProviders'))
def find_providers(self):
return self.run_command('findProviders')
def find_best_provider(self, pn):
return self.run_command('findBestProvider', pn)
def get_runtime_providers(self, rdep):
return self.run_command('getRuntimeProviders', rdep)
def get_recipe_file(self, pn):
"""
Get the file name for the specified recipe/target. Raises
bb.providers.NoProvider if there is no match or the recipe was
skipped.
"""
best = self.find_best_provider(pn)
if not best or (len(best) > 3 and not best[3]):
skiplist = self.get_skipped_recipes()
taskdata = bb.taskdata.TaskData(None, skiplist=skiplist)
skipreasons = taskdata.get_reasons(pn)
if skipreasons:
raise bb.providers.NoProvider('%s is unavailable:\n %s' % (pn, ' \n'.join(skipreasons)))
else:
raise bb.providers.NoProvider('Unable to find any recipe file matching "%s"' % pn)
return best[3]
def get_file_appends(self, fn):
"""
Find the bbappends for a recipe file
"""
return self.run_command('getFileAppends', fn)
def all_recipes(self, mc='', sort=True):
"""
Enable iterating over all recipes in the current configuration.
Returns an iterator over TinfoilRecipeInfo objects created on demand.
Parameters:
mc: The multiconfig, default of '' uses the main configuration.
sort: True to sort recipes alphabetically (default), False otherwise
"""
recipecache = self.cooker.recipecaches[mc]
if sort:
recipes = sorted(recipecache.pkg_pn.items())
else:
recipes = recipecache.pkg_pn.items()
for pn, fns in recipes:
prov = self.find_best_provider(pn)
recipe = TinfoilRecipeInfo(recipecache,
self.config_data,
pn=pn,
fn=prov[3],
fns=fns)
yield recipe
def all_recipe_files(self, mc='', variants=True, preferred_only=False):
"""
Enable iterating over all recipe files in the current configuration.
Returns an iterator over file paths.
Parameters:
mc: The multiconfig, default of '' uses the main configuration.
variants: True to include variants of recipes created through
BBCLASSEXTEND (default) or False to exclude them
preferred_only: True to include only the preferred recipe where
multiple exist providing the same PN, False to list
all recipes
"""
recipecache = self.cooker.recipecaches[mc]
if preferred_only:
files = []
for pn in recipecache.pkg_pn.keys():
prov = self.find_best_provider(pn)
files.append(prov[3])
else:
files = recipecache.pkg_fn.keys()
for fn in sorted(files):
if not variants and fn.startswith('virtual:'):
continue
yield fn
def get_recipe_info(self, pn, mc=''):
"""
Get information on a specific recipe in the current configuration by name (PN).
Returns a TinfoilRecipeInfo object created on demand.
Parameters:
mc: The multiconfig, default of '' uses the main configuration.
"""
recipecache = self.cooker.recipecaches[mc]
prov = self.find_best_provider(pn)
fn = prov[3]
if fn:
actual_pn = recipecache.pkg_fn[fn]
recipe = TinfoilRecipeInfo(recipecache,
self.config_data,
pn=actual_pn,
fn=fn,
fns=recipecache.pkg_pn[actual_pn])
return recipe
else:
return None
def parse_recipe(self, pn):
"""
Parse the specified recipe and return a datastore object
representing the environment for the recipe.
"""
fn = self.get_recipe_file(pn)
return self.parse_recipe_file(fn)
def parse_recipe_file(self, fn, appends=True, appendlist=None, config_data=None):
"""
Parse the specified recipe file (with or without bbappends)
and return a datastore object representing the environment
for the recipe.
Parameters:
fn: recipe file to parse - can be a file path or virtual
specification
appends: True to apply bbappends, False otherwise
appendlist: optional list of bbappend files to apply, if you
want to filter them
config_data: custom config datastore to use. NOTE: if you
specify config_data then you cannot use a virtual
specification for fn.
"""
if self.tracking:
# Enable history tracking just for the parse operation
self.run_command('enableDataTracking')
try:
if appends and appendlist == []:
appends = False
if config_data:
dctr = bb.remotedata.RemoteDatastores.transmit_datastore(config_data)
dscon = self.run_command('parseRecipeFile', fn, appends, appendlist, dctr)
while self.cooker.state in (state.initial, state.parsing):
self.cooker.updateCache()
except KeyboardInterrupt:
self.cooker.shutdown()
self.cooker.updateCache()
sys.exit(2)
self.logger.setLevel(logging.INFO)
sys.stderr.write("done.\n")
self.cooker_data = self.cooker.recipecache
def prepare(self, config_only = False):
if not self.cooker_data:
if config_only:
self.cooker.parseConfiguration()
self.cooker_data = self.cooker.recipecache
else:
dscon = self.run_command('parseRecipeFile', fn, appends, appendlist)
if dscon:
return self._reconvert_type(dscon, 'DataStoreConnectionHandle')
else:
return None
finally:
if self.tracking:
self.run_command('disableDataTracking')
def build_file(self, buildfile, task, internal=True):
"""
Runs the specified task for just a single recipe (i.e. no dependencies).
This is equivalent to bitbake -b, except with the default internal=True
no warning about dependencies will be produced, normal info messages
from the runqueue will be silenced and BuildInit, BuildStarted and
BuildCompleted events will not be fired.
"""
return self.run_command('buildFile', buildfile, task, internal)
def build_targets(self, targets, task=None, handle_events=True, extra_events=None, event_callback=None):
"""
Builds the specified targets. This is equivalent to a normal invocation
of bitbake. Has built-in event handling which is enabled by default and
can be extended if needed.
Parameters:
targets:
One or more targets to build. Can be a list or a
space-separated string.
task:
The task to run; if None then the value of BB_DEFAULT_TASK
will be used. Default None.
handle_events:
True to handle events in a similar way to normal bitbake
invocation with knotty; False to return immediately (on the
assumption that the caller will handle the events instead).
Default True.
extra_events:
An optional list of events to add to the event mask (if
handle_events=True). If you add events here you also need
to specify a callback function in event_callback that will
handle the additional events. Default None.
event_callback:
An optional function taking a single parameter which
will be called first upon receiving any event (if
handle_events=True) so that the caller can override or
extend the event handling. Default None.
"""
if isinstance(targets, str):
targets = targets.split()
if not task:
task = self.config_data.getVar('BB_DEFAULT_TASK')
if handle_events:
# A reasonable set of default events matching up with those we handle below
eventmask = [
'bb.event.BuildStarted',
'bb.event.BuildCompleted',
'logging.LogRecord',
'bb.event.NoProvider',
'bb.command.CommandCompleted',
'bb.command.CommandFailed',
'bb.build.TaskStarted',
'bb.build.TaskFailed',
'bb.build.TaskSucceeded',
'bb.build.TaskFailedSilent',
'bb.build.TaskProgress',
'bb.runqueue.runQueueTaskStarted',
'bb.runqueue.sceneQueueTaskStarted',
'bb.event.ProcessStarted',
'bb.event.ProcessProgress',
'bb.event.ProcessFinished',
]
if extra_events:
eventmask.extend(extra_events)
ret = self.set_event_mask(eventmask)
includelogs = self.config_data.getVar('BBINCLUDELOGS')
loglines = self.config_data.getVar('BBINCLUDELOGS_LINES')
ret = self.run_command('buildTargets', targets, task)
if handle_events:
result = False
# Borrowed from knotty, instead somewhat hackily we use the helper
# as the object to store "shutdown" on
helper = bb.ui.uihelper.BBUIHelper()
# We set up logging optionally in the constructor so now we need to
# grab the handlers to pass to TerminalFilter
console = None
errconsole = None
for handler in self.logger.handlers:
if isinstance(handler, logging.StreamHandler):
if handler.stream == sys.stdout:
console = handler
elif handler.stream == sys.stderr:
errconsole = handler
format_str = "%(levelname)s: %(message)s"
format = bb.msg.BBLogFormatter(format_str)
helper.shutdown = 0
parseprogress = None
termfilter = bb.ui.knotty.TerminalFilter(helper, helper, console, errconsole, format, quiet=self.quiet)
try:
while True:
try:
event = self.wait_event(0.25)
if event:
if event_callback and event_callback(event):
continue
if helper.eventHandler(event):
if isinstance(event, bb.build.TaskFailedSilent):
logger.warning("Logfile for failed setscene task is %s" % event.logfile)
elif isinstance(event, bb.build.TaskFailed):
bb.ui.knotty.print_event_log(event, includelogs, loglines, termfilter)
continue
if isinstance(event, bb.event.ProcessStarted):
if self.quiet > 1:
continue
parseprogress = bb.ui.knotty.new_progress(event.processname, event.total)
parseprogress.start(False)
continue
if isinstance(event, bb.event.ProcessProgress):
if self.quiet > 1:
continue
if parseprogress:
parseprogress.update(event.progress)
else:
bb.warn("Got ProcessProgress event for someting that never started?")
continue
if isinstance(event, bb.event.ProcessFinished):
if self.quiet > 1:
continue
if parseprogress:
parseprogress.finish()
parseprogress = None
continue
if isinstance(event, bb.command.CommandCompleted):
result = True
break
if isinstance(event, bb.command.CommandFailed):
self.logger.error(str(event))
result = False
break
if isinstance(event, logging.LogRecord):
if event.taskpid == 0 or event.levelno > logging.INFO:
self.logger.handle(event)
continue
if isinstance(event, bb.event.NoProvider):
self.logger.error(str(event))
result = False
break
elif helper.shutdown > 1:
break
termfilter.updateFooter()
except KeyboardInterrupt:
termfilter.clearFooter()
if helper.shutdown == 1:
print("\nSecond Keyboard Interrupt, stopping...\n")
ret = self.run_command("stateForceShutdown")
if ret and ret[2]:
self.logger.error("Unable to cleanly stop: %s" % ret[2])
elif helper.shutdown == 0:
print("\nKeyboard Interrupt, closing down...\n")
interrupted = True
ret = self.run_command("stateShutdown")
if ret and ret[2]:
self.logger.error("Unable to cleanly shutdown: %s" % ret[2])
helper.shutdown = helper.shutdown + 1
termfilter.clearFooter()
finally:
termfilter.finish()
if helper.failed_tasks:
result = False
return result
else:
return ret
self.parseRecipes()
def shutdown(self):
"""
Shut down tinfoil. Disconnects from the server and gracefully
releases any associated resources. You must call this function if
prepare() has been called, or use a with... block when you create
the tinfoil object which will ensure that it gets called.
"""
if self.server_connection:
self.run_command('clientComplete')
_server_connections.remove(self.server_connection)
bb.event.ui_queue = []
self.server_connection.terminate()
self.server_connection = None
self.cooker.shutdown(force=True)
self.cooker.post_serve()
self.cooker.unlockBitbake()
# Restore logging handlers to how it looked when we started
if self.oldhandlers:
for handler in self.logger.handlers:
if handler not in self.oldhandlers:
self.logger.handlers.remove(handler)
class TinfoilConfigParameters(ConfigParameters):
def _reconvert_type(self, obj, origtypename):
"""
Convert an object back to the right type, in the case
that marshalling has changed it (especially with xmlrpc)
"""
supported_types = {
'set': set,
'DataStoreConnectionHandle': bb.command.DataStoreConnectionHandle,
}
origtype = supported_types.get(origtypename, None)
if origtype is None:
raise Exception('Unsupported type "%s"' % origtypename)
if type(obj) == origtype:
newobj = obj
elif isinstance(obj, dict):
# New style class
newobj = origtype()
for k,v in obj.items():
setattr(newobj, k, v)
else:
# Assume we can coerce the type
newobj = origtype(obj)
if isinstance(newobj, bb.command.DataStoreConnectionHandle):
connector = TinfoilDataStoreConnector(self, newobj.dsindex)
newobj = bb.data.init()
newobj.setVar('_remote_data', connector)
return newobj
class TinfoilConfigParameters(BitBakeConfigParameters):
def __init__(self, config_only, **options):
def __init__(self, **options):
self.initial_options = options
# Apply some sane defaults
if not 'parse_only' in options:
self.initial_options['parse_only'] = not config_only
#if not 'status_only' in options:
# self.initial_options['status_only'] = config_only
if not 'ui' in options:
self.initial_options['ui'] = 'knotty'
if not 'argv' in options:
self.initial_options['argv'] = []
super(TinfoilConfigParameters, self).__init__()
def parseCommandLine(self, argv=None):
# We don't want any parameters parsed from the command line
opts = super(TinfoilConfigParameters, self).parseCommandLine([])
for key, val in self.initial_options.items():
setattr(opts[0], key, val)
return opts
def parseCommandLine(self, argv=sys.argv):
class DummyOptions:
def __init__(self, initial_options):
for key, val in initial_options.items():
setattr(self, key, val)
return DummyOptions(self.initial_options), None

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More