Openembedded Core Discussions
 help / color / mirror / Atom feed
* [PATCH 00/10] Integrate swupd software updater
@ 2016-02-24 14:52 Joshua Lock
  2016-02-24 14:52 ` [PATCH 01/10] rsync: add native variant Joshua Lock
                   ` (11 more replies)
  0 siblings, 12 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

This series provides an initial set of changes to enable integration of the
swupd (https://clearlinux.org/features/software-update) software updater into an
image.

The changes are in the relatively early stages but I am hoping to land this work
before the M3 feature freeze so that the 2.1 release provides a foundation for
experimenting with swupd.

Approach:
An image that inherits the swupd-image bbclass will automatically have bundle
'chroots' created which contain the filesystem contents of the specified
bundles, with the contents of the inheriting image forming the default os-core
bundle.

The mechanism to achieve this is that several virtual image recipes are created
using the swupdbundle class, one for each defined bundle plus a 'mega' image
recipe. The 'mega' image contains the base image plus the contents of all of the
bundles, whilst bundle images contain only the base image plus the contents of a
single bundle.

We build the mega image first, then the base image (the one which inherits this
class) and finally all of the bundle images. Each non-mega image has a manifest
generated that lists the file contents of the image.

We took the approach of building images, rather than populating the chroot-like
bundle directories with a package manager, because various layers and recipes
make changes to the rootfs contents outside of the package manager, particularly
with IMAGE_POSTPROCESS_COMMAND, etc.

Once the images and their manifests have been created each bundle image manifest
is compared to the base image manifest in order to generate a list of files in
the bundle image which don't exist in the base image.
Files in this list are then preserved in the bundle directory for processing by
swupd-server in order to generate update artefacts.

Finally the binaries from swupd-server are called on the bundle directories to
generate the artefacts for consumption by a swupd client.

How to:
* inherit the swupd-image class in your core OS image. swupd-based OS's use
  bundles, the primary one of which, os-core, is defined as the contents of this
  image.
* Assign a list of names for bundles you wish to generate to the SWUPD_BUNDLES
  variable i.e.

  SWUPD_BUNDLES = "feature_one feature_two"
* Assign a list of packages for which their content should be included in a
  bundle to a varflag of BUNDLE_CONTENTS which matches the bundle name i.e.

  BUNDLE_CONTENTS[feature_one] = "package_one package_three package_six"
* Ensure the OS_VERSION variable is assigned an integer value and increased
  before each image build which should generate swupd update artefacts. This
  variable must echo the same version number as is used to set the VERSION_ID
  field of os-release as swupd-client will use it to check for updates.
* Publish the contents of ${DEPLOY_DIR}/swupd/${MACHINE}/${IMAGE_BASENAME}/www
  on a server for consumption by swupd-client
* Use swupd client sub-commands with the -u argument pointing to the contents
  published above

Known issues:
* shared pseudo database: the bundle chroot-like directories are generated
  per-recipe and processed by a task of the inheriting recipe. In order for the
  files generated outside of the base recipe to have correct permissions when
  processed by swupd-server we need to share a pseudo database across the
  recipes.
  This database is currently never cleaned up, which is likely to cause
  headaches due to the way pseudo operates on inodes that could be reused
  outside of pseudo's influence. We have yet to determine an appropriate time to
  perform housekeeping on this database (we essentially need the database to be
  removed when DEPLOY_DIR_SWUPD is removed).
* oe-swupd-helpers: this recipe provides stub implementations only of some
  swupd-client helpers. Anyone wishing to utilise swupd in a deployed image will
  need to at least override kernel_updater.sh and systemdboot_updater.sh.
* hard-coded paths: swupd assumes Clear Linux as a host OS and hard-codes
  several paths to directories, programs and configuration files on Clear.
* builds a lot of images: due to the approach taken there are n+2 images built,
  where n is the number of bundles defined in SWUPD_BUNDLES.
* creates a lot of duplicate files: due to the way swupd works by processing
  chroot-like bundle directories on each os release we potentially end up
  carrying a lot of duplicate files in DEPLOY_DIR_SWUPD. We intend to look at
  using the hardlink program to replace duplicate files in that directory with
  hard links in order to save disk space.
* requires far more testing: there are a lot of combinations of bundle contents,
  rootfs modification commands (IMAGE_POSTPROCESS_COMMAND,
  IMAGE_PREPROCESS_COMMAND, etc) that can affect the inputs to swupd and our
  testing has likely missed areas of issue.
* OS_VERSION: introduces a new variable for the OS version number when we
  already have a DISTRO_VERSION variable. This was done because swupd makes
  various assumptions about the version number which aren't necessarily true for
  traditional DISTRO_VERSION values in OE et al.

Example run:

# swupd verify -u 192.167.7.1/update
swupd-client software verify 2.87
  Copyright (C) 2012-2015 Intel Corporation
  bsdiff portions Copyright Colin Percival, see COPYING file for details

Verifying version 10
Verifying files
Inspected 2094 files
  0 files did not match
Verify succesdful

# swupd update -u 192.167.7.1/update
swupd-client software verify 2.87
  Copyright (C) 2012-2015 Intel Corporation
  bsdiff portions Copyright Colin Percival, see COPYING file for details

Update started.
Querying server version.
Perparing to update from 10 to 20
Querying current manifest.
Querying server manifest.
Running script 'Pre-update'
Downloading os-core pack for version 20
Extracting pack.

Statistics for going from version 20 to version 20:

    changed manifests : 3
    new manifests     : 0
    deleted manifests : 0

    changed files     : 258
    new files         : 35
    deleted files     : 0

 200...downloading files, this may take a while
Staging file content
Update was applied.
Update successful. System updated from version 10 to version 20
Calling post-update helper scripts.
No kernel update needed, skipping helper call out.
No bootloader updated needed, skipping helper call out.
Update exiting.

# swupd verify -u 192.167.7.1/update
swupd-client software verify 2.87
  Copyright (C) 2012-2015 Intel Corporation
  bsdiff portions Copyright Colin Percival, see COPYING file for details

Verifying version 20
Verifying files
Inspected 2112 files
  0 files did not match
Verify successful

---

The following changes since commit 205b446f3fc4a9885179a66a8dab9d81bcc63dca:

  uclibc: Do not use immediate expansion operator (2016-02-22 20:42:34 +0000)

are available in the git repository at:

  git://git.openembedded.org/openembedded-core-contrib joshuagl/swupd
  http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=joshuagl/swupd

Joshua Lock (9):
  rsync: add native variant
  swupd-server: initial recipe 2.53
  hardlink: add new recipe
  swupdbundle: new class to generate virtual images for swupd-image
  swupd-image.bbclass: initial class to support swupd updater
  oe-swupd-helpers: provide swupd-client required helper scripts and
    units
  swupd-client: RDEPENDS on oe-swupd-helpers
  swupd-client: enable native builds
  os-release: sanitise VERSION_ID field

Mariano Lopez (1):
  swupd-client: Add recipe

 meta/classes/swupd-image.bbclass                   | 372 ++++++++++
 meta/classes/swupdbundle.bbclass                   |  59 ++
 meta/recipes-core/os-release/os-release.bb         |   9 +
 meta/recipes-devtools/rsync/rsync_3.1.2.bb         |   2 +
 meta/recipes-devtools/swupd/oe-swupd-helpers.bb    |  39 +
 .../swupd/oe-swupd-helpers/catalog-trigger.service |   8 +
 .../swupd/oe-swupd-helpers/clr_pre_update.sh       |  16 +
 .../swupd/oe-swupd-helpers/kernel_updater.sh       |   9 +
 .../oe-swupd-helpers/ldconfig-trigger.service      |   8 +
 .../swupd/oe-swupd-helpers/systemdboot_updater.sh  |  10 +
 .../oe-swupd-helpers/tmpfiles-trigger.service      |   8 +
 .../swupd/oe-swupd-helpers/update-triggers.target  |   5 +
 .../0001-Tolerate-quotes-in-os-release-files.patch |  59 ++
 ...hange-systemctl-path-to-OE-systemctl-path.patch |  31 +
 .../swupd-client/Fix-build-failure-on-Yocto.patch  |  36 +
 .../Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch    |  38 +
 meta/recipes-devtools/swupd/swupd-client_2.87.bb   |  49 ++
 ...S-to-take-the-state-data-dir-as-an-argume.patch | 782 +++++++++++++++++++++
 ...argv-helper-for-safer-calls-to-system-uti.patch | 133 ++++
 ...re-option-to-re-enable-config-files-in-ma.patch |  66 ++
 ...ression-that-introduced-a-directory-named.patch |  29 +
 meta/recipes-devtools/swupd/swupd-server_2.53.bb   |  33 +
 meta/recipes-extended/hardlink/hardlink_0.3.0.bb   |  19 +
 23 files changed, 1820 insertions(+)
 create mode 100644 meta/classes/swupd-image.bbclass
 create mode 100644 meta/classes/swupdbundle.bbclass
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers.bb
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client_2.87.bb
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server_2.53.bb
 create mode 100644 meta/recipes-extended/hardlink/hardlink_0.3.0.bb

--
2.5.0


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 01/10] rsync: add native variant
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 14:52 ` [PATCH 02/10] swupd-server: initial recipe 2.53 Joshua Lock
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

---
 meta/recipes-devtools/rsync/rsync_3.1.2.bb | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/meta/recipes-devtools/rsync/rsync_3.1.2.bb b/meta/recipes-devtools/rsync/rsync_3.1.2.bb
index 71c2045..7237f43 100644
--- a/meta/recipes-devtools/rsync/rsync_3.1.2.bb
+++ b/meta/recipes-devtools/rsync/rsync_3.1.2.bb
@@ -26,3 +26,5 @@ do_configure_prepend () {
 do_configure_append () {
 	cp -f ${S}/configure ${S}/configure.sh
 }
+
+BBCLASSEXTEND = "native"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 02/10] swupd-server: initial recipe 2.53
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
  2016-02-24 14:52 ` [PATCH 01/10] rsync: add native variant Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-25  8:11   ` Maciej Borzecki
  2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

Include some patches to remove hard-coded state directory and backport some
fixes.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 ...S-to-take-the-state-data-dir-as-an-argume.patch | 782 +++++++++++++++++++++
 ...argv-helper-for-safer-calls-to-system-uti.patch | 133 ++++
 ...re-option-to-re-enable-config-files-in-ma.patch |  66 ++
 ...ression-that-introduced-a-directory-named.patch |  29 +
 meta/recipes-devtools/swupd/swupd-server_2.53.bb   |  33 +
 5 files changed, 1043 insertions(+)
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-server_2.53.bb

diff --git a/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch b/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
new file mode 100644
index 0000000..b771e0a
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
@@ -0,0 +1,782 @@
+From 83fbb8a78594cf9047e37ed0aa1e931b9d691f2a Mon Sep 17 00:00:00 2001
+From: Joshua Lock <joshua.g.lock@intel.com>
+Date: Thu, 28 Jan 2016 10:24:56 +0000
+Subject: [PATCH 1/2] Add option -S to take the state data dir as an argument
+
+The optional -S option expects a full path to a directory
+swupd-server should use instead of the default /var/lib/update.
+
+Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
+
+Upstream-Status: Accepted (v3.0+)
+
+---
+ include/swupd.h      | 11 ++++++---
+ src/analyze_fs.c     |  4 ++--
+ src/chroot.c         | 13 ++++++-----
+ src/globals.c        | 53 +++++++++++++++++++++++++++++++++++++++++
+ src/main.c           | 50 ++++++++++++++++++++++++++++++---------
+ src/make_fullfiles.c | 63 +++++++++++++++++++++++++++++++++++++++++++++----
+ src/make_packs.c     | 66 ++++++++++++++++++++++++++++++++++++++++++++--------
+ src/pack.c           | 65 +++++++++++++++++++++++++++------------------------
+ src/rename.c         |  6 ++---
+ src/versions.c       |  6 ++---
+ 10 files changed, 264 insertions(+), 73 deletions(-)
+
+diff --git a/include/swupd.h b/include/swupd.h
+index 775c28e..58307d9 100644
+--- a/include/swupd.h
++++ b/include/swupd.h
+@@ -16,9 +16,6 @@
+ #define SWUPD_DEFAULT_FORMAT	3
+ 
+ #define SWUPD_SERVER_STATE_DIR "/var/lib/update"
+-#define PACKSTAGE_DIR SWUPD_SERVER_STATE_DIR "/packstage"
+-#define IMAGE_DIR SWUPD_SERVER_STATE_DIR "/image"
+-#define STAGING_DIR SWUPD_SERVER_STATE_DIR "/www"
+ 
+ #if SWUPD_WITH_SELINUX
+ #define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*' --selinux"
+@@ -123,9 +120,17 @@ extern int newversion;
+ extern int minversion;
+ extern char *format_string;
+ 
++extern char *state_dir;
++extern char *packstage_dir;
++extern char *image_dir;
++extern char *staging_dir;
++
+ extern bool init_globals(void);
+ extern void free_globals(void);
+ extern bool set_format_string(char *);
++extern bool set_state_dir(char *);
++extern bool init_state_globals(void);
++extern void free_state_globals(void);
+ 
+ extern int file_sort_hash(gconstpointer a, gconstpointer b);
+ extern int file_sort_filename(gconstpointer a, gconstpointer b);
+diff --git a/src/analyze_fs.c b/src/analyze_fs.c
+index 2326237..fdc359a 100644
+--- a/src/analyze_fs.c
++++ b/src/analyze_fs.c
+@@ -389,7 +389,7 @@ struct manifest *full_manifest_from_directory(int version)
+ 
+ 	manifest = alloc_manifest(version, "full");
+ 
+-	string_or_die(&dir, "%s/%i/full", IMAGE_DIR, version);
++	string_or_die(&dir, "%s/%i/full", image_dir, version);
+ 
+ 	threadpool = g_thread_pool_new(get_hash, dir, 12, FALSE, NULL);
+ 
+@@ -413,7 +413,7 @@ struct manifest *sub_manifest_from_directory(char *component, int version)
+ 
+ 	manifest = alloc_manifest(version, component);
+ 
+-	string_or_die(&dir, "%s/%i/%s", IMAGE_DIR, version, component);
++	string_or_die(&dir, "%s/%i/%s", image_dir, version, component);
+ 
+ 	iterate_directory(manifest, dir, "", false);
+ 
+diff --git a/src/chroot.c b/src/chroot.c
+index 1d7df95..c5bb942 100644
+--- a/src/chroot.c
++++ b/src/chroot.c
+@@ -40,14 +40,15 @@ void chroot_create_full(int newversion)
+ 	char * command;
+ 	char *full_dir;
+ 
+-	string_or_die(&full_dir, "%s/%i/full/", IMAGE_DIR, newversion);
++	string_or_die(&full_dir, "%s/%i/full/ ", image_dir, newversion);
+ 
+ 	g_mkdir_with_parents(full_dir, S_IRWXU);
+ 
+ 
+ 	/* start with base */
+ 	LOG(NULL, "Copying chroot os-core to full", "");
+-	string_or_die(&command, "rsync -aAX " IMAGE_DIR "/%i/os-core/ %s", newversion, full_dir);
++	string_or_die(&command, "rsync -aAX %s/%i/os-core/ %s",
++	              image_dir, newversion, full_dir);
+ 	ret = system(command);
+ 	assert(ret==0);
+ 	free(command);
+@@ -60,8 +61,8 @@ void chroot_create_full(int newversion)
+ 		}
+ 
+ 		LOG(NULL, "Overlaying bundle chroot onto full", "%s", group);
+-		string_or_die(&command, "rsync -aAX --ignore-existing " IMAGE_DIR "/%i/%s/ %s",
+-		             newversion, group, full_dir);
++		string_or_die(&command, "rsync -aAX --ignore-existing %s/%i/%s/ %s",
++		             image_dir, newversion, group, full_dir);
+ 		ret = system(command);
+ 		assert(ret==0);
+ 		free(command);
+@@ -80,8 +81,8 @@ void chroot_create_full(int newversion)
+ 		}
+ 
+ 		LOG(NULL, "Recopy bundle chroot out of full", "%s", group);
+-		string_or_die(&command, "rsync -aAX --existing %s " IMAGE_DIR "/%i/%s",
+-		             full_dir, newversion, group);
++		string_or_die(&command, "rsync -aAX --existing %s %s/%i/%s",
++		             full_dir, image_dir, newversion, group);
+ 		ret = system(command);
+ 		assert(ret==0);
+ 		free(command);
+diff --git a/src/globals.c b/src/globals.c
+index 32dc793..ff6a3fa 100644
+--- a/src/globals.c
++++ b/src/globals.c
+@@ -34,6 +34,11 @@ int newversion = -1;
+ int minversion = 0;
+ char *format_string = NULL;
+ 
++char *state_dir = NULL;
++char *packstage_dir = NULL;
++char *image_dir = NULL;
++char *staging_dir = NULL;
++
+ bool set_format_string(char *userinput)
+ {
+ 	int version;
+@@ -52,12 +57,36 @@ bool set_format_string(char *userinput)
+ 	return true;
+ }
+ 
++bool set_state_dir(char *dir)
++{
++	if (dir == NULL || dir[0] == '\0') {
++		return false;
++	}
++
++	/* TODO: more validation of input? */
++	if (dir[0] != '/') {
++		printf("statedir must be a full path starting with '/', not '%c'\n", dir[0]);
++		return false;
++	}
++
++	if (state_dir) {
++		free(state_dir);
++	}
++	string_or_die(&state_dir, "%s", dir);
++
++	return true;
++}
++
+ bool init_globals(void)
+ {
+ 	if (format_string == NULL) {
+ 		string_or_die(&format_string, "%d", SWUPD_DEFAULT_FORMAT);
+ 	}
+ 
++	if (!init_state_globals()) {
++		return false;
++	}
++
+ 	if (newversion == -1) {
+ 		printf("Missing version parameter: No new version number specified\n");
+ 		return false;
+@@ -71,4 +100,28 @@ bool init_globals(void)
+ void free_globals(void)
+ {
+ 	free(format_string);
++	free(state_dir);
++	free(packstage_dir);
++	free(image_dir);
++	free(staging_dir);
++}
++
++bool init_state_globals(void)
++{
++	if (state_dir == NULL) {
++		string_or_die(&state_dir, "%s", SWUPD_SERVER_STATE_DIR);
++	}
++	string_or_die(&packstage_dir, "%s/%s", state_dir, "packstage");
++	string_or_die(&image_dir, "%s/%s", state_dir, "image");
++	string_or_die(&staging_dir, "%s/%s", state_dir, "www");
++
++	return true;
++}
++
++void free_state_globals(void)
++{
++	free(state_dir);
++	free(packstage_dir);
++	free(image_dir);
++	free(staging_dir);
+ }
+diff --git a/src/main.c b/src/main.c
+index 7ed71d5..3d5f24a 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -55,6 +55,7 @@ static const struct option prog_opts[] = {
+ 	{"minversion", required_argument, 0, 'm'},
+ 	{"format", required_argument, 0, 'F'},
+ 	{"getformat", no_argument, 0, 'g'},
++	{"statedir", required_argument, 0, 'S'},
+ 	{0, 0, 0, 0}
+ };
+ 
+@@ -70,6 +71,7 @@ static void print_help(const char *name) {
+ 	printf("   -m, --minversion        Optional minimum file version to write into manifests per file\n");
+ 	printf("   -F, --format            Optional format string [ default:=%d ]\n", SWUPD_DEFAULT_FORMAT);
+ 	printf("   -g, --getformat         Print current format string and exit\n");
++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
+ 	printf("\n");
+ }
+ 
+@@ -77,7 +79,7 @@ static bool parse_options(int argc, char **argv)
+ {
+ 	int opt;
+ 
+-	while ((opt = getopt_long(argc, argv, "hvo:m:F:g", prog_opts, NULL)) != -1) {
++	while ((opt = getopt_long(argc, argv, "hvo:m:F:g:S:", prog_opts, NULL)) != -1) {
+ 		switch (opt) {
+ 		case '?':
+ 		case 'h':
+@@ -107,6 +109,12 @@ static bool parse_options(int argc, char **argv)
+ 				return false;
+ 			}
+ 			break;
++		case 'S':
++			if (!optarg || !set_state_dir(optarg)) {
++				printf("Invalid --statedir argument ''%s'\n\n", optarg);
++				return false;
++			}
++			break;
+ 		case 'g':
+ 			if (format_string == NULL) {
+ 				printf("%d\n", SWUPD_DEFAULT_FORMAT);
+@@ -138,9 +146,14 @@ static void check_root(void)
+ static void populate_dirs(int version)
+ {
+ 	char *newversiondir;
+-	string_or_die(&newversiondir, "%s/%d", IMAGE_DIR, version);
++
++	string_or_die(&newversiondir, "%s/%d", image_dir, version);
+ 
+ 	if ((access(newversiondir, F_OK | R_OK) != 0) && (version == 0)) {
++		char *latestpath = NULL;
++
++		string_or_die(&latestpath, "%s/latest.version", image_dir);
++
+ 		printf("** %s does not exist... creating and populating\n", newversiondir);
+ 		if (mkdir(newversiondir, 0755) != 0) {
+ 			printf("Failed to create directory\n");
+@@ -151,14 +164,17 @@ static void populate_dirs(int version)
+ 		}
+ 
+ 		FILE *latestver;
+-		latestver = fopen_exclusive(IMAGE_DIR "/latest.version");
++		latestver = fopen_exclusive(latestpath);
+ 		if (latestver == NULL) {
+-			printf("Failed to create %s/latest.version\n", IMAGE_DIR);
++			printf("Failed to create %s\n", latestpath);
++			free(latestpath);
+ 			return;
+ 		}
+ 		if (fwrite("0\n", 2, 1, latestver) != 1) {
+ 			LOG(NULL, "Failed to write latestver", "errno: %d", errno);
+ 		}
++
++		free(latestpath);
+ 		fclose(latestver);
+ 	}
+ 	/* groups don't exist in version 0 */
+@@ -170,7 +186,7 @@ static void populate_dirs(int version)
+ 				break;
+ 			}
+ 
+-			string_or_die(&newversiondir, "%s/%d/%s", IMAGE_DIR, version, group);
++			string_or_die(&newversiondir, "%s/%d/%s", image_dir, version, group);
+ 
+ 			/* Create the bundle directory(s) as needed */
+ 			if (access(newversiondir, F_OK | R_OK) != 0) {
+@@ -186,13 +202,18 @@ static void populate_dirs(int version)
+ 
+ static int check_build_env(void)
+ {
+-	if (access(SWUPD_SERVER_STATE_DIR "/temp", F_OK | R_OK) != 0) {
+-		LOG(NULL, "/var/lib/update/temp does not exist...creating directory", "");
+-		if (mkdir(SWUPD_SERVER_STATE_DIR "/temp", 0755) != 0) {
++	char *temp_dir = NULL;
++	string_or_die(&temp_dir, "%s/%s", state_dir, "/temp");
++
++	if (access(temp_dir, F_OK | R_OK) != 0) {
++		LOG(NULL, "%s", "does not exist...creating directory", temp_dir);
++		if (mkdir(temp_dir, 0755) != 0) {
+ 			printf("Failed to create build directory, EXITING\n");
++			free(temp_dir);
+ 			return -errno;
+ 		}
+ 	}
++	free(temp_dir);
+ 
+ 	return 0;
+ }
+@@ -217,6 +238,8 @@ int main(int argc, char **argv)
+ 	int exit_status = EXIT_FAILURE;
+ 	int ret;
+ 
++	char *file_path = NULL;
++
+ 	/* keep valgrind working well */
+ 	setenv("G_SLICE", "always-malloc", 0);
+ 
+@@ -240,12 +263,17 @@ int main(int argc, char **argv)
+ 	}
+ 
+ 
+-	if (!read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini")) {
+-		printf("Failed to read " SWUPD_SERVER_STATE_DIR "/server.ini configuration file!\n");
++	string_or_die(&file_path, "%s/server.ini", state_dir);
++	if (!read_configuration_file(file_path)) {
++		printf("Failed to read %s configuration file!\n", state_dir);
++		free(file_path);
+ 		goto exit;
+ 	}
++	free(file_path);
+ 
+-	read_group_file(SWUPD_SERVER_STATE_DIR "/groups.ini");
++	string_or_die(&file_path, "%s/groups.ini", state_dir);
++	read_group_file(file_path);
++	free(file_path);
+ 
+ 	read_current_version("latest.version");
+ 	printf("Last processed version is %i\n", current_version);
+diff --git a/src/make_fullfiles.c b/src/make_fullfiles.c
+index e755a33..bf97a1c 100644
+--- a/src/make_fullfiles.c
++++ b/src/make_fullfiles.c
+@@ -27,8 +27,52 @@
+ #include <string.h>
+ #include <assert.h>
+ 
++#include <getopt.h>
++
+ #include <swupd.h>
+ 
++static const struct option prog_opts[] = {
++	{"help", no_argument, 0, 'h'},
++	{"statedir", required_argument, 0, 'S'},
++	{0, 0, 0, 0}
++};
++
++static void usage(const char *name)
++{
++	printf("usage:\n");
++	printf("   %s <version>\n\n", name);
++	printf("Help options:\n");
++	printf("   -h, --help              Show help options\n");
++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
++	printf("\n");
++}
++
++static bool parse_options(int argc, char **argv)
++{
++	int opt;
++
++	while ((opt = getopt_long(argc, argv, "hS:", prog_opts, NULL)) != -1) {
++		switch (opt) {
++			case '?':
++			case 'h':
++				usage(argv[0]);
++				return false;
++			case 'S':
++				if (!optarg || !set_state_dir(optarg)) {
++					printf("Invalid --statedir argument '%s'\n\n", optarg);
++					return false;
++				}
++				break;
++		}
++	}
++
++	if (!init_state_globals()) {
++		return false;
++	}
++
++	return true;
++}
++
+ static void banner(void)
+ {
+ 	printf(PACKAGE_NAME " update creator -- fullfiles -- version " PACKAGE_VERSION "\n");
+@@ -51,20 +95,29 @@ int main(int argc, char **argv)
+ {
+ 	struct manifest *manifest;
+ 	int version;
++	char *file_path = NULL;
+ 
+ 	/* keep valgrind working well */
+ 	setenv("G_SLICE", "always-malloc", 0);
+ 
++	if (!parse_options(argc, argv)) {
++		free_state_globals();
++		return EXIT_FAILURE;
++	}
+ 	banner();
+ 	check_root();
+ 
+-	read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini");
++	string_or_die(&file_path, "%s/server.ini", state_dir);
++	read_configuration_file(file_path);
++	free(file_path);
+ 
+-	if (argc < 1) {
+-		printf("Usage:\n\tswupd_make_fullfiles <version>\n\n");
++	if (argc - optind < 1) {
++		usage(argv[0]);
++		free_state_globals();
+ 		exit(EXIT_FAILURE);
+ 	}
+-	version = strtoull(argv[1], NULL, 10);
++
++	version = strtoull(argv[optind++], NULL, 10);
+ 	if (version < 0) {
+ 		printf("Usage:\n\tswupd_make_fullfiles <version>\n\n");
+ 		exit(EXIT_FAILURE);
+@@ -73,5 +126,7 @@ int main(int argc, char **argv)
+ 	manifest = manifest_from_file(version, "full");
+ 	create_fullfiles(manifest);
+ 
++	free_state_globals();
++
+ 	return EXIT_SUCCESS;
+ }
+diff --git a/src/make_packs.c b/src/make_packs.c
+index 20fbd67..2b62b8a 100644
+--- a/src/make_packs.c
++++ b/src/make_packs.c
+@@ -33,6 +33,8 @@
+ 
+ #include <glib.h>
+ 
++#include <getopt.h>
++
+ #include <swupd.h>
+ 
+ static void banner(void)
+@@ -43,12 +45,47 @@ static void banner(void)
+ 	printf("\n");
+ }
+ 
+-static void usage(void)
++static const struct option prog_opts[] = {
++	{"help", no_argument, 0, 'h'},
++	{"statedir", required_argument, 0, 'S'},
++	{0, 0, 0, 0}
++};
++
++static void usage(const char *name)
+ {
+ 	printf("usage:\n");
+-	printf("   swupd_make_pack <start version> <latest version> <bundle>\n");
++	printf("   %s <start version> <latest version> <bundle>\n\n", name);
++	printf("Help options:\n");
++	printf("   -h, --help              Show help options\n");
++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
+ 	printf("\n");
+-	exit(EXIT_FAILURE);
++}
++
++static bool parse_options(int argc, char **argv)
++{
++	int opt;
++
++	while ((opt = getopt_long(argc, argv, "hS:", prog_opts, NULL)) != -1) {
++		switch (opt) {
++		case '?':
++		case 'h':
++			usage(argv[0]);
++			return false;
++		case 'S':
++			if (!optarg || !set_state_dir(optarg)) {
++				printf("Invalid --statedir argument ''%s'\n\n", optarg);
++				return false;
++			}
++			break;
++		}
++	}
++
++	/* FIXME: *_state_globals() are ugly hacks */
++	if (!init_state_globals()) {
++		return false;
++	}
++
++	return true;
+ }
+ 
+ int main(int argc, char **argv)
+@@ -59,11 +96,17 @@ int main(int argc, char **argv)
+ 	char *module;
+ 	struct packdata *pack;
+ 	int exit_status = EXIT_FAILURE;
++	char *file_path = NULL;
+ 
++	if (!parse_options(argc, argv)) {
++		free_state_globals();
++		return EXIT_FAILURE;
++	}
+ 	banner();
+ 
+-	if (argc != 4) {
+-		usage();
++	if (argc - optind != 3) {
++		usage(argv[0]);
++		exit(EXIT_FAILURE);
+ 	}
+ 
+ 	/* FIXME: should use "end_version" not "0" and a unique filename
+@@ -76,12 +119,13 @@ int main(int argc, char **argv)
+ 		return exit_status;
+ 	}
+ 
+-	read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini");
+-
++	string_or_die(&file_path, "%s/server.ini", state_dir);
++	read_configuration_file(file_path);
++	free(file_path);
+ 
+-	start_version = strtoull(argv[1], NULL, 10);
+-	end_version = strtoull(argv[2], NULL, 10);
+-	module = argv[3];
++	start_version = strtoull(argv[optind++], NULL, 10);
++	end_version = strtoull(argv[optind++], NULL, 10);
++	module = argv[optind++];
+ 
+ 	if ((start_version < 0) ||
+ 	    (end_version == 0) ||
+@@ -108,5 +152,7 @@ int main(int argc, char **argv)
+ 	printf("Pack creation %s (pack-%s %i to %li)\n",
+ 		exit_status == EXIT_SUCCESS ? "complete" : "failed",
+ 		module, start_version, end_version);
++
++	free_state_globals();
+ 	return exit_status;
+ }
+diff --git a/src/pack.c b/src/pack.c
+index e96e9a4..036853f 100644
+--- a/src/pack.c
++++ b/src/pack.c
+@@ -46,21 +46,21 @@ static void empty_pack_stage(int full, int version, char *module)
+ 	int ret;
+ 
+ 	// clean any stale data (eg: re-run after a failure)
+-	string_or_die(&cmd, "rm -rf " PACKSTAGE_DIR "/%s/%i/", module, version);
++	string_or_die(&cmd, "rm -rf %s/%s/%i/", packstage_dir, module, version);
+ 	ret = system(cmd);
+ 	if (ret) {
+-		fprintf(stderr, "Failed to clean " PACKSTAGE_DIR "/%s/%i\n",
+-			module, version);
++		fprintf(stderr, "Failed to clean %s/%s/%i\n",
++			packstage_dir, module, version);
+ 		exit(EXIT_FAILURE);
+ 	}
+ 	free(cmd);
+ 
+ 	if (!full) {
+ 		// (re)create module/version/{delta,staged}
+-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/delta", module, version);
++		string_or_die(&path, "%s/%s/%i/delta", packstage_dir, module, version);
+ 		g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
+ 		free(path);
+-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged", module, version);
++		string_or_die(&path, "%s/%s/%i/staged", packstage_dir, module, version);
+ 		g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
+ 		free(path);
+ 	}
+@@ -76,7 +76,7 @@ static void explode_pack_stage(int version, char *module)
+ 	struct stat buf;
+ 	char *path;
+ 
+-	string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged", module, version);
++	string_or_die(&path, "%s/%s/%i/staged", packstage_dir, module, version);
+ 	g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
+ 	dir = opendir(path);
+ 	if (!dir) {
+@@ -99,7 +99,8 @@ static void explode_pack_stage(int version, char *module)
+ 			continue;
+ 		}
+ 
+-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged/%s", module, version, entry->d_name);
++		string_or_die(&path, "%s/%s/%i/staged/%s",
++		              packstage_dir, module, version, entry->d_name);
+ 		ret = stat(path, &buf);
+ 		if (ret) {
+ 			free(path);
+@@ -112,8 +113,8 @@ static void explode_pack_stage(int version, char *module)
+ 		 * the resulting pack is slightly smaller, and in addition, we're saving CPU
+ 		 * time on the client...
+ 		 */
+-		string_or_die(&tar, "tar --directory=" PACKSTAGE_DIR "/%s/%i/staged --warning=no-timestamp "
+-				TAR_PERM_ATTR_ARGS " -axf %s", module, version, path);
++		string_or_die(&tar, "tar --directory=%s/%s/%i/staged --warning=no-timestamp "
++				TAR_PERM_ATTR_ARGS " -axf %s", packstage_dir, module, version, path);
+ 		ret = system(tar);
+ 		if (!ret) {
+ 			unlink(path);
+@@ -162,8 +163,8 @@ static void make_pack_full_files(struct packdata *pack)
+ 		if ((!file->peer || file->peer->is_deleted) && !file->is_deleted && !file->rename_peer) {
+ 			char *from, *to;
+ 			/* hardlink each file that is in <end> but not in <X> */
+-			string_or_die(&from, STAGING_DIR "/%i/files/%s.tar", file->last_change, file->hash);
+-			string_or_die(&to, PACKSTAGE_DIR "/%s/%i/staged/%s.tar", pack->module, pack->from, file->hash);
++			string_or_die(&from, "%s/%i/files/%s.tar", staging_dir, file->last_change, file->hash);
++			string_or_die(&to, "%s/%s/%i/staged/%s.tar", packstage_dir, pack->module, pack->from, file->hash);
+ 			ret = link(from, to);
+ 			if (ret) {
+ 				if (errno != EEXIST) {
+@@ -228,8 +229,8 @@ static GList *consolidate_packs_delta_files(GList *files, struct packdata *pack)
+ 			continue;
+ 		}
+ 
+-		string_or_die(&from, STAGING_DIR "/%i/delta/%i-%i-%s", file->last_change,
+-				file->peer->last_change, file->last_change, file->hash);
++		string_or_die(&from, "%s/%i/delta/%i-%i-%s", staging_dir, file->last_change,
++		              file->peer->last_change, file->last_change, file->hash);
+ 
+ 		ret = stat(from, &stat_delta);
+ 		if (ret && !find_file_in_list(files, file)) {
+@@ -284,8 +285,8 @@ static int write_pack_signature(struct packdata *pack)
+ 	char *filename = NULL;
+ 	int ret = -1;
+ 
+-	string_or_die(&filename, STAGING_DIR "/%i/pack-%s-from-%i.tar",
+-			pack->to, pack->module, pack->from);
++	string_or_die(&filename, "%s/%i/pack-%s-from-%i.tar",
++			staging_dir, pack->to, pack->module, pack->from);
+ 	if (!signature_sign(filename)) {
+ 		fprintf(stderr, "Creating signature for '%s' failed\n", filename);
+ 		goto exit;
+@@ -324,12 +325,14 @@ static int make_final_pack(struct packdata *pack)
+ 
+ 		/* for each file changed since <X> */
+ 		/* locate delta, check if the diff it's from is >= <X> */
+-		string_or_die(&from, STAGING_DIR "/%i/delta/%i-%i-%s", file->last_change,
+-				file->peer->last_change, file->last_change, file->hash);
+-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/delta/%i-%i-%s", pack->module, pack->from,
++		string_or_die(&from, "%s/%i/delta/%i-%i-%s", staging_dir, file->last_change,
+ 				file->peer->last_change, file->last_change, file->hash);
+-		string_or_die(&tarfrom, STAGING_DIR "/%i/files/%s.tar", file->last_change, file->hash);
+-		string_or_die(&tarto, PACKSTAGE_DIR "/%s/%i/staged/%s.tar", pack->module, pack->from, file->hash);
++		string_or_die(&to, "%s/%s/%i/delta/%i-%i-%s", packstage_dir, pack->module,
++				pack->from, file->peer->last_change, file->last_change, file->hash);
++		string_or_die(&tarfrom, "%s/%i/files/%s.tar", staging_dir,
++				file->last_change, file->hash);
++		string_or_die(&tarto, "%s/%s/%i/staged/%s.tar", packstage_dir, pack->module,
++				pack->from, file->hash);
+ 
+ 		ret = stat(from, &stat_delta);
+ 		if (ret) {
+@@ -388,8 +391,8 @@ static int make_final_pack(struct packdata *pack)
+ 		char *from, *to;
+ 		struct stat st;
+ 
+-		string_or_die(&from, STAGING_DIR "/%i/Manifest-%s-delta-from-%i",
+-				pack->to, pack->module, pack->from);
++		string_or_die(&from, "%s/%i/Manifest-%s-delta-from-%i",
++				staging_dir, pack->to, pack->module, pack->from);
+ 
+ 		ret = stat(from, &st);
+ 		if (ret) {
+@@ -398,8 +401,8 @@ static int make_final_pack(struct packdata *pack)
+ 		}
+ 
+ 
+-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/Manifest-%s-delta-from-%i",
+-				pack->module, pack->from, pack->module, pack->from);
++		string_or_die(&to, "%s/%s/%i/Manifest-%s-delta-from-%i",
++				packstage_dir, pack->module, pack->from, pack->module, pack->from);
+ 
+ 		ret = link(from, to);
+ 		if (ret) {
+@@ -416,16 +419,16 @@ static int make_final_pack(struct packdata *pack)
+ 		char *from, *to;
+ 		struct stat st;
+ 
+-		string_or_die(&from, STAGING_DIR "/%i/Manifest-%s-delta-from-%i",
+-				pack->to, "MoM", pack->from);
++		string_or_die(&from, "%s/%i/Manifest-%s-delta-from-%i",
++				staging_dir, pack->to, "MoM", pack->from);
+ 		ret = stat(from, &st);
+ 		if (ret) {
+ 			LOG(NULL, "Making extra manifest delta", "MoM: %i->%i", pack->from, pack->to);
+ 			create_manifest_delta(pack->from, pack->to, "MoM");
+ 		}
+ 
+-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/Manifest-%s-delta-from-%i",
+-				pack->module, pack->from, "MoM", pack->from);
++		string_or_die(&to, "%s/%s/%i/Manifest-%s-delta-from-%i",
++				packstage_dir, pack->module, pack->from, "MoM", pack->from);
+ 
+ 		ret = link(from, to);
+ 		if (ret) {
+@@ -439,9 +442,9 @@ static int make_final_pack(struct packdata *pack)
+ 
+ 	/* tar the staging directory up */
+ 	LOG(NULL, "starting tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
+-	string_or_die(&tar, "tar " TAR_PERM_ATTR_ARGS " --directory=" PACKSTAGE_DIR "/%s/%i/ "
+-			"--numeric-owner -Jcf " STAGING_DIR "/%i/pack-%s-from-%i.tar delta staged",
+-			pack->module, pack->from, pack->to, pack->module, pack->from);
++	string_or_die(&tar, "tar " TAR_PERM_ATTR_ARGS " --directory=%s/%s/%i/ "
++			"--numeric-owner -Jcf %s/%i/pack-%s-from-%i.tar delta staged",
++			packstage_dir, pack->module, pack->from, staging_dir, pack->to, pack->module, pack->from);
+ 	ret = system(tar);
+ 	free(tar);
+ 	LOG(NULL, "finished tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
+diff --git a/src/rename.c b/src/rename.c
+index 70f9006..5ea979c 100644
+--- a/src/rename.c
++++ b/src/rename.c
+@@ -153,7 +153,7 @@ static void precompute_file_data(struct manifest *manifest, struct file *file, i
+ 	}
+ 
+ 	if (manifest)  {
+-		string_or_die(&filename, "%s/%i/%s/%s", IMAGE_DIR, manifest->version, manifest->component, file->filename);
++		string_or_die(&filename, "%s/%i/%s/%s", image_dir, manifest->version, manifest->component, file->filename);
+ 	} else if (old_rename) {
+ 		item = g_list_first(last_versions_list);
+ 		while (item) {
+@@ -161,13 +161,13 @@ static void precompute_file_data(struct manifest *manifest, struct file *file, i
+ 			item = g_list_next(item);
+ 
+ 			free(filename);
+-			string_or_die(&filename, "%s/%i/full/%s", IMAGE_DIR, last_change, file->filename);
++			string_or_die(&filename, "%s/%i/full/%s", image_dir, last_change, file->filename);
+ 			if (!lstat(filename, &buf)) {
+ 				break;
+ 			}
+ 		}
+ 	} else {
+-		string_or_die(&filename, "%s/%i/full/%s", IMAGE_DIR, file->last_change, file->filename);
++		string_or_die(&filename, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
+ 	}
+ 
+ 	/* make sure file->stat.st_size is valid */
+diff --git a/src/versions.c b/src/versions.c
+index 6860160..0fb729a 100644
+--- a/src/versions.c
++++ b/src/versions.c
+@@ -215,10 +215,10 @@ GList *get_last_versions_list(int next_version, int max_versions)
+ 	int idx, build_num, build_type, jump_point;
+ 	int jump_point_found;
+ 
+-	dir = opendir(STAGING_DIR);
++	dir = opendir(staging_dir);
+ 	if (dir == NULL) {
+ 		LOG(NULL, "Cannot open directory", "dir_path= %s, strerror= %s",
+-				STAGING_DIR, strerror(errno));
++				staging_dir, strerror(errno));
+ 		return NULL;
+ 	}
+ 
+@@ -228,7 +228,7 @@ GList *get_last_versions_list(int next_version, int max_versions)
+ 		}
+ 
+ 		free(filename);
+-		string_or_die(&filename, STAGING_DIR "/%s", entry.d_name);
++		string_or_die(&filename, "%s/%s", staging_dir, entry.d_name);
+ 
+ 		if (lstat(filename, &stat)) {
+ 			LOG(NULL, "lstat failed", "path= %s, strerror= %s",
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch b/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
new file mode 100644
index 0000000..f94305e
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
@@ -0,0 +1,133 @@
+From 8f24ef7f857c9d2c2eb2601a2a1e06123c086001 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+Date: Fri, 29 Jan 2016 17:48:46 +0200
+Subject: [PATCH swupd-server 1/2] Add system_argv() helper for safer calls to
+ system utilities
+
+Often file names contain special characters like hashes or
+whitespaces and that makes escaping a difficult task when using
+system(). Thus add a new helper system_argv() that is based
+on execvp() syscall and doesn't require escaping.
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+
+Upstream-Status: Backport (v2.54+)
+
+---
+ include/swupd.h |  1 +
+ src/fullfiles.c |  6 ++----
+ src/helpers.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 66 insertions(+), 4 deletions(-)
+
+diff --git a/include/swupd.h b/include/swupd.h
+index 00b88d4..2805186 100644
+--- a/include/swupd.h
++++ b/include/swupd.h
+@@ -223,6 +223,7 @@ extern FILE * fopen_exclusive(const char *filename); /* no mode, opens for write
+ extern void dump_file_info(struct file *file);
+ extern void string_or_die(char **strp, const char *fmt, ...);
+ extern void print_elapsed_time(struct timeval *previous_time, struct timeval *current_time);
++extern int system_argv(char *const argv[]);
+ 
+ extern bool signature_initialize(void);
+ extern void signature_terminate(void);
+diff --git a/src/fullfiles.c b/src/fullfiles.c
+index 1bb581e..fa78293 100644
+--- a/src/fullfiles.c
++++ b/src/fullfiles.c
+@@ -138,12 +138,10 @@ static void create_fullfile(struct file *file)
+ 		string_or_die(&tempfile, "%s/%s", empty, file->hash);
+ 		if (link(origin, tempfile) < 0) {
+ 			LOG(NULL, "hardlink failed", "%s due to %s (%s -> %s)", file->filename, strerror(errno), origin, tempfile);
+-			string_or_die(&tarcommand, "cp -a %s %s", origin, tempfile);
+-			if (system(tarcommand) != 0) {
+-				LOG(NULL, "Failed to run command:", "%s", tarcommand);
++			char *const argv[] = {"cp", "-a", origin, tempfile, NULL};
++			if (system_argv(argv) != 0) {
+ 				assert(0);
+ 			}
+-			free(tarcommand);
+ 		}
+ 
+ 		/* step 2a: tar it with each compression type  */
+diff --git a/src/helpers.c b/src/helpers.c
+index 65acffd..5884b51 100644
+--- a/src/helpers.c
++++ b/src/helpers.c
+@@ -29,6 +29,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
++#include <sys/wait.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ 
+@@ -124,3 +125,65 @@ void print_elapsed_time(struct timeval *previous_time, struct timeval *current_t
+ 
+ 	free(elapsed);
+ }
++
++void concat_str_array(char **output, char *const argv[])
++{
++	int size = 0;
++
++	for (int i = 0; argv[i]; i++) {
++		size += strlen(argv[i]) + 1;
++	}
++
++	*output = malloc(size + 1);
++	if (!*output) {
++		LOG(NULL, "Failed to allocate", "%i bytes", size);
++		assert(0);
++	}
++	strcpy(*output, "");
++	for (int i = 0; argv[i]; i++) {
++		strcat(*output, argv[i]);
++		strcat(*output, " ");
++	}
++}
++
++int system_argv(char *const argv[])
++{
++	int child_exit_status;
++	pid_t pid;
++	int status;
++
++	pid = fork();
++
++	if (pid == 0) { /* child */
++		execvp(*argv, argv);
++		LOG(NULL, "This line must not be reached", "");
++		assert(0);
++	} else if (pid < 0) {
++		LOG(NULL, "Failed to fork a child process", "");
++		assert(0);
++	} else {
++		pid_t ws = waitpid(pid, &child_exit_status, 0);
++
++		if (ws == -1) {
++			LOG(NULL, "Failed to wait for child process", "");
++			assert(0);
++		}
++
++		if (WIFEXITED(child_exit_status)) {
++			status = WEXITSTATUS(child_exit_status);
++		} else {
++			LOG(NULL, "Child process didn't exit", "");
++			assert(0);
++		}
++
++		if (status != 0) {
++			char* cmdline = NULL;
++
++			concat_str_array(&cmdline, argv);
++			LOG(NULL, "Failed to run command:", "%s", cmdline);
++			free(cmdline);
++		}
++
++		return status;
++	}
++}
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch b/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
new file mode 100644
index 0000000..a5ab7af
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
@@ -0,0 +1,66 @@
+From e209255d8985eb4eb4c43f5e773ee1a0a16eb297 Mon Sep 17 00:00:00 2001
+From: Joshua Lock <joshua.g.lock@intel.com>
+Date: Fri, 12 Feb 2016 16:02:58 +0000
+Subject: [PATCH 2/2] Add configure option to re-enable config files in
+ manifests
+
+Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
+
+Upstream-Status: Accepted (v3.0+)
+
+---
+ configure.ac    | 6 ++++++
+ include/swupd.h | 6 ++++++
+ src/manifest.c  | 2 +-
+ 3 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 8bb6e3b..afffad5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -28,6 +28,12 @@ AC_ARG_ENABLE(
+     AC_DEFINE(SWUPD_WITH_LZMA,1,[Use lzma compression])
+ 	[enable_lzma=check]
+ )
++AC_ARG_ENABLE(
++    [stateless],
++    AS_HELP_STRING([--disable-stateless],[OS is not stateless, do not ignore configuration files (stateless by default)]),
++    AC_DEFINE(SWUPD_WITH_STATELESS,0,[OS is not stateless]),
++		AC_DEFINE(SWUPD_WITH_STATELESS,1,[OS is stateless])
++)
+ 
+ AS_IF([test "$enable_lzma" = "check"],
+ 	[PKG_CHECK_MODULES([lzma],
+diff --git a/include/swupd.h b/include/swupd.h
+index 58307d9..7cce735 100644
+--- a/include/swupd.h
++++ b/include/swupd.h
+@@ -23,6 +23,12 @@
+ #define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*'"
+ #endif
+ 
++#if SWUPD_WITH_STATELESS
++#define OS_IS_STATELESS 1
++#else
++#define OS_IS_STATELESS 0
++#endif
++
+ /* Build types */
+ #define REGULAR_BUILD 0
+ #define FIX_BUILD     1
+diff --git a/src/manifest.c b/src/manifest.c
+index 69a8fb9..58d0be1 100644
+--- a/src/manifest.c
++++ b/src/manifest.c
+@@ -830,7 +830,7 @@ int prune_manifest(struct manifest *manifest)
+ 		next = g_list_next(list);
+ 		file = list->data;
+ 
+-		if ((!file->is_deleted) && (file->is_config)) {
++		if (OS_IS_STATELESS && (!file->is_deleted) && (file->is_config)) {
+ 			// toward being a stateless OS
+ 			LOG(file, "Skipping config file in manifest write", "component %s", manifest->component);
+ 			manifest->files = g_list_delete_link(manifest->files, list);
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch b/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
new file mode 100644
index 0000000..9c1d8fa
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
@@ -0,0 +1,29 @@
+From aba4418696ef31ab5afc9811903a044366619dc4 Mon Sep 17 00:00:00 2001
+From: Patrick McCarty <patrick.mccarty@intel.com>
+Date: Mon, 22 Feb 2016 22:07:08 -0800
+Subject: [PATCH 2/4] Fix regression that introduced a directory named '/ '
+
+Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
+
+Upstream-Status: Backport (v3.0+)
+
+---
+ src/chroot.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/chroot.c b/src/chroot.c
+index f961d58..2878496 100644
+--- a/src/chroot.c
++++ b/src/chroot.c
+@@ -40,7 +40,7 @@ void chroot_create_full(int newversion)
+ 	char * command;
+ 	char *full_dir;
+ 
+-	string_or_die(&full_dir, "%s/%i/full/ ", image_dir, newversion);
++	string_or_die(&full_dir, "%s/%i/full/", image_dir, newversion);
+ 
+ 	g_mkdir_with_parents(full_dir, S_IRWXU);
+ 
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-server_2.53.bb b/meta/recipes-devtools/swupd/swupd-server_2.53.bb
new file mode 100644
index 0000000..fdbd39b
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-server_2.53.bb
@@ -0,0 +1,33 @@
+SUMMARY = "swupd sofware update from Clear Linux - server component"
+LICENSE = "GPL-2.0"
+LIC_FILES_CHKSUM = "file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
+                    file://bsdiff/LICENSE;md5=0dbe7a50f028269750631fcbded3846a"
+
+DEPENDS = "file xz glib-2.0 zlib bzip2 tar rsync openssl"
+
+SRC_URI = "\
+    https://download.clearlinux.org/releases/5940/clear/source/SRPMS/${BPN}-${PV}-4.src.rpm;extract=${BP}.tar.gz \
+    file://0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch \
+    file://0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch \
+    file://0002-Add-configure-option-to-re-enable-config-files-in-ma.patch \
+    file://0002-Fix-regression-that-introduced-a-directory-named.patch \
+"
+
+SRC_URI[md5sum] = "14f25677b5a4f0b33785910b03860939"
+SRC_URI[sha256sum] = "c2d0e595444fe198c4092dd83d20a929fd1402a13b66b410b76677ed3a993d99"
+
+inherit autotools
+
+EXTRA_OECONF = "--enable-bzip2 --enable-lzma --disable-stateless"
+
+# safer-calls-to-system-utilities.patch uses for loop initial declaration
+CFLAGS_append = " -std=c99"
+
+do_install_append () {
+    mkdir -p ${D}${sysconfdir}/swupd-certs
+    install -m 0755 ${S}/test/signature/* ${D}${sysconfdir}/swupd-certs/
+}
+
+RDEPENDS_${PN} = "tar rsync"
+
+BBCLASSEXTEND = "native"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 03/10] hardlink: add new recipe
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
  2016-02-24 14:52 ` [PATCH 01/10] rsync: add native variant Joshua Lock
  2016-02-24 14:52 ` [PATCH 02/10] swupd-server: initial recipe 2.53 Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 21:00   ` Burton, Ross
                     ` (2 more replies)
  2016-02-24 14:52 ` [PATCH 04/10] swupd-client: Add recipe Joshua Lock
                   ` (8 subsequent siblings)
  11 siblings, 3 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

---
 meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 meta/recipes-extended/hardlink/hardlink_0.3.0.bb

diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
new file mode 100644
index 0000000..2e06ac2
--- /dev/null
+++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
@@ -0,0 +1,19 @@
+SUMMARY = "hardlink is a tool which replaces multiple copies of a file with hardlinks."
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
+
+SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar.xz"
+SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
+SRC_URI[sha256sum] = "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
+
+DEPENDS = "libpcre attr"
+
+do_compile () {
+	oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
+}
+
+do_install () {
+	oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
+}
+
+BBCLASSEXTEND = "native nativesdk"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 04/10] swupd-client: Add recipe
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (2 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-25  8:07   ` Maciej Borzecki
  2016-02-24 14:52 ` [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image Joshua Lock
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

From: Mariano Lopez <mariano.lopez@linux.intel.com>

This commit adds the Clear Linux client updater.
This is experimental and bleeding edge, including the comments on the recipe.

Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 .../0001-Tolerate-quotes-in-os-release-files.patch | 59 ++++++++++++++++++++++
 ...hange-systemctl-path-to-OE-systemctl-path.patch | 31 ++++++++++++
 .../swupd-client/Fix-build-failure-on-Yocto.patch  | 36 +++++++++++++
 .../Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch    | 38 ++++++++++++++
 meta/recipes-devtools/swupd/swupd-client_2.87.bb   | 49 ++++++++++++++++++
 5 files changed, 213 insertions(+)
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
 create mode 100644 meta/recipes-devtools/swupd/swupd-client_2.87.bb

diff --git a/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch b/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
new file mode 100644
index 0000000..49c71ae
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
@@ -0,0 +1,59 @@
+From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:00 2001
+From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+Date: Thu, 11 Feb 2016 13:29:57 +0200
+Subject: [PATCH 1/2] Tolerate quotes in os-release files
+
+Some systems like Yocto or OpenSUSE prefer to wrap values in
+/etc/os-release file with quotes always and that still conforms
+to the format defined in systemd.
+
+This patch removes quotes from the values before trying to
+transform them into integer version id.
+
+Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
+
+Upstream-Status: Backport (v3.0.0+)
+
+---
+ src/version.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/src/version.c b/src/version.c
+index 0e09cd9..83d6ad4 100644
+--- a/src/version.c
++++ b/src/version.c
+@@ -88,6 +88,7 @@ int read_version_from_subvol_file(char *path_prefix)
+ 	FILE *file;
+ 	int v = -1;
+ 	char *buildstamp;
++	char *src, *dest;
+ 
+ 	string_or_die(&buildstamp, "%s/usr/lib/os-release", path_prefix);
+ 	file = fopen(buildstamp, "rm");
+@@ -106,7 +107,22 @@ int read_version_from_subvol_file(char *path_prefix)
+ 			break;
+ 		}
+ 
+-		if (strncmp(line,"VERSION_ID=", 11) == 0) {
++		if (strncmp(line, "VERSION_ID=", 11) == 0) {
++			src = &line[11];
++
++			/* Drop quotes and newline in value */
++			dest = src;
++			while (*src) {
++				if (*src == '\'' || *src == '"' || *src == '\n') {
++					++src;
++				} else {
++					*dest = *src;
++					++dest;
++					++src;
++				}
++			}
++			*dest = 0;
++
+ 			v = strtoull(&line[11], NULL, 10);
+ 			break;
+ 		}
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch b/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
new file mode 100644
index 0000000..5ca6373
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
@@ -0,0 +1,31 @@
+From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:00 2001
+From: Jaska Uimonen <jaska.uimonen@intel.com>
+Date: Thu, 14 Jan 2016 10:17:43 +0200
+Subject: [PATCH] change systemctl path to OE systemctl path
+
+Upstream-Status: Inappropriate
+
+---
+ src/scripts.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/scripts.c b/src/scripts.c
+index e426272..9bec0f5 100644
+--- a/src/scripts.c
++++ b/src/scripts.c
+@@ -84,10 +84,10 @@ static void update_triggers(void)
+ 	int ret;
+ 	LOG_INFO(NULL, "calling systemd trigger", class_scripts, "");
+ 
+-	ret = system("/usr/bin/systemctl daemon-reload");
++	ret = system("/bin/systemctl daemon-reload");
+ 	if (ret != 0)
+ 		LOG_ERROR(NULL, "systemd daemon reload failed", class_scripts, "%d", ret);
+-	ret = system("/usr/bin/systemctl restart update-triggers.target");
++	ret = system("/bin/systemctl restart update-triggers.target");
+ 	if (ret != 0)
+ 		LOG_ERROR(NULL, "systemd update triggers failed", class_scripts, "%d", ret);
+ }
+-- 
+2.5.0
+
diff --git a/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch b/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
new file mode 100644
index 0000000..73f1728
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
@@ -0,0 +1,36 @@
+From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:00 2001
+From: Amarnath Valluri <amarnath.valluri@intel.com>
+Date: Thu, 7 Jan 2016 16:19:34 +0200
+Subject: [PATCH] Fix build failure on Yocto
+
+On install phase certificate files are being installed twice as included in
+_DATA twice. We can use EXTRA_DIST than dist_.
+
+Upstream-Status: Inappropriate
+
+Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
+---
+ Makefile.am | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 1e65d3d..4d15c55 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -111,11 +111,11 @@ SWUPD_CERTS = certs/157753a5.0 \
+ 	certs/d6325660.0 \
+ 	certs/d6325660.1
+ swupdcerts_DATA = $(SWUPD_CERTS)
+-dist_swupdcerts_DATA = $(SWUPD_CERTS)
+ 
+ EXTRA_DIST += \
+ 	data/check-update.service \
+-	data/check-update.timer
++	data/check-update.timer \
++	$(SWUPD_CERTS)
+ 
+ DISTCHECK_CONFIGURE_FLAGS = \
+         --with-systemdsystemunitdir=$$dc_install_base/$(systemdunitdir)
+-- 
+2.1.4
+
diff --git a/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch b/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
new file mode 100644
index 0000000..e5b53ef
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
@@ -0,0 +1,38 @@
+From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:00 2001
+From: Amarnath Valluri <amarnath.valluri@intel.com>
+Date: Wed, 13 Jan 2016 15:46:19 +0200
+Subject: [PATCH] Right usage of AC_ARG_ENABLE on bzip2
+
+Upstream-Status: Pending[Not submitted]
+
+Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
+---
+ configure.ac | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index f94a17d..b11ef0a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -20,11 +20,13 @@ AC_CONFIG_HEADERS([config.h])
+ PKG_CHECK_MODULES([lzma], [liblzma])
+ PKG_CHECK_MODULES([zlib], [zlib])
+ AC_ARG_ENABLE(
+-	bzip2,
+-	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2 compression (uses bzip2 by default)]),
+-	AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression]) ,
+-	AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
+-	AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [], [AC_MSG_ERROR([the libbz2 library is missing])])
++	[bzip2],
++	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2 compression (uses bzip2 by default)])
++)
++AS_IF([test "x$enable_bzip2" = "xyes" ],
++  [AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
++	 AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [], [AC_MSG_ERROR([the libbz2 library is missing])])],
++  [AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression])]
+ )
+ 
+ AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
+-- 
+2.1.4
+
diff --git a/meta/recipes-devtools/swupd/swupd-client_2.87.bb b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
new file mode 100644
index 0000000..a5afdd6
--- /dev/null
+++ b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
@@ -0,0 +1,49 @@
+SUMMARY = "swupd sofware update from Clear Linux - client component"
+LICENSE = "GPL-2.0"
+LIC_FILES_CHKSUM = "file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
+                    file://bsdiff/LICENSE;md5=0dbe7a50f028269750631fcbded3846a"
+
+SRC_URI = "\
+    https://download.clearlinux.org/releases/5700/clear/source/SRPMS/${BPN}-${PV}-105.src.rpm;extract=${BP}.tar.gz \
+    file://Fix-build-failure-on-Yocto.patch \
+    file://Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch \
+    file://Change-systemctl-path-to-OE-systemctl-path.patch \
+    file://0001-Tolerate-quotes-in-os-release-files.patch \
+"
+
+SRC_URI[md5sum] = "5d272c62edb8a9c576005ac5e1182ea3"
+SRC_URI[sha256sum] = "45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1c66fb8"
+
+DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
+RDEPENDS_${PN} = "gzip bzip2 tar xz"
+# swupd requires at least an update-triggers target, should it be part of the
+# swupd-client package?
+RDEPENDS_${PN} = "swupd-units"
+# We check /etc/os-release for the current OS version number
+RRECOMMENDS_${PN} = "os-release"
+
+inherit pkgconfig autotools-brokensep systemd
+
+EXTRA_OECONF = "--with-systemdsystemunitdir=${systemd_system_unitdir}"
+
+#TODO: create and install /var/lib/swupd/{delta,staged/download}
+do_install_append () {
+    # swupd-client 2.87 doesn't (succesfully) create these and fails to update
+    # should they not exist. This is due to a bash-specific shell command
+    # called to create the directories 'mkdir -p /var/lib/{delta,staged,download}'
+    install -d ${D}/var/lib/swupd/delta
+    install -d ${D}/var/lib/swupd/download
+    install -d ${D}/var/lib/swupd/staged
+
+    # TODO: This should be a less os-specific directory and not hard-code datadir
+    install -d ${D}/usr/share/clear/bundles
+}
+
+FILES_${PN} += "\
+    /usr/share/clear \
+    ${systemd_system_unitdir}/multi-user.target.wants* \
+    /var/lib/swupd \
+"
+
+SYSTEMD_SERVICE_${PN} = "check-update.timer check-update.service"
+SYSTEMD_AUTO_ENABLE_${PN} = "disable"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (3 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 04/10] swupd-client: Add recipe Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-25  8:19   ` Maciej Borzecki
  2016-02-25 17:06   ` Patrick Ohly
  2016-02-24 14:52 ` [PATCH 06/10] swupd-image.bbclass: initial class to support swupd updater Joshua Lock
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

Our initial strategy to generate bundles for consumption by swupd
is to generate images which contain the base image (os-core) plus
the additional contents of the bundle, then prune out the core
contents. By generating images in this manner we hope to accomodate
packages which modify the rootfs outside of installing files, i.e.
with postinsts.

To that end this class, to be used via BBCLASSEXTEND, will generate
virtual image recipes that add extra packages to the extended
image.

Only extensions matching entries in a SWUPD_BUNDLES variable are
valid and the bundle contents should be listed in a varFlag
matching the bundle's name on the BUNDLE_CONTENTS variable.

An example of usage in an image recipe follows:

SWUPD_BUNDLES = "foo bar"
BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
BUNDLE_CONTENTS[bar] = "bar baz quux"

BBCLASSEXTEND = "swupdbundle:foo"

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/classes/swupdbundle.bbclass | 59 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 meta/classes/swupdbundle.bbclass

diff --git a/meta/classes/swupdbundle.bbclass b/meta/classes/swupdbundle.bbclass
new file mode 100644
index 0000000..897666d
--- /dev/null
+++ b/meta/classes/swupdbundle.bbclass
@@ -0,0 +1,59 @@
+# Our initial strategy to generate bundles for consumption by swupd is to
+# generate images which contain the base image (os-core) plus the additional
+# contents of the bundle, then prune out the core contents. By generating
+# images in this manner we hope to accomodate packages which modify the rootfs
+# outside of installing files, i.e.with postinsts.
+#
+# To that end this class, to be used via BBCLASSEXTEND, will generate virtual
+# image recipes that add extra packages to the extended image.
+#
+# Only extensions matching entries in a SWUPD_BUNDLES variable are valid and
+# the bundle contents should be listed in a varFlag matching the bundle's name
+# on the BUNDLE_CONTENTS variable. i.e in foo-image.bb:
+#
+# SWUPD_BUNDLES = "foo bar"
+# BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
+# BUNDLE_CONTENTS[bar] = "bar baz quux"
+# BBCLASSEXTEND = "swupdbundle:foo"
+
+python swupdbundle_virtclass_handler () {
+    pn = e.data.getVar("PN", True)
+    cls = e.data.getVar("BBEXTENDCURR", True)
+    bundle = e.data.getVar("BBEXTENDVARIANT", True)
+
+    if cls != 'swupdbundle':
+        return
+
+    if not bundle:
+        bb.fatal('swupdbundle must be used with a parameter i.e. BBCLASSEXTEND="swupdbundle:foo"')
+
+    # Rename the virtual recipe to create the desired image bundle variant.
+    e.data.setVar("PN_BASE", pn)
+    pn = pn + '-' + bundle
+    e.data.setVar("PN", pn)
+    e.data.setVar("BUNDLE_NAME", bundle)
+
+    bundles = (e.data.getVar('SWUPD_BUNDLES', True) or "").split()
+    if not bundles:
+        bb.fatal('SWUPD_BUNDLES is not defined, this variable should list bundles for the image.')
+
+    curr_install = (e.data.getVar('IMAGE_INSTALL', True) or "").split()
+
+    def get_bundle_contents(bndl):
+        contents = e.data.getVarFlag('BUNDLE_CONTENTS', bndl, True)
+        if contents:
+            return contents.split()
+        else:
+            bb.fatal('BUNDLE_CONTENTS[%s] is not set, this should list the packages to be included in the bundle.' % bndl)
+
+    if bundle == 'mega':
+        for bndl in bundles:
+            curr_install += get_bundle_contents(bndl)
+    else:
+        curr_install += get_bundle_contents(bundle)
+
+    e.data.setVar('IMAGE_INSTALL', ' '.join(curr_install))
+}
+
+addhandler swupdbundle_virtclass_handler
+swupdbundle_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 06/10] swupd-image.bbclass: initial class to support swupd updater
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (4 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 14:52 ` [PATCH 07/10] oe-swupd-helpers: provide swupd-client required helper scripts and units Joshua Lock
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

This class takes care of generating appropriate inputs for the swupd-server
to process, specifically the separate 'chroot'-like directory structures that
swupd-server expects to represent bundles.

It will then use swupd-server to process these 'chroot'-like directories into
update artefacts that are generated in a child of ${DEPLOYDIR}.

Co-authored by Joshua Lock & Mariano Lopez

Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/classes/swupd-image.bbclass | 372 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 372 insertions(+)
 create mode 100644 meta/classes/swupd-image.bbclass

diff --git a/meta/classes/swupd-image.bbclass b/meta/classes/swupd-image.bbclass
new file mode 100644
index 0000000..27d5f41
--- /dev/null
+++ b/meta/classes/swupd-image.bbclass
@@ -0,0 +1,372 @@
+# Class for swupd integration -- generates input artefacts for consumption by
+# swupd-server and calls swupd-server to process the inputs into update
+# artefacts for consumption by swupd-client.
+#
+# Limitations:
+# * Machine specific: generated swupd update artefacts are for a single MACHINE
+#   only as reflected in the DEPLOY_DIR directories.
+#
+# Usage:
+# * inherit this class in your core OS image. swupd-based OS's use bundles, the
+#   primary one of which, os-core, is defined as the contents of this image.
+# * Assign a list of names for bundles you wish to generate to the
+#   SWUPD_BUNDLES variable i.e. SWUPD_BUNDLES = "feature_one feature_two"
+# * Assign a list of packages for which their content should be included in
+#   a bundle to a varflag of BUNDLE_CONTENTS which matches the bundle name
+#   i.e. BUNDLE_CONTENTS[feature_one] = "package_one package_three package_six"
+# * Ensure the OS_VERSION variable is assigned an integer value and increased
+#   before each image build which should generate swupd update artefacts.
+#
+# An image that inherits this class will automatically have bundle 'chroots'
+# created which contain the filesystem contents of the specified bundles.
+# The mechanism to achieve this is that several virtual image recipes are
+# created, one for each defined bundle plus a 'mega' image recipe.
+# The 'mega' image contains the base image plus all of the bundles, whilst
+# bundle images contain only the base image plus the contents of a single
+# bundle.
+#
+# We build the mega image first, then the base image (the one which inherits
+# this class)and finally all of the bundle images  . Each non-mega image
+# has a manifest generated that lists all of the file contents of the image.
+#
+# Once the images and their manifests have been created each bundle image
+# manifest is compared to the base image manifest in order to generate a delta
+# list of files in the bundle image which don't exist in the base image.
+# Files in this list are then preserved in the bundle directory for processing
+# by swupd-server in order to generate update artefacts.
+#
+# Note: the reason for generating the mega image is to ensure that all files
+# which are staged from the shared sysroot, i.e. passwd and groups, are
+# fully populated.
+# This is not an ideal compromise and requires further thought.
+#
+# TODO: we're copying a lot of potentially duplicate files into
+# DEPLOY_DIR_SWUPD consider using hardlink to de-duplicate the files and save
+# some disk space.
+
+DEPLOY_DIR_SWUPDBASE = "${DEPLOY_DIR}/swupd/${MACHINE}"
+SWUPD_ROOTFS_MANIFEST = "${IMAGE_BASENAME}-files-in-image.txt"
+
+# User configurable variables to disable all swupd processing or deltapack
+# generation.
+SWUPD_GENERATE ??= "1"
+SWUPD_DELTAPACKS ??= "1"
+# Create delta packs for N versions back — default 2
+SWUPD_N_DELTAPACK ??= "2"
+# Amount the OS_VERSION should be increased by for each release, used by the
+# delta pack looping to generate delta packs going back up toSWUPD_N_DELTAPACK
+# releases
+SWUPD_VERSION_STEP ??= "10"
+
+# This version number *must* map to VERSION_ID in /etc/os-release and *must* be
+# a non-negative integer that fits in an int.
+OS_VERSION ??= "${DISTRO_VERSION}"
+
+IMAGE_INSTALL_append = " swupd-client os-release"
+# We need full-fat versions of these for swupd (at least as of 2.87)
+IMAGE_INSTALL_append = " gzip bzip2 tar xz"
+
+inherit distro_features_check
+REQUIRED_DISTRO_FEATURES = "systemd"
+
+python () {
+    if d.getVar('VIRTUAL-RUNTIME_init_manager', True) != 'systemd':
+        bb.error('swupd integration requires the systemd init manager')
+
+    ver = d.getVar('OS_VERSION', True) or 'invalid'
+    try:
+        int(ver)
+    except ValueError:
+        bb.fatal("Invalid value for OS_VERSION (%s), must be a non-negative integer value." % ver)
+
+    pn_base = d.getVar('PN_BASE', True)
+    if pn_base is not None:
+        # We want all virtual images from this recipe to deploy to the same
+        # directory
+        deploy_dir = d.getVar('DEPLOY_DIR_SWUPDBASE')
+        deploy_dir = os.path.join(deploy_dir, pn_base)
+        d.setVar('DEPLOY_DIR_SWUPD', deploy_dir)
+
+        # We need all virtual images from this recipe to share the same pseudo
+        # database so that permissions are correctly set in the copied bundle
+        # directories when swupd post-processing happens
+        pseudo_state = d.expand('${TMPDIR}/work-shared/${PN_BASE}/pseudo')
+        d.setVar('PSEUDO_LOCALSTATEDIR', pseudo_state)
+
+        # Non-base (bundle) images which aren't the mega image must depend on
+        # the base image having been built and its contents staged in
+        # DEPLOY_DIR_SWUPD so that those contents can be compared against in
+        # the do_prune_bundle task
+        if (d.getVar('BUNDLE_NAME') or "") == 'mega':
+            return
+        base_copy = (' %s:do_copy_bundle_contents' % pn_base)
+        d.appendVarFlag('do_prune_bundle', 'depends', base_copy)
+        return
+
+    # We use a shared Pseudo database in order to ensure that all tasks have
+    # full awareness of the files created for the base image recipe and each
+    # of its virtual recipes.
+    # However, we must be careful with the pseudo database and managing
+    # database lifecycles in order to avoid confusion should inode numbers be
+    # reused when files are deleted outside of pseudo's awareness.
+    #
+    # TODO: Figure out database lifecycles. When can we be sure that deleting
+    # the database is appropriate? We need it to live for the generation of
+    # an image and all of its virtual images.
+    pseudo_state = d.expand('${TMPDIR}/work-shared/${IMAGE_BASENAME}/pseudo')
+    d.setVar('PSEUDO_LOCALSTATEDIR', pseudo_state)
+
+    deploy_dir = d.expand('${DEPLOY_DIR_SWUPDBASE}/${IMAGE_BASENAME}')
+    d.setVar('DEPLOY_DIR_SWUPD', deploy_dir)
+    varflags = '%s/image %s/empty %s/www %s' % (deploy_dir, deploy_dir, deploy_dir, deploy_dir)
+    d.setVarFlag('do_swupd_update', 'dirs', varflags)
+
+    # For the base image only, set the BUNDLE_NAME to os-core and generate the
+    # virtual images for each bundle and the mega image
+    d.setVar('BUNDLE_NAME', 'os-core')
+
+    bundles = (d.getVar('SWUPD_BUNDLES', True) or "").split()
+    extended = (d.getVar('BBCLASSEXTEND', True) or "").split()
+
+    # Generate virtual images for each of the bundles, the base image + the
+    # bundle contents. Add each virtual image's do_prune_bundle task as a
+    # dependency of the base image as we can't generate the update until all
+    # dependent images are done with their build, 'chroot' populate and pruning
+    pn = d.getVar('PN', True)
+    for bndl in bundles:
+        extended.append('swupdbundle:%s' % bndl)
+        dep = ' %s-%s:do_prune_bundle' % (pn, bndl)
+        d.appendVarFlag ('do_swupd_update', 'depends', dep)
+    extended.append('swupdbundle:mega')
+    d.setVar('BBCLASSEXTEND', ' '.join(extended))
+
+    # The base image should depend on the mega-image having been populated
+    # to ensure that we're staging the same shared files from the sysroot as
+    # the bundle images.
+    mega_name = (' %s-mega:do_rootfs' % d.getVar('PN', True))
+    d.appendVarFlag('do_rootfs', 'depends', mega_name)
+}
+
+fakeroot do_rootfs_append () {
+    bndl = d.getVar('BUNDLE_NAME', True)
+    if (bndl == 'mega'):
+        return
+
+    # swupd-client expects a bundle subscription to exist for each
+    # installed bundle. This is simply an empty file named for the
+    # bundle in /usr/share/clear/bundles
+    bundledir = d.expand('${IMAGE_ROOTFS}/usr/share/clear/bundles')
+    bb.utils.mkdirhier(bundledir)
+    open(os.path.join(bundledir, bndl), 'w+b').close()
+}
+
+# Stage the contents of the generated image rootfs, and a manifest listing all
+# of the files in the image, for further processing.
+fakeroot do_copy_bundle_contents () {
+    bbdebug 2 "Considering copying bundle contents for ${PN}"
+    if [ "${BUNDLE_NAME}" != "mega" ] ; then
+        bbdebug 2 "Copying ${BUNDLE_NAME} contents"
+        outfile="${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/${SWUPD_ROOTFS_MANIFEST}"
+        bundledir="${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/${BUNDLE_NAME}/"
+        rootfs="${IMAGE_ROOTFS}"
+        mkdir -p $bundledir
+        # Generate a manifest of the bundle contents for pruning
+        cd $rootfs && find . ! -path . > $outfile
+        # Copy the rootfs tree preserving the files and all of their attributes
+        cp -a $rootfs/* $bundledir
+    fi
+}
+# Needs to run after do_image_complete so that IMAGE_POSTPROCESS commands have run
+addtask copy_bundle_contents after do_image_complete before do_prune_bundle
+
+# Generate a list of files which exist in the bundle image, but not the base
+# image.
+def delta_contents(difflist):
+    # '- ' - line unique to lhs
+    # '+ ' - line unique to rhs
+    # '  ' - line common
+    # '? ' - line not present in either
+    #
+    # difflist should be a list containing the output of difflib.Differ.compare
+    #       where the lhs (left-hand-side) was the base image and the rhs
+    #       (right-hand-side) was base image + extras (the bundle image).
+    #
+    # returns a list containing the items which are unique in the rhs
+    cont = []
+    for ln in difflist:
+        if ln[0] == '+':
+            cont.append(ln[3:])
+    return cont
+
+# Compare the bundle image manifest to the base image manifest and return
+# a list of files unique to the bundle image.
+def unique_contents(base_manifest_fn, image_manifest_fn):
+    import difflib
+    differ = difflib.Differ()
+
+    base_manifest_list = []
+    with open(base_manifest_fn) as base:
+        base_manifest_list = base.read().splitlines()
+
+    image_manifest_list = []
+    with open(image_manifest_fn) as image:
+        image_manifest_list = image.read().splitlines()
+
+    delta = list(differ.compare(base_manifest_list, image_manifest_list))
+
+    return delta_contents(delta)
+
+fakeroot python do_prune_bundle () {
+    bundle = d.getVar('BUNDLE_NAME', True) or ''
+    if not bundle:
+        bb.warn('Trying to prune bundle of a non-bundle image: ' % d.getVar('PN', True))
+        return
+
+    if bundle == 'mega' or bundle == 'os-core':
+        bb.debug(2, 'Skipping bundle pruning for %s image' % bundle)
+        return
+
+    # Get a list of files in the bundle which aren't in the base image
+    pn_base = d.getVar("PN_BASE", True)
+    image_manifest = d.expand("${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/${SWUPD_ROOTFS_MANIFEST}")
+    base_manifest = image_manifest.replace('-%s' % bundle, '')
+    bb.debug(1, "Comparing manifest %s to %s" % (base_manifest, image_manifest))
+    bundle_file_contents = unique_contents(base_manifest, image_manifest)
+    bb.debug(1, '%s has %s unique contents' % (d.getVar('PN', True), len(bundle_file_contents)))
+
+    # now we have a list of bundle files we can go ahead and delete files in
+    # the bundle directory which aren't in this list.
+    bundledir = d.expand('${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/${BUNDLE_NAME}/')
+    bb.debug(1, "Creating and pruning %s bundle dir (%s)" % (bundle, bundledir))
+    for root, dirs, files in os.walk(bundledir):
+        relroot = root.replace(bundledir, '/')
+        for f in files:
+            fpath = os.path.join(relroot, f)
+            if fpath not in bundle_file_contents:
+                bb.debug(3, 'Pruning %s from the bundle\n\t%s' % (fpath, os.path.join(root, f)))
+                os.remove(os.path.join(root, f))
+
+    # Now need to clean up empty directories
+    for dir, _, _ in os.walk(bundledir, topdown=False):
+        try:
+            os.rmdir(dir)
+        except OSError as err:
+            bb.debug(2, 'Not removing %s, reason: %s' % (dir, err.strerror))
+    bb.debug(1, "Done pruning %s bundle dir (%s)" % (bundle, bundledir))
+}
+addtask prune_bundle after do_copy_bundle_contents before do_swupd_update
+
+fakeroot do_swupd_update() {
+    if [ ! -z "${PN_BASE}" ]; then
+        bbwarn 'We only generate swupd updates for the base image, skipping ${PN}'
+        exit
+    fi
+
+    if [ ! "${SWUPD_GENERATE}" -eq 1 ]; then
+        bbnote 'Update generation disabled, skipping.'
+        exit
+    fi
+
+    export SWUPD_CERTS_DIR="${STAGING_ETCDIR_NATIVE}/swupd-certs"
+    export LEAF_KEY="leaf.key.pem"
+    export LEAF_CERT="leaf.cert.pem"
+    export CA_CHAIN_CERT="ca-chain.cert.pem"
+    export PASSPHRASE="${SWUPD_CERTS_DIR}/passphrase"
+
+    export XZ_DEFAULTS="--threads 0"
+
+    bbdebug 1 "New OS_VERSION is ${OS_VERSION}"
+    # If the swupd directory already exists don't trample over it, but let
+    # the user know we're not doing any update generation.
+    if [ -e ${DEPLOY_DIR_SWUPD}/www/${OS_VERSION} ]; then
+        bbwarn 'swupd image directory exists for OS_VERSION=${OS_VERSION}, not generating updates.'
+        bbwarn 'Ensure OS_VERSION is incremented if you want to generate updates.'
+        exit
+    fi
+
+    mkdir -p ${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/os-core
+    cp -ar ${IMAGE_ROOTFS}/* ${DEPLOY_DIR_SWUPD}/image/${OS_VERSION}/os-core/
+
+    # Generate swupd-server configuration
+    bbdebug 1 "Writing ${DEPLOY_DIR_SWUPD}/server.ini"
+    if [ -e "${DEPLOY_DIR_SWUPD}/server.ini" ]; then
+       rm ${DEPLOY_DIR_SWUPD}/server.ini
+    fi
+    cat << END > ${DEPLOY_DIR_SWUPD}/server.ini
+[Server]
+imagebase=${DEPLOY_DIR_SWUPD}/image/
+outputdir=${DEPLOY_DIR_SWUPD}/www/
+emptydir=${DEPLOY_DIR_SWUPD}/empty/
+END
+
+    if [ -e ${DEPLOY_DIR_SWUPD}/image/latest.version ]; then
+        PREVREL=`cat ${DEPLOY_DIR_SWUPD}/image/latest.version`
+    else
+        bbdebug 1 "Stubbing out empty latest.version file"
+        touch ${DEPLOY_DIR_SWUPD}/image/latest.version
+        PREVREL="0"
+    fi
+
+    GROUPS_INI="${DEPLOY_DIR_SWUPD}/groups.ini"
+    bbdebug 1 "Writing ${GROUPS_INI}"
+    if [ -e "${DEPLOY_DIR_SWUPD}/groups.ini" ]; then
+       rm ${DEPLOY_DIR_SWUPD}/groups.ini
+    fi
+    for bndl in ${SWUPD_BUNDLES}; do
+        echo "[$bndl]" >> ${GROUPS_INI}
+        echo "group=$bndl" >> ${GROUPS_INI}
+        echo "" >> ${GROUPS_INI}
+    done
+
+    bbdebug 1 "Generating update from PREVREL to ${OS_VERSION}"
+    ${STAGING_BINDIR_NATIVE}/swupd_create_update -S ${DEPLOY_DIR_SWUPD} --osversion ${OS_VERSION}
+
+    bbdebug 1 "Generating fullfiles for ${OS_VERSION}"
+    ${STAGING_BINDIR_NATIVE}/swupd_make_fullfiles -S ${DEPLOY_DIR_SWUPD} ${OS_VERSION}
+
+    bbdebug 1 "Generating zero packs, this can take some time."
+    ${STAGING_BINDIR_NATIVE}/swupd_make_pack -S ${DEPLOY_DIR_SWUPD} 0 ${OS_VERSION} os-core
+    for bndl in ${SWUPD_BUNDLES}; do
+        bbdebug 2 "Generating zero pack for $bndl"
+        ${STAGING_BINDIR_NATIVE}/swupd_make_pack -S ${DEPLOY_DIR_SWUPD} 0 ${OS_VERSION} $bndl
+    done
+
+    # Generate delta-packs going back SWUPD_N_DELTAPACK versions
+    if [ ${SWUPD_DELTAPACKS} -eq 1 -a ${SWUPD_N_DELTAPACK} -gt 0 -a $PREVREL -gt 0 ]; then
+        bbdebug 1 "Generating delta pack with previous release $PREVREL"
+        bundles="os-core ${SWUPD_BUNDLES}"
+        for bndl in $bundles; do
+            bndlcnt=0
+            prevver=$PREVREL
+            while [ $bndlcnt -lt ${SWUPD_N_DELTAPACK} -a $prevver -gt 0 ]; do
+                if [ -e ${DEPLOY_DIR_SWUPD}/image/$prevver/$bndl ]; then
+                    bbdebug 2 "Generating delta pack from $prevver to ${OS_VERSION} for $bndl"
+                    ${STAGING_BINDIR_NATIVE}/swupd_make_pack -S ${DEPLOY_DIR_SWUPD} $prevver ${OS_VERSION} $bndl
+                    bndlcnt=`expr $bndlcnt + 1`
+                fi
+                # Both let and expr return 1 if the expression evaluates to 0,
+                # bitbake catches the non-zero exit code from a shell command
+                # end exits with an error - special case to work around this.
+                if [ $prevver -eq ${SWUPD_VERSION_STEP} ]; then
+                    prevver=0
+                else
+                    prevver=`expr $prevver - ${SWUPD_VERSION_STEP}`
+                fi
+            done
+        done
+    fi
+
+    # Write version to www/version/format3/latest and image/latest.version
+    bbdebug 2 "Writing latest file"
+    mkdir -p ${DEPLOY_DIR_SWUPD}/www/version/format3
+    echo ${OS_VERSION} > ${DEPLOY_DIR_SWUPD}/www/version/format3/latest
+    echo ${OS_VERSION} > ${DEPLOY_DIR_SWUPD}/image/latest.version
+}
+
+SWUPDDEPENDS = "\
+    virtual/fakeroot-native:do_populate_sysroot \
+    rsync-native:do_populate_sysroot \
+    swupd-server-native:do_populate_sysroot \
+"
+addtask swupd_update after do_image_complete after do_copy_bundle_contents after do_prune_bundle before do_build
+do_swupd_update[depends] = "${SWUPDDEPENDS}"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 07/10] oe-swupd-helpers: provide swupd-client required helper scripts and units
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (5 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 06/10] swupd-image.bbclass: initial class to support swupd updater Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 14:52 ` [PATCH 08/10] swupd-client: RDEPENDS on oe-swupd-helpers Joshua Lock
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

swup-client tries to call out to certain helper scripts during an update:
* before the update clr_pre_update.sh is called
* after the update systemdboot_updater.sh and kernel_updater.sh are called
* the systemd update-triggers.target is restarted once the update is complete

Clear Linux, the incubation OS for swupd, provides Clear specific
implementations of the systemd units in clr-systemd-units and the helper
scripts in clr-specialized-helpers.

This patch introduces a recipe which provides minimal, stub,
implementations of the required helper scripts and units. These will
need overriding by a product and will in future be improved to be generically
useful for OE-Core images.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/recipes-devtools/swupd/oe-swupd-helpers.bb    | 39 ++++++++++++++++++++++
 .../swupd/oe-swupd-helpers/catalog-trigger.service |  8 +++++
 .../swupd/oe-swupd-helpers/clr_pre_update.sh       | 16 +++++++++
 .../swupd/oe-swupd-helpers/kernel_updater.sh       |  9 +++++
 .../oe-swupd-helpers/ldconfig-trigger.service      |  8 +++++
 .../swupd/oe-swupd-helpers/systemdboot_updater.sh  | 10 ++++++
 .../oe-swupd-helpers/tmpfiles-trigger.service      |  8 +++++
 .../swupd/oe-swupd-helpers/update-triggers.target  |  5 +++
 8 files changed, 103 insertions(+)
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers.bb
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service
 create mode 100755 meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service
 create mode 100644 meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target

diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers.bb b/meta/recipes-devtools/swupd/oe-swupd-helpers.bb
new file mode 100644
index 0000000..4690f21
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers.bb
@@ -0,0 +1,39 @@
+SUMMARY = "OE swupd helper files"
+DESCRIPTION = "swupd-client assumes the presence of various helpers, this is a minimal OE \
+implementation of the required scripts and systemd units. \
+Scripts are modified versions of those in clr-specialized-updaters and units are modified \
+versions of those in clr-systemd-config"
+LICENSE = "GPL-2.0"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6"
+
+SRC_URI = "file://update-triggers.target \
+           file://catalog-trigger.service \
+           file://ldconfig-trigger.service \
+           file://tmpfiles-trigger.service \
+           file://clr_pre_update.sh \
+           file://kernel_updater.sh \
+           file://systemdboot_updater.sh \
+           "
+
+inherit allarch distro_features_check systemd
+
+REQUIRED_DISTRO_FEATURES = "systemd"
+
+do_install () {
+    install -d ${D}${systemd_system_unitdir}
+    for svc in `find ${WORKDIR} -maxdepth 1 -name *.target -o -name *.service`; do
+        install -m 0644 $svc ${D}${systemd_system_unitdir}/
+        sed -i -e s#/bin#${base_bindir}# ${D}${systemd_system_unitdir}/`basename $svc`
+        sed -i -e s#/sbin#${base_sbindir}# ${D}${systemd_system_unitdir}/`basename $svc`
+        sed -i -e s#/lib#${base_libdir}# ${D}${systemd_system_unitdir}/`basename $svc`
+    done
+
+    # NOTE: swupd-client hard-codes /usr/bin
+    install -d ${D}/usr/bin
+    for helper in `find ${WORKDIR} -maxdepth 1 -name *.sh`; do
+        install $helper ${D}/usr/bin/
+    done
+}
+
+RDEPENDS_${PN} += "bash"
+FILES_${PN} += "${systemd_system_unitdir}"
\ No newline at end of file
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service b/meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service
new file mode 100644
index 0000000..8266174
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Rebuild journal catalog
+Documentation=man:journalctl(1)
+BindsTo=update-triggers.target
+
+[Service]
+Type=oneshot
+ExecStart=/bin/journalctl --update-catalog
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh b/meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh
new file mode 100755
index 0000000..6302090
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -u
+
+#######################################
+# Clear Linux General Purpose Pre-update helper script
+#  This is a script meant to update state information external to what swupd updates.
+#  The specific content of this script will vary over time, according to the state
+#  change needed
+#######################################
+
+UPDATE_NAME="Pre-update"
+VERSION="3.60"
+
+### Enter your script here
+echo "Running script '$UPDATE_NAME'"
+exit 0
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh b/meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh
new file mode 100755
index 0000000..b0d5335
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+#######################################
+# This script will be called after an updated kernel has been installed
+#######################################
+
+### Enter your script here
+echo "Running script 'kernel_updater.sh'"
+exit 0
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service b/meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service
new file mode 100644
index 0000000..224ac7a
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Rebuild Dynamic Linker Cache
+Documentation=man:ldconfig(8)
+BindsTo=update-triggers.target
+
+[Service]
+Type=oneshot
+ExecStart=/sbin/ldconfig -X
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh b/meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh
new file mode 100755
index 0000000..470cd6e
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+#######################################
+# systemd bootloader installer
+# This script will be called after an updated bootloader has been installed
+#######################################
+
+### Enter your script here
+echo "Running script 'systemdboot_updater.sh'"
+exit 0
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service b/meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service
new file mode 100644
index 0000000..71009fe
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Create tmpfiles
+Documentation=man:systemd-tmpfiles(8)
+BindsTo=update-triggers.target
+
+[Service]
+Type=oneshot
+ExecStart=/bin/systemd-tmpfiles --create
diff --git a/meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target b/meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target
new file mode 100644
index 0000000..d104b00
--- /dev/null
+++ b/meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target
@@ -0,0 +1,5 @@
+[Unit]
+Description=Post system update triggers
+Wants=ldconfig-trigger.service
+Wants=catalog-trigger.service
+Wants=tmpfiles-trigger.service
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 08/10] swupd-client: RDEPENDS on oe-swupd-helpers
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (6 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 07/10] oe-swupd-helpers: provide swupd-client required helper scripts and units Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 14:52 ` [PATCH 09/10] swupd-client: enable native builds Joshua Lock
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

The oe-swupd-helpers package provides scripts and units that swupd-client
calls before, during and after the update process.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/recipes-devtools/swupd/swupd-client_2.87.bb | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/meta/recipes-devtools/swupd/swupd-client_2.87.bb b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
index a5afdd6..73bfeb1 100644
--- a/meta/recipes-devtools/swupd/swupd-client_2.87.bb
+++ b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
@@ -16,9 +16,7 @@ SRC_URI[sha256sum] = "45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1
 
 DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
 RDEPENDS_${PN} = "gzip bzip2 tar xz"
-# swupd requires at least an update-triggers target, should it be part of the
-# swupd-client package?
-RDEPENDS_${PN} = "swupd-units"
+RDEPENDS_${PN}_class-target = "oe-swupd-helpers"
 # We check /etc/os-release for the current OS version number
 RRECOMMENDS_${PN} = "os-release"
 
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 09/10] swupd-client: enable native builds
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (7 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 08/10] swupd-client: RDEPENDS on oe-swupd-helpers Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 14:52 ` [PATCH 10/10] os-release: sanitise VERSION_ID field Joshua Lock
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

This is useful for debugging swupd generated artefacts on the build
host i.e. `swupd hashdump`

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/recipes-devtools/swupd/swupd-client_2.87.bb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/meta/recipes-devtools/swupd/swupd-client_2.87.bb b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
index 73bfeb1..8226624 100644
--- a/meta/recipes-devtools/swupd/swupd-client_2.87.bb
+++ b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
@@ -18,7 +18,7 @@ DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
 RDEPENDS_${PN} = "gzip bzip2 tar xz"
 RDEPENDS_${PN}_class-target = "oe-swupd-helpers"
 # We check /etc/os-release for the current OS version number
-RRECOMMENDS_${PN} = "os-release"
+RRECOMMENDS_${PN}_class-target = "os-release"
 
 inherit pkgconfig autotools-brokensep systemd
 
@@ -45,3 +45,5 @@ FILES_${PN} += "\
 
 SYSTEMD_SERVICE_${PN} = "check-update.timer check-update.service"
 SYSTEMD_AUTO_ENABLE_${PN} = "disable"
+
+BBCLASSEXTEND = "native"
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 10/10] os-release: sanitise VERSION_ID field
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (8 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 09/10] swupd-client: enable native builds Joshua Lock
@ 2016-02-24 14:52 ` Joshua Lock
  2016-02-24 15:37 ` [PATCH 00/10] Integrate swupd software updater Patrick Ohly
  2016-02-24 16:06 ` Trevor Woerner
  11 siblings, 0 replies; 35+ messages in thread
From: Joshua Lock @ 2016-02-24 14:52 UTC (permalink / raw)
  To: openembedded-core

Per os-release(5) the VERSION_ID field should be:

  a lower-case string (mostly numeric, no spaces or other characters
  outside of 0-9, a-z, ".", "_" and "-")

Do some string manipulation to try and ensure the VERSION_ID field
we write is valid.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
---
 meta/recipes-core/os-release/os-release.bb | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/meta/recipes-core/os-release/os-release.bb b/meta/recipes-core/os-release/os-release.bb
index df19ca2..03abc50 100644
--- a/meta/recipes-core/os-release/os-release.bb
+++ b/meta/recipes-core/os-release/os-release.bb
@@ -23,11 +23,20 @@ PRETTY_NAME = "${DISTRO_NAME} ${VERSION}"
 BUILD_ID ?= "${DATETIME}"
 BUILD_ID[vardepsexclude] = "DATETIME"
 
+def sanitise_version(ver):
+    # VERSION_ID should be (from os-release(5)):
+    #    lower-case string (mostly numeric, no spaces or other characters
+    #    outside of 0-9, a-z, ".", "_" and "-")
+    ret = ver.replace('+', '-').replace(' ','_')
+    return ret.lower()
+
 python do_compile () {
     import shutil
     with open(d.expand('${B}/os-release'), 'w') as f:
         for field in d.getVar('OS_RELEASE_FIELDS', True).split():
             value = d.getVar(field, True)
+            if value and field == 'VERSION_ID':
+                value = sanitise_version(value)
             if value:
                 f.write('{0}="{1}"\n'.format(field, value))
     if d.getVar('RPM_SIGN_PACKAGES', True) == '1':
-- 
2.5.0



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (9 preceding siblings ...)
  2016-02-24 14:52 ` [PATCH 10/10] os-release: sanitise VERSION_ID field Joshua Lock
@ 2016-02-24 15:37 ` Patrick Ohly
  2016-02-24 16:14   ` Joshua G Lock
       [not found]   ` <1456330147.5333.14.camel@intel.com>
  2016-02-24 16:06 ` Trevor Woerner
  11 siblings, 2 replies; 35+ messages in thread
From: Patrick Ohly @ 2016-02-24 15:37 UTC (permalink / raw)
  To: Joshua Lock; +Cc: openembedded-core

Hello!

I haven't had a chance to play with the actual code yet and I don't know
yet when I'll be able to. Let me ask for some clarifications about the
approach first anyway.

On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> Approach:
> An image that inherits the swupd-image bbclass will automatically have bundle
> 'chroots' created which contain the filesystem contents of the specified
> bundles, with the contents of the inheriting image forming the default os-core
> bundle.
> 
> The mechanism to achieve this is that several virtual image recipes are created
> using the swupdbundle class, one for each defined bundle plus a 'mega' image
> recipe. The 'mega' image contains the base image plus the contents of all of the
> bundles, whilst bundle images contain only the base image plus the contents of a
> single bundle.

Just to be sure, the actual "content" (a term that is a bit too
overloaded to be used precisely in all cases) of a file and its meta
attributes will come from the mega image, and the virtual image recipes,
including the base image, are merely used to generate file lists?

What is the content of the actual image that gets created? It has to
match the content (= file content and meta information) of the mega
image and not of the base image, otherwise there can be inconsistencies
between the actual running image and the core os bundle. I suppose swupd
will be able to fix that, but I'm not sure.

It sounds like this bundle creation is completely separated from the
regular image creation; if so, then I suspect that this may have to
change.

> We took the approach of building images, rather than populating the chroot-like
> bundle directories with a package manager, because various layers and recipes
> make changes to the rootfs contents outside of the package manager, particularly
> with IMAGE_POSTPROCESS_COMMAND, etc.

Makes sense to me.

Have you considered generating the file lists more efficiently? I can
think of some alternatives, but all have downsides.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.





^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
                   ` (10 preceding siblings ...)
  2016-02-24 15:37 ` [PATCH 00/10] Integrate swupd software updater Patrick Ohly
@ 2016-02-24 16:06 ` Trevor Woerner
  2016-02-24 16:35   ` Philip Balister
  11 siblings, 1 reply; 35+ messages in thread
From: Trevor Woerner @ 2016-02-24 16:06 UTC (permalink / raw)
  To: Joshua Lock, openembedded-core

Ideally the work done here and the work done on meta-swupdate[1] would 
be somehow merged so people creating images/distros would only have to 
learn and integrate one software update solution, instead of having to 
evaluate and choose between the two (or more?).


[1] https://github.com/sbabic/meta-swupdate


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 15:37 ` [PATCH 00/10] Integrate swupd software updater Patrick Ohly
@ 2016-02-24 16:14   ` Joshua G Lock
       [not found]   ` <1456330147.5333.14.camel@intel.com>
  1 sibling, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-24 16:14 UTC (permalink / raw)
  To: Patrick Ohly; +Cc: openembedded-core

On Wed, 2016-02-24 at 16:37 +0100, Patrick Ohly wrote:
> Hello!
> 
> I haven't had a chance to play with the actual code yet and I don't
> know
> yet when I'll be able to. Let me ask for some clarifications about
> the
> approach first anyway.
> 
> On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> > 
> > Approach:
> > An image that inherits the swupd-image bbclass will automatically
> > have bundle
> > 'chroots' created which contain the filesystem contents of the
> > specified
> > bundles, with the contents of the inheriting image forming the
> > default os-core
> > bundle.
> > 
> > The mechanism to achieve this is that several virtual image recipes
> > are created
> > using the swupdbundle class, one for each defined bundle plus a
> > 'mega' image
> > recipe. The 'mega' image contains the base image plus the contents
> > of all of the
> > bundles, whilst bundle images contain only the base image plus the
> > contents of a
> > single bundle.
> Just to be sure, the actual "content" (a term that is a bit too
> overloaded to be used precisely in all cases) of a file and its meta
> attributes will come from the mega image, and the virtual image
> recipes,
> including the base image, are merely used to generate file lists?

That's not currently true, no — the file contents for a bundle come
from the bundle image and the file contents for os-core come from the
base image. It shouldn't be too difficult a change to make, I'll take a
look now.

> What is the content of the actual image that gets created? It has to
> match the content (= file content and meta information) of the mega
> image and not of the base image, otherwise there can be
> inconsistencies
> between the actual running image and the core os bundle. I suppose
> swupd
> will be able to fix that, but I'm not sure.
> 
> It sounds like this bundle creation is completely separated from the
> regular image creation; if so, then I suspect that this may have to
> change.

Right, currently bundle creation happens after image creation and as
above bundles are populated from the rootfs of the bundle images.

You're right, of course, we'll need to construct the running image from
the bundle contents for more complex images.

> > 
> > We took the approach of building images, rather than populating the
> > chroot-like
> > bundle directories with a package manager, because various layers
> > and recipes
> > make changes to the rootfs contents outside of the package manager,
> > particularly
> > with IMAGE_POSTPROCESS_COMMAND, etc.
> Makes sense to me.
> 
> Have you considered generating the file lists more efficiently? I can
> think of some alternatives, but all have downsides.
> 

I did consider a couple of other approaches but with a goal of
submitting this for M3 this approach felt like the surest route within
the time available. I'd certainly like to find a more efficient method
and if you have any suggestions I'd be happy to hear them.

Regards,

Joshua


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 16:06 ` Trevor Woerner
@ 2016-02-24 16:35   ` Philip Balister
  2016-02-24 18:36     ` Maciej Borzecki
  2016-02-24 19:51     ` Paul Eggleton
  0 siblings, 2 replies; 35+ messages in thread
From: Philip Balister @ 2016-02-24 16:35 UTC (permalink / raw)
  To: Trevor Woerner, Joshua Lock, openembedded-core

On 02/24/2016 11:06 AM, Trevor Woerner wrote:
> Ideally the work done here and the work done on meta-swupdate[1] would
> be somehow merged so people creating images/distros would only have to
> learn and integrate one software update solution, instead of having to
> evaluate and choose between the two (or more?).
> 
> 
> [1] https://github.com/sbabic/meta-swupdate

Amen. I had the same thoughts reading the patch set intro.

Maybe the swupd should go in a seperate layer so we can see which
project works best for oe users before moving something directly into
oe-core?

Philip


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 16:35   ` Philip Balister
@ 2016-02-24 18:36     ` Maciej Borzecki
  2016-02-24 19:51     ` Paul Eggleton
  1 sibling, 0 replies; 35+ messages in thread
From: Maciej Borzecki @ 2016-02-24 18:36 UTC (permalink / raw)
  To: Trevor Woerner, Philip Balister, openembedded-core, Joshua Lock

> Dnia 24 luty 2016 o 17:35 Philip Balister <philip@balister.org> napisał(a):
>
>
> On 02/24/2016 11:06 AM, Trevor Woerner wrote:
> > Ideally the work done here and the work done on meta-swupdate[1] would
> > be somehow merged so people creating images/distros would only have to
> > learn and integrate one software update solution, instead of having to
> > evaluate and choose between the two (or more?).
> >
> >
> > [1] https://github.com/sbabic/meta-swupdate
>
> Amen. I had the same thoughts reading the patch set intro.
>
> Maybe the swupd should go in a seperate layer so we can see which
> project works best for oe users before moving something directly into
> oe-core?
>

Frankly, swupdate is more embedded oriented. If I was to choose which
one fits better into OE, I would say that swupdate does. However, in the
end, both projects have their uses.

`swupd` is a new thing and I'm not aware of it being used in any other
project than ClearLinux.  From what I've seen[1] there are some nice
concepts that might prove useful in embedded (maybe even automotive
applications?), but I have not tried it personally.

`swupdate` on the other hand is very much embedded oriented. It's aware
of u-boot, ubifs volumes, MTD, and is capable of updating firmware. I've
used it, even contributed some code, and so far I've had a rather
positive experience using it. There are some quirks in meta-swupdate
that might need fixing, for ex. the actual process of building of update
images is a bit convoluted, lack of systemd awareness, and certain
assumptions about the update method that I don't agree with. I have some
patches queued up, but they're more like shameful hacks than something
worth upstreaming at this point.

[1]. https://lists.clearlinux.org/pipermail/dev/2016-January/000159.html

--
Maciej Borzęcki
Senior Software Engineer at Open-RnD Sp. z o.o.
www.open-rnd.pl, Facebook, Twitter


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
       [not found]   ` <1456330147.5333.14.camel@intel.com>
@ 2016-02-24 18:49     ` Patrick Ohly
  2016-03-01 16:18       ` Joshua G Lock
  0 siblings, 1 reply; 35+ messages in thread
From: Patrick Ohly @ 2016-02-24 18:49 UTC (permalink / raw)
  To: Lock, Joshua G; +Cc: openembedded-core@lists.openembedded.org

On Wed, 2016-02-24 at 16:09 +0000, Lock, Joshua G wrote:
> On Wed, 2016-02-24 at 16:37 +0100, Patrick Ohly wrote:
> > Hello!
> > 
> > I haven't had a chance to play with the actual code yet and I don't
> > know
> > yet when I'll be able to. Let me ask for some clarifications about
> > the
> > approach first anyway.
> > 
> > On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> > > 
> > > Approach:
> > > An image that inherits the swupd-image bbclass will automatically
> > > have bundle
> > > 'chroots' created which contain the filesystem contents of the
> > > specified
> > > bundles, with the contents of the inheriting image forming the
> > > default os-core
> > > bundle.
> > > 
> > > The mechanism to achieve this is that several virtual image recipes
> > > are created
> > > using the swupdbundle class, one for each defined bundle plus a
> > > 'mega' image
> > > recipe. The 'mega' image contains the base image plus the contents
> > > of all of the
> > > bundles, whilst bundle images contain only the base image plus the
> > > contents of a
> > > single bundle.
> > Just to be sure, the actual "content" (a term that is a bit too
> > overloaded to be used precisely in all cases) of a file and its meta
> > attributes will come from the mega image, and the virtual image
> > recipes,
> > including the base image, are merely used to generate file lists?
> 
> That's not currently true, no — the file contents for a bundle come
> from the bundle image and the file contents for os-core come from the
> base image. It shouldn't be too difficult a change to make, I'll take a
> look now.

The prime example that needs to be handled correctly is where installing
additional packages for one of the extra bundles adds a system user
to /etc/passwd (*). The content of /etc/passwd must come from the mega
rootfs.

(*) Except that swupd assumes that the distro is stateless and thus
automatically excludes /etc from bundles. The example is still valid
because preparing bundles does not need to care about that.

> > What is the content of the actual image that gets created? It has to
> > match the content (= file content and meta information) of the mega
> > image and not of the base image, otherwise there can be
> > inconsistencies
> > between the actual running image and the core os bundle. I suppose
> > swupd
> > will be able to fix that, but I'm not sure.
> > 
> > It sounds like this bundle creation is completely separated from the
> > regular image creation; if so, then I suspect that this may have to
> > change.
> 
> Right, currently bundle creation happens after image creation and as
> above bundles are populated from the rootfs of the bundle images.
> 
> You're right, of course, we'll need to construct the running image from
> the bundle contents for more complex images.

We can remove the original do_rootfs and do_image and replace it with
code that copies the relevant subset of the mega image. Then the rest of
the image creation will see the right content.

> > > We took the approach of building images, rather than populating the
> > > chroot-like
> > > bundle directories with a package manager, because various layers
> > > and recipes
> > > make changes to the rootfs contents outside of the package manager,
> > > particularly
> > > with IMAGE_POSTPROCESS_COMMAND, etc.
> > Makes sense to me.
> > 
> > Have you considered generating the file lists more efficiently? I can
> > think of some alternatives, but all have downsides.
> > 
> 
> I did consider a couple of other approaches but with a goal of
> submitting this for M3 this approach felt like the surest route within
> the time available. I'd certainly like to find a more efficient method
> and if you have any suggestions I'd be happy to hear them.

I don't have any and thus agree with this route. I was merely wondering
whether you already had a working solution in mind.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.





^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 16:35   ` Philip Balister
  2016-02-24 18:36     ` Maciej Borzecki
@ 2016-02-24 19:51     ` Paul Eggleton
  2016-02-24 20:40       ` Philip Balister
  1 sibling, 1 reply; 35+ messages in thread
From: Paul Eggleton @ 2016-02-24 19:51 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Lock

On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
> On 02/24/2016 11:06 AM, Trevor Woerner wrote:
> > Ideally the work done here and the work done on meta-swupdate[1] would
> > be somehow merged so people creating images/distros would only have to
> > learn and integrate one software update solution, instead of having to
> > evaluate and choose between the two (or more?).
> > 
> > [1] https://github.com/sbabic/meta-swupdate
> 
> Amen. I had the same thoughts reading the patch set intro.

I think it would be hard to integrate these two, since they operate quite 
differently to eachother.
 
> Maybe the swupd should go in a seperate layer so we can see which
> project works best for oe users before moving something directly into
> oe-core?

This makes sense to me too though FWIW. The os-release patch should probably 
go straight in, but everything else looks like it could comfortably live in a 
separate layer without making things too difficult.

Cheers,
Paul

-- 

Paul Eggleton
Intel Open Source Technology Centre


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 19:51     ` Paul Eggleton
@ 2016-02-24 20:40       ` Philip Balister
  2016-02-25 21:42         ` Joshua G Lock
  0 siblings, 1 reply; 35+ messages in thread
From: Philip Balister @ 2016-02-24 20:40 UTC (permalink / raw)
  To: Paul Eggleton, openembedded-core; +Cc: Joshua Lock

On 02/24/2016 02:51 PM, Paul Eggleton wrote:
> On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
>> On 02/24/2016 11:06 AM, Trevor Woerner wrote:
>>> Ideally the work done here and the work done on meta-swupdate[1] would
>>> be somehow merged so people creating images/distros would only have to
>>> learn and integrate one software update solution, instead of having to
>>> evaluate and choose between the two (or more?).
>>>
>>> [1] https://github.com/sbabic/meta-swupdate
>>
>> Amen. I had the same thoughts reading the patch set intro.
> 
> I think it would be hard to integrate these two, since they operate quite 
> differently to eachother.
>  
>> Maybe the swupd should go in a seperate layer so we can see which
>> project works best for oe users before moving something directly into
>> oe-core?
> 
> This makes sense to me too though FWIW. The os-release patch should probably 
> go straight in, but everything else looks like it could comfortably live in a 
> separate layer without making things too difficult.

It also makes it easier to update as problems in swupd are resolved
since you do not need to go through the entire oe-core testing cycle.

Philip


> 
> Cheers,
> Paul
> 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
@ 2016-02-24 21:00   ` Burton, Ross
  2016-02-24 22:57   ` Andre McCurdy
  2016-02-25 17:13   ` Mark Hatle
  2 siblings, 0 replies; 35+ messages in thread
From: Burton, Ross @ 2016-02-24 21:00 UTC (permalink / raw)
  To: Joshua Lock; +Cc: OE-core

[-- Attachment #1: Type: text/plain, Size: 346 bytes --]

On 24 February 2016 at 14:52, Joshua Lock <joshua.g.lock@intel.com> wrote:

> +do_compile () {
> +       oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
> +}
> +
> +do_install () {
> +       oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}'
> BINDIR='${bindir}'
> +}
>

EXTRA_OEMAKE will make this neater.

Ross

[-- Attachment #2: Type: text/html, Size: 817 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
  2016-02-24 21:00   ` Burton, Ross
@ 2016-02-24 22:57   ` Andre McCurdy
  2016-02-25  8:48     ` Joshua G Lock
  2016-02-25 17:13   ` Mark Hatle
  2 siblings, 1 reply; 35+ messages in thread
From: Andre McCurdy @ 2016-02-24 22:57 UTC (permalink / raw)
  To: Joshua Lock; +Cc: OE Core mailing list

On Wed, Feb 24, 2016 at 6:52 AM, Joshua Lock <joshua.g.lock@intel.com> wrote:
> ---
>  meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 meta/recipes-extended/hardlink/hardlink_0.3.0.bb
>
> diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> new file mode 100644
> index 0000000..2e06ac2
> --- /dev/null
> +++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> @@ -0,0 +1,19 @@
> +SUMMARY = "hardlink is a tool which replaces multiple copies of a file with hardlinks."
> +LICENSE = "MIT"
> +LIC_FILES_CHKSUM = "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
> +
> +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar.xz"
> +SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
> +SRC_URI[sha256sum] = "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
> +
> +DEPENDS = "libpcre attr"

According to the style guide, DEPENDS should come between
LIC_FILES_CHKSUM and SRC_URI.

> +do_compile () {
> +       oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
> +}
> +
> +do_install () {
> +       oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
> +}
> +
> +BBCLASSEXTEND = "native nativesdk"
> --
> 2.5.0
>
> --
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 04/10] swupd-client: Add recipe
  2016-02-24 14:52 ` [PATCH 04/10] swupd-client: Add recipe Joshua Lock
@ 2016-02-25  8:07   ` Maciej Borzecki
  2016-02-25  8:50     ` Joshua G Lock
  0 siblings, 1 reply; 35+ messages in thread
From: Maciej Borzecki @ 2016-02-25  8:07 UTC (permalink / raw)
  To: Joshua Lock; +Cc: openembedded-core

On 02/24 14:52, Joshua Lock wrote:
> From: Mariano Lopez <mariano.lopez@linux.intel.com>
>
> This commit adds the Clear Linux client updater.
> This is experimental and bleeding edge, including the comments on the recipe.
>
> Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
> Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> ---
>  .../0001-Tolerate-quotes-in-os-release-files.patch | 59 ++++++++++++++++++++++
>  ...hange-systemctl-path-to-OE-systemctl-path.patch | 31 ++++++++++++
>  .../swupd-client/Fix-build-failure-on-Yocto.patch  | 36 +++++++++++++
>  .../Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch    | 38 ++++++++++++++
>  meta/recipes-devtools/swupd/swupd-client_2.87.bb   | 49 ++++++++++++++++++
>  5 files changed, 213 insertions(+)
>  create mode 100644 meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-client_2.87.bb
>
> diff --git a/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch b/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
> new file mode 100644
> index 0000000..49c71ae
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch
> @@ -0,0 +1,59 @@
> +From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:00 2001
> +From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> +Date: Thu, 11 Feb 2016 13:29:57 +0200
> +Subject: [PATCH 1/2] Tolerate quotes in os-release files
> +
> +Some systems like Yocto or OpenSUSE prefer to wrap values in
> +/etc/os-release file with quotes always and that still conforms
> +to the format defined in systemd.
> +
> +This patch removes quotes from the values before trying to
> +transform them into integer version id.
> +
> +Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> +
> +Upstream-Status: Backport (v3.0.0+)
> +
> +---
> + src/version.c | 18 +++++++++++++++++-
> + 1 file changed, 17 insertions(+), 1 deletion(-)
> +
> +diff --git a/src/version.c b/src/version.c
> +index 0e09cd9..83d6ad4 100644
> +--- a/src/version.c
> ++++ b/src/version.c
> +@@ -88,6 +88,7 @@ int read_version_from_subvol_file(char *path_prefix)
> + 	FILE *file;
> + 	int v = -1;
> + 	char *buildstamp;
> ++	char *src, *dest;
> +
> + 	string_or_die(&buildstamp, "%s/usr/lib/os-release", path_prefix);
> + 	file = fopen(buildstamp, "rm");
> +@@ -106,7 +107,22 @@ int read_version_from_subvol_file(char *path_prefix)
> + 			break;
> + 		}
> +
> +-		if (strncmp(line,"VERSION_ID=", 11) == 0) {
> ++		if (strncmp(line, "VERSION_ID=", 11) == 0) {
> ++			src = &line[11];
> ++
> ++			/* Drop quotes and newline in value */
> ++			dest = src;
> ++			while (*src) {
> ++				if (*src == '\'' || *src == '"' || *src == '\n') {
> ++					++src;
> ++				} else {
> ++					*dest = *src;
> ++					++dest;
> ++					++src;
> ++				}
> ++			}
> ++			*dest = 0;
> ++
> + 			v = strtoull(&line[11], NULL, 10);
> + 			break;
> + 		}
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch b/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
> new file mode 100644
> index 0000000..5ca6373
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch
> @@ -0,0 +1,31 @@
> +From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:00 2001
> +From: Jaska Uimonen <jaska.uimonen@intel.com>
> +Date: Thu, 14 Jan 2016 10:17:43 +0200
> +Subject: [PATCH] change systemctl path to OE systemctl path
> +
> +Upstream-Status: Inappropriate
> +
> +---
> + src/scripts.c | 4 ++--
> + 1 file changed, 2 insertions(+), 2 deletions(-)
> +
> +diff --git a/src/scripts.c b/src/scripts.c
> +index e426272..9bec0f5 100644
> +--- a/src/scripts.c
> ++++ b/src/scripts.c
> +@@ -84,10 +84,10 @@ static void update_triggers(void)
> + 	int ret;
> + 	LOG_INFO(NULL, "calling systemd trigger", class_scripts, "");
> +
> +-	ret = system("/usr/bin/systemctl daemon-reload");
> ++	ret = system("/bin/systemctl daemon-reload");
> + 	if (ret != 0)
> + 		LOG_ERROR(NULL, "systemd daemon reload failed", class_scripts, "%d", ret);
> +-	ret = system("/usr/bin/systemctl restart update-triggers.target");
> ++	ret = system("/bin/systemctl restart update-triggers.target");
> + 	if (ret != 0)
> + 		LOG_ERROR(NULL, "systemd update triggers failed", class_scripts, "%d", ret);
> + }
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch b/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
> new file mode 100644
> index 0000000..73f1728
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch
> @@ -0,0 +1,36 @@
> +From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:00 2001
> +From: Amarnath Valluri <amarnath.valluri@intel.com>
> +Date: Thu, 7 Jan 2016 16:19:34 +0200
> +Subject: [PATCH] Fix build failure on Yocto
> +
> +On install phase certificate files are being installed twice as included in
> +_DATA twice. We can use EXTRA_DIST than dist_.
> +
> +Upstream-Status: Inappropriate
> +
> +Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
> +---
> + Makefile.am | 4 ++--
> + 1 file changed, 2 insertions(+), 2 deletions(-)
> +
> +diff --git a/Makefile.am b/Makefile.am
> +index 1e65d3d..4d15c55 100644
> +--- a/Makefile.am
> ++++ b/Makefile.am
> +@@ -111,11 +111,11 @@ SWUPD_CERTS = certs/157753a5.0 \
> + 	certs/d6325660.0 \
> + 	certs/d6325660.1
> + swupdcerts_DATA = $(SWUPD_CERTS)
> +-dist_swupdcerts_DATA = $(SWUPD_CERTS)
> +
> + EXTRA_DIST += \
> + 	data/check-update.service \
> +-	data/check-update.timer
> ++	data/check-update.timer \
> ++	$(SWUPD_CERTS)
> +
> + DISTCHECK_CONFIGURE_FLAGS = \
> +         --with-systemdsystemunitdir=$$dc_install_base/$(systemdunitdir)
> +--
> +2.1.4
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch b/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
> new file mode 100644
> index 0000000..e5b53ef
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch
> @@ -0,0 +1,38 @@
> +From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:00 2001
> +From: Amarnath Valluri <amarnath.valluri@intel.com>
> +Date: Wed, 13 Jan 2016 15:46:19 +0200
> +Subject: [PATCH] Right usage of AC_ARG_ENABLE on bzip2
> +
> +Upstream-Status: Pending[Not submitted]
> +
> +Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
> +---
> + configure.ac | 12 +++++++-----
> + 1 file changed, 7 insertions(+), 5 deletions(-)
> +
> +diff --git a/configure.ac b/configure.ac
> +index f94a17d..b11ef0a 100644
> +--- a/configure.ac
> ++++ b/configure.ac
> +@@ -20,11 +20,13 @@ AC_CONFIG_HEADERS([config.h])
> + PKG_CHECK_MODULES([lzma], [liblzma])
> + PKG_CHECK_MODULES([zlib], [zlib])
> + AC_ARG_ENABLE(
> +-	bzip2,
> +-	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2 compression (uses bzip2 by default)]),
> +-	AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression]) ,
> +-	AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
> +-	AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [], [AC_MSG_ERROR([the libbz2 library is missing])])
> ++	[bzip2],
> ++	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2 compression (uses bzip2 by default)])
> ++)
> ++AS_IF([test "x$enable_bzip2" = "xyes" ],
> ++  [AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
> ++	 AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [], [AC_MSG_ERROR([the libbz2 library is missing])])],
> ++  [AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2 compression])]
> + )
> +
> + AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
> +--
> +2.1.4
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-client_2.87.bb b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
> new file mode 100644
> index 0000000..a5afdd6
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
> @@ -0,0 +1,49 @@
> +SUMMARY = "swupd sofware update from Clear Linux - client component"
> +LICENSE = "GPL-2.0"
> +LIC_FILES_CHKSUM = "file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
> +                    file://bsdiff/LICENSE;md5=0dbe7a50f028269750631fcbded3846a"
> +
> +SRC_URI = "\
> +    https://download.clearlinux.org/releases/5700/clear/source/SRPMS/${BPN}-${PV}-105.src.rpm;extract=${BP}.tar.gz \
> +    file://Fix-build-failure-on-Yocto.patch \
> +    file://Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch \
> +    file://Change-systemctl-path-to-OE-systemctl-path.patch \
> +    file://0001-Tolerate-quotes-in-os-release-files.patch \
> +"
> +
> +SRC_URI[md5sum] = "5d272c62edb8a9c576005ac5e1182ea3"
> +SRC_URI[sha256sum] = "45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1c66fb8"
> +
> +DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
> +RDEPENDS_${PN} = "gzip bzip2 tar xz"
> +# swupd requires at least an update-triggers target, should it be part of the
> +# swupd-client package?
> +RDEPENDS_${PN} = "swupd-units"
> +# We check /etc/os-release for the current OS version number
> +RRECOMMENDS_${PN} = "os-release"
> +
> +inherit pkgconfig autotools-brokensep systemd
> +
> +EXTRA_OECONF = "--with-systemdsystemunitdir=${systemd_system_unitdir}"
> +
> +#TODO: create and install /var/lib/swupd/{delta,staged/download}
> +do_install_append () {
> +    # swupd-client 2.87 doesn't (succesfully) create these and fails to update
> +    # should they not exist. This is due to a bash-specific shell command
> +    # called to create the directories 'mkdir -p /var/lib/{delta,staged,download}'
> +    install -d ${D}/var/lib/swupd/delta
> +    install -d ${D}/var/lib/swupd/download
> +    install -d ${D}/var/lib/swupd/staged
> +
> +    # TODO: This should be a less os-specific directory and not hard-code datadir
> +    install -d ${D}/usr/share/clear/bundles
> +}
> +
> +FILES_${PN} += "\
> +    /usr/share/clear \
> +    ${systemd_system_unitdir}/multi-user.target.wants* \
> +    /var/lib/swupd \

Try using ${datadir} and ${localstatedir} if possible:
    ${datadir}/clear
    ${localstatedir}/lib//swupd
    install -d ${D}${datadir}/clear/bundles


--
Maciej Borzęcki
Senior Software Developer at Open-RnD Sp. z o.o., Poland


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 02/10] swupd-server: initial recipe 2.53
  2016-02-24 14:52 ` [PATCH 02/10] swupd-server: initial recipe 2.53 Joshua Lock
@ 2016-02-25  8:11   ` Maciej Borzecki
  2016-02-25  8:51     ` Joshua G Lock
  0 siblings, 1 reply; 35+ messages in thread
From: Maciej Borzecki @ 2016-02-25  8:11 UTC (permalink / raw)
  To: Joshua Lock; +Cc: openembedded-core

On 02/24 14:52, Joshua Lock wrote:
> Include some patches to remove hard-coded state directory and backport some
> fixes.
>
> Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> ---
>  ...S-to-take-the-state-data-dir-as-an-argume.patch | 782 +++++++++++++++++++++
>  ...argv-helper-for-safer-calls-to-system-uti.patch | 133 ++++
>  ...re-option-to-re-enable-config-files-in-ma.patch |  66 ++
>  ...ression-that-introduced-a-directory-named.patch |  29 +
>  meta/recipes-devtools/swupd/swupd-server_2.53.bb   |  33 +
>  5 files changed, 1043 insertions(+)
>  create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
>  create mode 100644 meta/recipes-devtools/swupd/swupd-server_2.53.bb
>
> diff --git a/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch b/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
> new file mode 100644
> index 0000000..b771e0a
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch
> @@ -0,0 +1,782 @@
> +From 83fbb8a78594cf9047e37ed0aa1e931b9d691f2a Mon Sep 17 00:00:00 2001
> +From: Joshua Lock <joshua.g.lock@intel.com>
> +Date: Thu, 28 Jan 2016 10:24:56 +0000
> +Subject: [PATCH 1/2] Add option -S to take the state data dir as an argument
> +
> +The optional -S option expects a full path to a directory
> +swupd-server should use instead of the default /var/lib/update.
> +
> +Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> +
> +Upstream-Status: Accepted (v3.0+)
> +
> +---
> + include/swupd.h      | 11 ++++++---
> + src/analyze_fs.c     |  4 ++--
> + src/chroot.c         | 13 ++++++-----
> + src/globals.c        | 53 +++++++++++++++++++++++++++++++++++++++++
> + src/main.c           | 50 ++++++++++++++++++++++++++++++---------
> + src/make_fullfiles.c | 63 +++++++++++++++++++++++++++++++++++++++++++++----
> + src/make_packs.c     | 66 ++++++++++++++++++++++++++++++++++++++++++++--------
> + src/pack.c           | 65 +++++++++++++++++++++++++++------------------------
> + src/rename.c         |  6 ++---
> + src/versions.c       |  6 ++---
> + 10 files changed, 264 insertions(+), 73 deletions(-)
> +
> +diff --git a/include/swupd.h b/include/swupd.h
> +index 775c28e..58307d9 100644
> +--- a/include/swupd.h
> ++++ b/include/swupd.h
> +@@ -16,9 +16,6 @@
> + #define SWUPD_DEFAULT_FORMAT	3
> +
> + #define SWUPD_SERVER_STATE_DIR "/var/lib/update"
> +-#define PACKSTAGE_DIR SWUPD_SERVER_STATE_DIR "/packstage"
> +-#define IMAGE_DIR SWUPD_SERVER_STATE_DIR "/image"
> +-#define STAGING_DIR SWUPD_SERVER_STATE_DIR "/www"
> +
> + #if SWUPD_WITH_SELINUX
> + #define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*' --selinux"
> +@@ -123,9 +120,17 @@ extern int newversion;
> + extern int minversion;
> + extern char *format_string;
> +
> ++extern char *state_dir;
> ++extern char *packstage_dir;
> ++extern char *image_dir;
> ++extern char *staging_dir;
> ++
> + extern bool init_globals(void);
> + extern void free_globals(void);
> + extern bool set_format_string(char *);
> ++extern bool set_state_dir(char *);
> ++extern bool init_state_globals(void);
> ++extern void free_state_globals(void);
> +
> + extern int file_sort_hash(gconstpointer a, gconstpointer b);
> + extern int file_sort_filename(gconstpointer a, gconstpointer b);
> +diff --git a/src/analyze_fs.c b/src/analyze_fs.c
> +index 2326237..fdc359a 100644
> +--- a/src/analyze_fs.c
> ++++ b/src/analyze_fs.c
> +@@ -389,7 +389,7 @@ struct manifest *full_manifest_from_directory(int version)
> +
> + 	manifest = alloc_manifest(version, "full");
> +
> +-	string_or_die(&dir, "%s/%i/full", IMAGE_DIR, version);
> ++	string_or_die(&dir, "%s/%i/full", image_dir, version);
> +
> + 	threadpool = g_thread_pool_new(get_hash, dir, 12, FALSE, NULL);
> +
> +@@ -413,7 +413,7 @@ struct manifest *sub_manifest_from_directory(char *component, int version)
> +
> + 	manifest = alloc_manifest(version, component);
> +
> +-	string_or_die(&dir, "%s/%i/%s", IMAGE_DIR, version, component);
> ++	string_or_die(&dir, "%s/%i/%s", image_dir, version, component);
> +
> + 	iterate_directory(manifest, dir, "", false);
> +
> +diff --git a/src/chroot.c b/src/chroot.c
> +index 1d7df95..c5bb942 100644
> +--- a/src/chroot.c
> ++++ b/src/chroot.c
> +@@ -40,14 +40,15 @@ void chroot_create_full(int newversion)
> + 	char * command;
> + 	char *full_dir;
> +
> +-	string_or_die(&full_dir, "%s/%i/full/", IMAGE_DIR, newversion);
> ++	string_or_die(&full_dir, "%s/%i/full/ ", image_dir, newversion);
> +
> + 	g_mkdir_with_parents(full_dir, S_IRWXU);
> +
> +
> + 	/* start with base */
> + 	LOG(NULL, "Copying chroot os-core to full", "");
> +-	string_or_die(&command, "rsync -aAX " IMAGE_DIR "/%i/os-core/ %s", newversion, full_dir);
> ++	string_or_die(&command, "rsync -aAX %s/%i/os-core/ %s",
> ++	              image_dir, newversion, full_dir);
> + 	ret = system(command);
> + 	assert(ret==0);
> + 	free(command);
> +@@ -60,8 +61,8 @@ void chroot_create_full(int newversion)
> + 		}
> +
> + 		LOG(NULL, "Overlaying bundle chroot onto full", "%s", group);
> +-		string_or_die(&command, "rsync -aAX --ignore-existing " IMAGE_DIR "/%i/%s/ %s",
> +-		             newversion, group, full_dir);
> ++		string_or_die(&command, "rsync -aAX --ignore-existing %s/%i/%s/ %s",
> ++		             image_dir, newversion, group, full_dir);
> + 		ret = system(command);
> + 		assert(ret==0);
> + 		free(command);
> +@@ -80,8 +81,8 @@ void chroot_create_full(int newversion)
> + 		}
> +
> + 		LOG(NULL, "Recopy bundle chroot out of full", "%s", group);
> +-		string_or_die(&command, "rsync -aAX --existing %s " IMAGE_DIR "/%i/%s",
> +-		             full_dir, newversion, group);
> ++		string_or_die(&command, "rsync -aAX --existing %s %s/%i/%s",
> ++		             full_dir, image_dir, newversion, group);
> + 		ret = system(command);
> + 		assert(ret==0);
> + 		free(command);
> +diff --git a/src/globals.c b/src/globals.c
> +index 32dc793..ff6a3fa 100644
> +--- a/src/globals.c
> ++++ b/src/globals.c
> +@@ -34,6 +34,11 @@ int newversion = -1;
> + int minversion = 0;
> + char *format_string = NULL;
> +
> ++char *state_dir = NULL;
> ++char *packstage_dir = NULL;
> ++char *image_dir = NULL;
> ++char *staging_dir = NULL;
> ++
> + bool set_format_string(char *userinput)
> + {
> + 	int version;
> +@@ -52,12 +57,36 @@ bool set_format_string(char *userinput)
> + 	return true;
> + }
> +
> ++bool set_state_dir(char *dir)
> ++{
> ++	if (dir == NULL || dir[0] == '\0') {
> ++		return false;
> ++	}
> ++
> ++	/* TODO: more validation of input? */
> ++	if (dir[0] != '/') {
> ++		printf("statedir must be a full path starting with '/', not '%c'\n", dir[0]);
> ++		return false;
> ++	}
> ++
> ++	if (state_dir) {
> ++		free(state_dir);
> ++	}
> ++	string_or_die(&state_dir, "%s", dir);
> ++
> ++	return true;
> ++}
> ++
> + bool init_globals(void)
> + {
> + 	if (format_string == NULL) {
> + 		string_or_die(&format_string, "%d", SWUPD_DEFAULT_FORMAT);
> + 	}
> +
> ++	if (!init_state_globals()) {
> ++		return false;
> ++	}
> ++
> + 	if (newversion == -1) {
> + 		printf("Missing version parameter: No new version number specified\n");
> + 		return false;
> +@@ -71,4 +100,28 @@ bool init_globals(void)
> + void free_globals(void)
> + {
> + 	free(format_string);
> ++	free(state_dir);
> ++	free(packstage_dir);
> ++	free(image_dir);
> ++	free(staging_dir);
> ++}
> ++
> ++bool init_state_globals(void)
> ++{
> ++	if (state_dir == NULL) {
> ++		string_or_die(&state_dir, "%s", SWUPD_SERVER_STATE_DIR);
> ++	}
> ++	string_or_die(&packstage_dir, "%s/%s", state_dir, "packstage");
> ++	string_or_die(&image_dir, "%s/%s", state_dir, "image");
> ++	string_or_die(&staging_dir, "%s/%s", state_dir, "www");
> ++
> ++	return true;
> ++}
> ++
> ++void free_state_globals(void)
> ++{
> ++	free(state_dir);
> ++	free(packstage_dir);
> ++	free(image_dir);
> ++	free(staging_dir);
> + }
> +diff --git a/src/main.c b/src/main.c
> +index 7ed71d5..3d5f24a 100644
> +--- a/src/main.c
> ++++ b/src/main.c
> +@@ -55,6 +55,7 @@ static const struct option prog_opts[] = {
> + 	{"minversion", required_argument, 0, 'm'},
> + 	{"format", required_argument, 0, 'F'},
> + 	{"getformat", no_argument, 0, 'g'},
> ++	{"statedir", required_argument, 0, 'S'},
> + 	{0, 0, 0, 0}
> + };
> +
> +@@ -70,6 +71,7 @@ static void print_help(const char *name) {
> + 	printf("   -m, --minversion        Optional minimum file version to write into manifests per file\n");
> + 	printf("   -F, --format            Optional format string [ default:=%d ]\n", SWUPD_DEFAULT_FORMAT);
> + 	printf("   -g, --getformat         Print current format string and exit\n");
> ++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
> + 	printf("\n");
> + }
> +
> +@@ -77,7 +79,7 @@ static bool parse_options(int argc, char **argv)
> + {
> + 	int opt;
> +
> +-	while ((opt = getopt_long(argc, argv, "hvo:m:F:g", prog_opts, NULL)) != -1) {
> ++	while ((opt = getopt_long(argc, argv, "hvo:m:F:g:S:", prog_opts, NULL)) != -1) {
> + 		switch (opt) {
> + 		case '?':
> + 		case 'h':
> +@@ -107,6 +109,12 @@ static bool parse_options(int argc, char **argv)
> + 				return false;
> + 			}
> + 			break;
> ++		case 'S':
> ++			if (!optarg || !set_state_dir(optarg)) {
> ++				printf("Invalid --statedir argument ''%s'\n\n", optarg);
> ++				return false;
> ++			}
> ++			break;
> + 		case 'g':
> + 			if (format_string == NULL) {
> + 				printf("%d\n", SWUPD_DEFAULT_FORMAT);
> +@@ -138,9 +146,14 @@ static void check_root(void)
> + static void populate_dirs(int version)
> + {
> + 	char *newversiondir;
> +-	string_or_die(&newversiondir, "%s/%d", IMAGE_DIR, version);
> ++
> ++	string_or_die(&newversiondir, "%s/%d", image_dir, version);
> +
> + 	if ((access(newversiondir, F_OK | R_OK) != 0) && (version == 0)) {
> ++		char *latestpath = NULL;
> ++
> ++		string_or_die(&latestpath, "%s/latest.version", image_dir);
> ++
> + 		printf("** %s does not exist... creating and populating\n", newversiondir);
> + 		if (mkdir(newversiondir, 0755) != 0) {
> + 			printf("Failed to create directory\n");
> +@@ -151,14 +164,17 @@ static void populate_dirs(int version)
> + 		}
> +
> + 		FILE *latestver;
> +-		latestver = fopen_exclusive(IMAGE_DIR "/latest.version");
> ++		latestver = fopen_exclusive(latestpath);
> + 		if (latestver == NULL) {
> +-			printf("Failed to create %s/latest.version\n", IMAGE_DIR);
> ++			printf("Failed to create %s\n", latestpath);
> ++			free(latestpath);
> + 			return;
> + 		}
> + 		if (fwrite("0\n", 2, 1, latestver) != 1) {
> + 			LOG(NULL, "Failed to write latestver", "errno: %d", errno);
> + 		}
> ++
> ++		free(latestpath);
> + 		fclose(latestver);
> + 	}
> + 	/* groups don't exist in version 0 */
> +@@ -170,7 +186,7 @@ static void populate_dirs(int version)
> + 				break;
> + 			}
> +
> +-			string_or_die(&newversiondir, "%s/%d/%s", IMAGE_DIR, version, group);
> ++			string_or_die(&newversiondir, "%s/%d/%s", image_dir, version, group);
> +
> + 			/* Create the bundle directory(s) as needed */
> + 			if (access(newversiondir, F_OK | R_OK) != 0) {
> +@@ -186,13 +202,18 @@ static void populate_dirs(int version)
> +
> + static int check_build_env(void)
> + {
> +-	if (access(SWUPD_SERVER_STATE_DIR "/temp", F_OK | R_OK) != 0) {
> +-		LOG(NULL, "/var/lib/update/temp does not exist...creating directory", "");
> +-		if (mkdir(SWUPD_SERVER_STATE_DIR "/temp", 0755) != 0) {
> ++	char *temp_dir = NULL;
> ++	string_or_die(&temp_dir, "%s/%s", state_dir, "/temp");
> ++
> ++	if (access(temp_dir, F_OK | R_OK) != 0) {
> ++		LOG(NULL, "%s", "does not exist...creating directory", temp_dir);
> ++		if (mkdir(temp_dir, 0755) != 0) {
> + 			printf("Failed to create build directory, EXITING\n");
> ++			free(temp_dir);
> + 			return -errno;
> + 		}
> + 	}
> ++	free(temp_dir);
> +
> + 	return 0;
> + }
> +@@ -217,6 +238,8 @@ int main(int argc, char **argv)
> + 	int exit_status = EXIT_FAILURE;
> + 	int ret;
> +
> ++	char *file_path = NULL;
> ++
> + 	/* keep valgrind working well */
> + 	setenv("G_SLICE", "always-malloc", 0);
> +
> +@@ -240,12 +263,17 @@ int main(int argc, char **argv)
> + 	}
> +
> +
> +-	if (!read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini")) {
> +-		printf("Failed to read " SWUPD_SERVER_STATE_DIR "/server.ini configuration file!\n");
> ++	string_or_die(&file_path, "%s/server.ini", state_dir);
> ++	if (!read_configuration_file(file_path)) {
> ++		printf("Failed to read %s configuration file!\n", state_dir);
> ++		free(file_path);
> + 		goto exit;
> + 	}
> ++	free(file_path);
> +
> +-	read_group_file(SWUPD_SERVER_STATE_DIR "/groups.ini");
> ++	string_or_die(&file_path, "%s/groups.ini", state_dir);
> ++	read_group_file(file_path);
> ++	free(file_path);
> +
> + 	read_current_version("latest.version");
> + 	printf("Last processed version is %i\n", current_version);
> +diff --git a/src/make_fullfiles.c b/src/make_fullfiles.c
> +index e755a33..bf97a1c 100644
> +--- a/src/make_fullfiles.c
> ++++ b/src/make_fullfiles.c
> +@@ -27,8 +27,52 @@
> + #include <string.h>
> + #include <assert.h>
> +
> ++#include <getopt.h>
> ++
> + #include <swupd.h>
> +
> ++static const struct option prog_opts[] = {
> ++	{"help", no_argument, 0, 'h'},
> ++	{"statedir", required_argument, 0, 'S'},
> ++	{0, 0, 0, 0}
> ++};
> ++
> ++static void usage(const char *name)
> ++{
> ++	printf("usage:\n");
> ++	printf("   %s <version>\n\n", name);
> ++	printf("Help options:\n");
> ++	printf("   -h, --help              Show help options\n");
> ++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
> ++	printf("\n");
> ++}
> ++
> ++static bool parse_options(int argc, char **argv)
> ++{
> ++	int opt;
> ++
> ++	while ((opt = getopt_long(argc, argv, "hS:", prog_opts, NULL)) != -1) {
> ++		switch (opt) {
> ++			case '?':
> ++			case 'h':
> ++				usage(argv[0]);
> ++				return false;
> ++			case 'S':
> ++				if (!optarg || !set_state_dir(optarg)) {
> ++					printf("Invalid --statedir argument '%s'\n\n", optarg);
> ++					return false;
> ++				}
> ++				break;
> ++		}
> ++	}
> ++
> ++	if (!init_state_globals()) {
> ++		return false;
> ++	}
> ++
> ++	return true;
> ++}
> ++
> + static void banner(void)
> + {
> + 	printf(PACKAGE_NAME " update creator -- fullfiles -- version " PACKAGE_VERSION "\n");
> +@@ -51,20 +95,29 @@ int main(int argc, char **argv)
> + {
> + 	struct manifest *manifest;
> + 	int version;
> ++	char *file_path = NULL;
> +
> + 	/* keep valgrind working well */
> + 	setenv("G_SLICE", "always-malloc", 0);
> +
> ++	if (!parse_options(argc, argv)) {
> ++		free_state_globals();
> ++		return EXIT_FAILURE;
> ++	}
> + 	banner();
> + 	check_root();
> +
> +-	read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini");
> ++	string_or_die(&file_path, "%s/server.ini", state_dir);
> ++	read_configuration_file(file_path);
> ++	free(file_path);
> +
> +-	if (argc < 1) {
> +-		printf("Usage:\n\tswupd_make_fullfiles <version>\n\n");
> ++	if (argc - optind < 1) {
> ++		usage(argv[0]);
> ++		free_state_globals();
> + 		exit(EXIT_FAILURE);
> + 	}
> +-	version = strtoull(argv[1], NULL, 10);
> ++
> ++	version = strtoull(argv[optind++], NULL, 10);
> + 	if (version < 0) {
> + 		printf("Usage:\n\tswupd_make_fullfiles <version>\n\n");
> + 		exit(EXIT_FAILURE);
> +@@ -73,5 +126,7 @@ int main(int argc, char **argv)
> + 	manifest = manifest_from_file(version, "full");
> + 	create_fullfiles(manifest);
> +
> ++	free_state_globals();
> ++
> + 	return EXIT_SUCCESS;
> + }
> +diff --git a/src/make_packs.c b/src/make_packs.c
> +index 20fbd67..2b62b8a 100644
> +--- a/src/make_packs.c
> ++++ b/src/make_packs.c
> +@@ -33,6 +33,8 @@
> +
> + #include <glib.h>
> +
> ++#include <getopt.h>
> ++
> + #include <swupd.h>
> +
> + static void banner(void)
> +@@ -43,12 +45,47 @@ static void banner(void)
> + 	printf("\n");
> + }
> +
> +-static void usage(void)
> ++static const struct option prog_opts[] = {
> ++	{"help", no_argument, 0, 'h'},
> ++	{"statedir", required_argument, 0, 'S'},
> ++	{0, 0, 0, 0}
> ++};
> ++
> ++static void usage(const char *name)
> + {
> + 	printf("usage:\n");
> +-	printf("   swupd_make_pack <start version> <latest version> <bundle>\n");
> ++	printf("   %s <start version> <latest version> <bundle>\n\n", name);
> ++	printf("Help options:\n");
> ++	printf("   -h, --help              Show help options\n");
> ++	printf("   -S, --statedir          Optional directory to use for state [ default:=%s ]\n", SWUPD_SERVER_STATE_DIR);
> + 	printf("\n");
> +-	exit(EXIT_FAILURE);
> ++}
> ++
> ++static bool parse_options(int argc, char **argv)
> ++{
> ++	int opt;
> ++
> ++	while ((opt = getopt_long(argc, argv, "hS:", prog_opts, NULL)) != -1) {
> ++		switch (opt) {
> ++		case '?':
> ++		case 'h':
> ++			usage(argv[0]);
> ++			return false;
> ++		case 'S':
> ++			if (!optarg || !set_state_dir(optarg)) {
> ++				printf("Invalid --statedir argument ''%s'\n\n", optarg);
> ++				return false;
> ++			}
> ++			break;
> ++		}
> ++	}
> ++
> ++	/* FIXME: *_state_globals() are ugly hacks */
> ++	if (!init_state_globals()) {
> ++		return false;
> ++	}
> ++
> ++	return true;
> + }
> +
> + int main(int argc, char **argv)
> +@@ -59,11 +96,17 @@ int main(int argc, char **argv)
> + 	char *module;
> + 	struct packdata *pack;
> + 	int exit_status = EXIT_FAILURE;
> ++	char *file_path = NULL;
> +
> ++	if (!parse_options(argc, argv)) {
> ++		free_state_globals();
> ++		return EXIT_FAILURE;
> ++	}
> + 	banner();
> +
> +-	if (argc != 4) {
> +-		usage();
> ++	if (argc - optind != 3) {
> ++		usage(argv[0]);
> ++		exit(EXIT_FAILURE);
> + 	}
> +
> + 	/* FIXME: should use "end_version" not "0" and a unique filename
> +@@ -76,12 +119,13 @@ int main(int argc, char **argv)
> + 		return exit_status;
> + 	}
> +
> +-	read_configuration_file(SWUPD_SERVER_STATE_DIR "/server.ini");
> +-
> ++	string_or_die(&file_path, "%s/server.ini", state_dir);
> ++	read_configuration_file(file_path);
> ++	free(file_path);
> +
> +-	start_version = strtoull(argv[1], NULL, 10);
> +-	end_version = strtoull(argv[2], NULL, 10);
> +-	module = argv[3];
> ++	start_version = strtoull(argv[optind++], NULL, 10);
> ++	end_version = strtoull(argv[optind++], NULL, 10);
> ++	module = argv[optind++];
> +
> + 	if ((start_version < 0) ||
> + 	    (end_version == 0) ||
> +@@ -108,5 +152,7 @@ int main(int argc, char **argv)
> + 	printf("Pack creation %s (pack-%s %i to %li)\n",
> + 		exit_status == EXIT_SUCCESS ? "complete" : "failed",
> + 		module, start_version, end_version);
> ++
> ++	free_state_globals();
> + 	return exit_status;
> + }
> +diff --git a/src/pack.c b/src/pack.c
> +index e96e9a4..036853f 100644
> +--- a/src/pack.c
> ++++ b/src/pack.c
> +@@ -46,21 +46,21 @@ static void empty_pack_stage(int full, int version, char *module)
> + 	int ret;
> +
> + 	// clean any stale data (eg: re-run after a failure)
> +-	string_or_die(&cmd, "rm -rf " PACKSTAGE_DIR "/%s/%i/", module, version);
> ++	string_or_die(&cmd, "rm -rf %s/%s/%i/", packstage_dir, module, version);
> + 	ret = system(cmd);
> + 	if (ret) {
> +-		fprintf(stderr, "Failed to clean " PACKSTAGE_DIR "/%s/%i\n",
> +-			module, version);
> ++		fprintf(stderr, "Failed to clean %s/%s/%i\n",
> ++			packstage_dir, module, version);
> + 		exit(EXIT_FAILURE);
> + 	}
> + 	free(cmd);
> +
> + 	if (!full) {
> + 		// (re)create module/version/{delta,staged}
> +-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/delta", module, version);
> ++		string_or_die(&path, "%s/%s/%i/delta", packstage_dir, module, version);
> + 		g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
> + 		free(path);
> +-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged", module, version);
> ++		string_or_die(&path, "%s/%s/%i/staged", packstage_dir, module, version);
> + 		g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
> + 		free(path);
> + 	}
> +@@ -76,7 +76,7 @@ static void explode_pack_stage(int version, char *module)
> + 	struct stat buf;
> + 	char *path;
> +
> +-	string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged", module, version);
> ++	string_or_die(&path, "%s/%s/%i/staged", packstage_dir, module, version);
> + 	g_mkdir_with_parents(path, S_IRWXU | S_IRWXG);
> + 	dir = opendir(path);
> + 	if (!dir) {
> +@@ -99,7 +99,8 @@ static void explode_pack_stage(int version, char *module)
> + 			continue;
> + 		}
> +
> +-		string_or_die(&path, PACKSTAGE_DIR "/%s/%i/staged/%s", module, version, entry->d_name);
> ++		string_or_die(&path, "%s/%s/%i/staged/%s",
> ++		              packstage_dir, module, version, entry->d_name);
> + 		ret = stat(path, &buf);
> + 		if (ret) {
> + 			free(path);
> +@@ -112,8 +113,8 @@ static void explode_pack_stage(int version, char *module)
> + 		 * the resulting pack is slightly smaller, and in addition, we're saving CPU
> + 		 * time on the client...
> + 		 */
> +-		string_or_die(&tar, "tar --directory=" PACKSTAGE_DIR "/%s/%i/staged --warning=no-timestamp "
> +-				TAR_PERM_ATTR_ARGS " -axf %s", module, version, path);
> ++		string_or_die(&tar, "tar --directory=%s/%s/%i/staged --warning=no-timestamp "
> ++				TAR_PERM_ATTR_ARGS " -axf %s", packstage_dir, module, version, path);
> + 		ret = system(tar);
> + 		if (!ret) {
> + 			unlink(path);
> +@@ -162,8 +163,8 @@ static void make_pack_full_files(struct packdata *pack)
> + 		if ((!file->peer || file->peer->is_deleted) && !file->is_deleted && !file->rename_peer) {
> + 			char *from, *to;
> + 			/* hardlink each file that is in <end> but not in <X> */
> +-			string_or_die(&from, STAGING_DIR "/%i/files/%s.tar", file->last_change, file->hash);
> +-			string_or_die(&to, PACKSTAGE_DIR "/%s/%i/staged/%s.tar", pack->module, pack->from, file->hash);
> ++			string_or_die(&from, "%s/%i/files/%s.tar", staging_dir, file->last_change, file->hash);
> ++			string_or_die(&to, "%s/%s/%i/staged/%s.tar", packstage_dir, pack->module, pack->from, file->hash);
> + 			ret = link(from, to);
> + 			if (ret) {
> + 				if (errno != EEXIST) {
> +@@ -228,8 +229,8 @@ static GList *consolidate_packs_delta_files(GList *files, struct packdata *pack)
> + 			continue;
> + 		}
> +
> +-		string_or_die(&from, STAGING_DIR "/%i/delta/%i-%i-%s", file->last_change,
> +-				file->peer->last_change, file->last_change, file->hash);
> ++		string_or_die(&from, "%s/%i/delta/%i-%i-%s", staging_dir, file->last_change,
> ++		              file->peer->last_change, file->last_change, file->hash);
> +
> + 		ret = stat(from, &stat_delta);
> + 		if (ret && !find_file_in_list(files, file)) {
> +@@ -284,8 +285,8 @@ static int write_pack_signature(struct packdata *pack)
> + 	char *filename = NULL;
> + 	int ret = -1;
> +
> +-	string_or_die(&filename, STAGING_DIR "/%i/pack-%s-from-%i.tar",
> +-			pack->to, pack->module, pack->from);
> ++	string_or_die(&filename, "%s/%i/pack-%s-from-%i.tar",
> ++			staging_dir, pack->to, pack->module, pack->from);
> + 	if (!signature_sign(filename)) {
> + 		fprintf(stderr, "Creating signature for '%s' failed\n", filename);
> + 		goto exit;
> +@@ -324,12 +325,14 @@ static int make_final_pack(struct packdata *pack)
> +
> + 		/* for each file changed since <X> */
> + 		/* locate delta, check if the diff it's from is >= <X> */
> +-		string_or_die(&from, STAGING_DIR "/%i/delta/%i-%i-%s", file->last_change,
> +-				file->peer->last_change, file->last_change, file->hash);
> +-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/delta/%i-%i-%s", pack->module, pack->from,
> ++		string_or_die(&from, "%s/%i/delta/%i-%i-%s", staging_dir, file->last_change,
> + 				file->peer->last_change, file->last_change, file->hash);
> +-		string_or_die(&tarfrom, STAGING_DIR "/%i/files/%s.tar", file->last_change, file->hash);
> +-		string_or_die(&tarto, PACKSTAGE_DIR "/%s/%i/staged/%s.tar", pack->module, pack->from, file->hash);
> ++		string_or_die(&to, "%s/%s/%i/delta/%i-%i-%s", packstage_dir, pack->module,
> ++				pack->from, file->peer->last_change, file->last_change, file->hash);
> ++		string_or_die(&tarfrom, "%s/%i/files/%s.tar", staging_dir,
> ++				file->last_change, file->hash);
> ++		string_or_die(&tarto, "%s/%s/%i/staged/%s.tar", packstage_dir, pack->module,
> ++				pack->from, file->hash);
> +
> + 		ret = stat(from, &stat_delta);
> + 		if (ret) {
> +@@ -388,8 +391,8 @@ static int make_final_pack(struct packdata *pack)
> + 		char *from, *to;
> + 		struct stat st;
> +
> +-		string_or_die(&from, STAGING_DIR "/%i/Manifest-%s-delta-from-%i",
> +-				pack->to, pack->module, pack->from);
> ++		string_or_die(&from, "%s/%i/Manifest-%s-delta-from-%i",
> ++				staging_dir, pack->to, pack->module, pack->from);
> +
> + 		ret = stat(from, &st);
> + 		if (ret) {
> +@@ -398,8 +401,8 @@ static int make_final_pack(struct packdata *pack)
> + 		}
> +
> +
> +-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/Manifest-%s-delta-from-%i",
> +-				pack->module, pack->from, pack->module, pack->from);
> ++		string_or_die(&to, "%s/%s/%i/Manifest-%s-delta-from-%i",
> ++				packstage_dir, pack->module, pack->from, pack->module, pack->from);
> +
> + 		ret = link(from, to);
> + 		if (ret) {
> +@@ -416,16 +419,16 @@ static int make_final_pack(struct packdata *pack)
> + 		char *from, *to;
> + 		struct stat st;
> +
> +-		string_or_die(&from, STAGING_DIR "/%i/Manifest-%s-delta-from-%i",
> +-				pack->to, "MoM", pack->from);
> ++		string_or_die(&from, "%s/%i/Manifest-%s-delta-from-%i",
> ++				staging_dir, pack->to, "MoM", pack->from);
> + 		ret = stat(from, &st);
> + 		if (ret) {
> + 			LOG(NULL, "Making extra manifest delta", "MoM: %i->%i", pack->from, pack->to);
> + 			create_manifest_delta(pack->from, pack->to, "MoM");
> + 		}
> +
> +-		string_or_die(&to, PACKSTAGE_DIR "/%s/%i/Manifest-%s-delta-from-%i",
> +-				pack->module, pack->from, "MoM", pack->from);
> ++		string_or_die(&to, "%s/%s/%i/Manifest-%s-delta-from-%i",
> ++				packstage_dir, pack->module, pack->from, "MoM", pack->from);
> +
> + 		ret = link(from, to);
> + 		if (ret) {
> +@@ -439,9 +442,9 @@ static int make_final_pack(struct packdata *pack)
> +
> + 	/* tar the staging directory up */
> + 	LOG(NULL, "starting tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
> +-	string_or_die(&tar, "tar " TAR_PERM_ATTR_ARGS " --directory=" PACKSTAGE_DIR "/%s/%i/ "
> +-			"--numeric-owner -Jcf " STAGING_DIR "/%i/pack-%s-from-%i.tar delta staged",
> +-			pack->module, pack->from, pack->to, pack->module, pack->from);
> ++	string_or_die(&tar, "tar " TAR_PERM_ATTR_ARGS " --directory=%s/%s/%i/ "
> ++			"--numeric-owner -Jcf %s/%i/pack-%s-from-%i.tar delta staged",
> ++			packstage_dir, pack->module, pack->from, staging_dir, pack->to, pack->module, pack->from);
> + 	ret = system(tar);
> + 	free(tar);
> + 	LOG(NULL, "finished tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
> +diff --git a/src/rename.c b/src/rename.c
> +index 70f9006..5ea979c 100644
> +--- a/src/rename.c
> ++++ b/src/rename.c
> +@@ -153,7 +153,7 @@ static void precompute_file_data(struct manifest *manifest, struct file *file, i
> + 	}
> +
> + 	if (manifest)  {
> +-		string_or_die(&filename, "%s/%i/%s/%s", IMAGE_DIR, manifest->version, manifest->component, file->filename);
> ++		string_or_die(&filename, "%s/%i/%s/%s", image_dir, manifest->version, manifest->component, file->filename);
> + 	} else if (old_rename) {
> + 		item = g_list_first(last_versions_list);
> + 		while (item) {
> +@@ -161,13 +161,13 @@ static void precompute_file_data(struct manifest *manifest, struct file *file, i
> + 			item = g_list_next(item);
> +
> + 			free(filename);
> +-			string_or_die(&filename, "%s/%i/full/%s", IMAGE_DIR, last_change, file->filename);
> ++			string_or_die(&filename, "%s/%i/full/%s", image_dir, last_change, file->filename);
> + 			if (!lstat(filename, &buf)) {
> + 				break;
> + 			}
> + 		}
> + 	} else {
> +-		string_or_die(&filename, "%s/%i/full/%s", IMAGE_DIR, file->last_change, file->filename);
> ++		string_or_die(&filename, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
> + 	}
> +
> + 	/* make sure file->stat.st_size is valid */
> +diff --git a/src/versions.c b/src/versions.c
> +index 6860160..0fb729a 100644
> +--- a/src/versions.c
> ++++ b/src/versions.c
> +@@ -215,10 +215,10 @@ GList *get_last_versions_list(int next_version, int max_versions)
> + 	int idx, build_num, build_type, jump_point;
> + 	int jump_point_found;
> +
> +-	dir = opendir(STAGING_DIR);
> ++	dir = opendir(staging_dir);
> + 	if (dir == NULL) {
> + 		LOG(NULL, "Cannot open directory", "dir_path= %s, strerror= %s",
> +-				STAGING_DIR, strerror(errno));
> ++				staging_dir, strerror(errno));
> + 		return NULL;
> + 	}
> +
> +@@ -228,7 +228,7 @@ GList *get_last_versions_list(int next_version, int max_versions)
> + 		}
> +
> + 		free(filename);
> +-		string_or_die(&filename, STAGING_DIR "/%s", entry.d_name);
> ++		string_or_die(&filename, "%s/%s", staging_dir, entry.d_name);
> +
> + 		if (lstat(filename, &stat)) {
> + 			LOG(NULL, "lstat failed", "path= %s, strerror= %s",
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch b/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
> new file mode 100644
> index 0000000..f94305e
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch
> @@ -0,0 +1,133 @@
> +From 8f24ef7f857c9d2c2eb2601a2a1e06123c086001 Mon Sep 17 00:00:00 2001
> +From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> +Date: Fri, 29 Jan 2016 17:48:46 +0200
> +Subject: [PATCH swupd-server 1/2] Add system_argv() helper for safer calls to
> + system utilities
> +
> +Often file names contain special characters like hashes or
> +whitespaces and that makes escaping a difficult task when using
> +system(). Thus add a new helper system_argv() that is based
> +on execvp() syscall and doesn't require escaping.
> +
> +Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> +
> +Upstream-Status: Backport (v2.54+)
> +
> +---
> + include/swupd.h |  1 +
> + src/fullfiles.c |  6 ++----
> + src/helpers.c   | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> + 3 files changed, 66 insertions(+), 4 deletions(-)
> +
> +diff --git a/include/swupd.h b/include/swupd.h
> +index 00b88d4..2805186 100644
> +--- a/include/swupd.h
> ++++ b/include/swupd.h
> +@@ -223,6 +223,7 @@ extern FILE * fopen_exclusive(const char *filename); /* no mode, opens for write
> + extern void dump_file_info(struct file *file);
> + extern void string_or_die(char **strp, const char *fmt, ...);
> + extern void print_elapsed_time(struct timeval *previous_time, struct timeval *current_time);
> ++extern int system_argv(char *const argv[]);
> +
> + extern bool signature_initialize(void);
> + extern void signature_terminate(void);
> +diff --git a/src/fullfiles.c b/src/fullfiles.c
> +index 1bb581e..fa78293 100644
> +--- a/src/fullfiles.c
> ++++ b/src/fullfiles.c
> +@@ -138,12 +138,10 @@ static void create_fullfile(struct file *file)
> + 		string_or_die(&tempfile, "%s/%s", empty, file->hash);
> + 		if (link(origin, tempfile) < 0) {
> + 			LOG(NULL, "hardlink failed", "%s due to %s (%s -> %s)", file->filename, strerror(errno), origin, tempfile);
> +-			string_or_die(&tarcommand, "cp -a %s %s", origin, tempfile);
> +-			if (system(tarcommand) != 0) {
> +-				LOG(NULL, "Failed to run command:", "%s", tarcommand);
> ++			char *const argv[] = {"cp", "-a", origin, tempfile, NULL};
> ++			if (system_argv(argv) != 0) {
> + 				assert(0);
> + 			}
> +-			free(tarcommand);
> + 		}
> +
> + 		/* step 2a: tar it with each compression type  */
> +diff --git a/src/helpers.c b/src/helpers.c
> +index 65acffd..5884b51 100644
> +--- a/src/helpers.c
> ++++ b/src/helpers.c
> +@@ -29,6 +29,7 @@
> + #include <sys/types.h>
> + #include <sys/stat.h>
> + #include <sys/time.h>
> ++#include <sys/wait.h>
> + #include <fcntl.h>
> + #include <errno.h>
> +
> +@@ -124,3 +125,65 @@ void print_elapsed_time(struct timeval *previous_time, struct timeval *current_t
> +
> + 	free(elapsed);
> + }
> ++
> ++void concat_str_array(char **output, char *const argv[])
> ++{
> ++	int size = 0;
> ++
> ++	for (int i = 0; argv[i]; i++) {
> ++		size += strlen(argv[i]) + 1;
> ++	}
> ++
> ++	*output = malloc(size + 1);
> ++	if (!*output) {
> ++		LOG(NULL, "Failed to allocate", "%i bytes", size);
> ++		assert(0);
> ++	}
> ++	strcpy(*output, "");
> ++	for (int i = 0; argv[i]; i++) {
> ++		strcat(*output, argv[i]);
> ++		strcat(*output, " ");
> ++	}
> ++}
> ++
> ++int system_argv(char *const argv[])
> ++{
> ++	int child_exit_status;
> ++	pid_t pid;
> ++	int status;
> ++
> ++	pid = fork();
> ++
> ++	if (pid == 0) { /* child */
> ++		execvp(*argv, argv);
> ++		LOG(NULL, "This line must not be reached", "");
> ++		assert(0);
> ++	} else if (pid < 0) {
> ++		LOG(NULL, "Failed to fork a child process", "");
> ++		assert(0);
> ++	} else {
> ++		pid_t ws = waitpid(pid, &child_exit_status, 0);
> ++
> ++		if (ws == -1) {
> ++			LOG(NULL, "Failed to wait for child process", "");
> ++			assert(0);
> ++		}
> ++
> ++		if (WIFEXITED(child_exit_status)) {
> ++			status = WEXITSTATUS(child_exit_status);
> ++		} else {
> ++			LOG(NULL, "Child process didn't exit", "");
> ++			assert(0);
> ++		}
> ++
> ++		if (status != 0) {
> ++			char* cmdline = NULL;
> ++
> ++			concat_str_array(&cmdline, argv);
> ++			LOG(NULL, "Failed to run command:", "%s", cmdline);
> ++			free(cmdline);
> ++		}
> ++
> ++		return status;
> ++	}
> ++}
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch b/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
> new file mode 100644
> index 0000000..a5ab7af
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch
> @@ -0,0 +1,66 @@
> +From e209255d8985eb4eb4c43f5e773ee1a0a16eb297 Mon Sep 17 00:00:00 2001
> +From: Joshua Lock <joshua.g.lock@intel.com>
> +Date: Fri, 12 Feb 2016 16:02:58 +0000
> +Subject: [PATCH 2/2] Add configure option to re-enable config files in
> + manifests
> +
> +Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> +
> +Upstream-Status: Accepted (v3.0+)
> +
> +---
> + configure.ac    | 6 ++++++
> + include/swupd.h | 6 ++++++
> + src/manifest.c  | 2 +-
> + 3 files changed, 13 insertions(+), 1 deletion(-)
> +
> +diff --git a/configure.ac b/configure.ac
> +index 8bb6e3b..afffad5 100644
> +--- a/configure.ac
> ++++ b/configure.ac
> +@@ -28,6 +28,12 @@ AC_ARG_ENABLE(
> +     AC_DEFINE(SWUPD_WITH_LZMA,1,[Use lzma compression])
> + 	[enable_lzma=check]
> + )
> ++AC_ARG_ENABLE(
> ++    [stateless],
> ++    AS_HELP_STRING([--disable-stateless],[OS is not stateless, do not ignore configuration files (stateless by default)]),
> ++    AC_DEFINE(SWUPD_WITH_STATELESS,0,[OS is not stateless]),
> ++		AC_DEFINE(SWUPD_WITH_STATELESS,1,[OS is stateless])
> ++)
> +
> + AS_IF([test "$enable_lzma" = "check"],
> + 	[PKG_CHECK_MODULES([lzma],
> +diff --git a/include/swupd.h b/include/swupd.h
> +index 58307d9..7cce735 100644
> +--- a/include/swupd.h
> ++++ b/include/swupd.h
> +@@ -23,6 +23,12 @@
> + #define TAR_PERM_ATTR_ARGS "--preserve-permissions --xattrs --xattrs-include='*'"
> + #endif
> +
> ++#if SWUPD_WITH_STATELESS
> ++#define OS_IS_STATELESS 1
> ++#else
> ++#define OS_IS_STATELESS 0
> ++#endif
> ++
> + /* Build types */
> + #define REGULAR_BUILD 0
> + #define FIX_BUILD     1
> +diff --git a/src/manifest.c b/src/manifest.c
> +index 69a8fb9..58d0be1 100644
> +--- a/src/manifest.c
> ++++ b/src/manifest.c
> +@@ -830,7 +830,7 @@ int prune_manifest(struct manifest *manifest)
> + 		next = g_list_next(list);
> + 		file = list->data;
> +
> +-		if ((!file->is_deleted) && (file->is_config)) {
> ++		if (OS_IS_STATELESS && (!file->is_deleted) && (file->is_config)) {
> + 			// toward being a stateless OS
> + 			LOG(file, "Skipping config file in manifest write", "component %s", manifest->component);
> + 			manifest->files = g_list_delete_link(manifest->files, list);
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch b/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
> new file mode 100644
> index 0000000..9c1d8fa
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch
> @@ -0,0 +1,29 @@
> +From aba4418696ef31ab5afc9811903a044366619dc4 Mon Sep 17 00:00:00 2001
> +From: Patrick McCarty <patrick.mccarty@intel.com>
> +Date: Mon, 22 Feb 2016 22:07:08 -0800
> +Subject: [PATCH 2/4] Fix regression that introduced a directory named '/ '
> +
> +Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
> +
> +Upstream-Status: Backport (v3.0+)
> +
> +---
> + src/chroot.c | 2 +-
> + 1 file changed, 1 insertion(+), 1 deletion(-)
> +
> +diff --git a/src/chroot.c b/src/chroot.c
> +index f961d58..2878496 100644
> +--- a/src/chroot.c
> ++++ b/src/chroot.c
> +@@ -40,7 +40,7 @@ void chroot_create_full(int newversion)
> + 	char * command;
> + 	char *full_dir;
> +
> +-	string_or_die(&full_dir, "%s/%i/full/ ", image_dir, newversion);
> ++	string_or_die(&full_dir, "%s/%i/full/", image_dir, newversion);
> +
> + 	g_mkdir_with_parents(full_dir, S_IRWXU);
> +
> +--
> +2.5.0
> +
> diff --git a/meta/recipes-devtools/swupd/swupd-server_2.53.bb b/meta/recipes-devtools/swupd/swupd-server_2.53.bb
> new file mode 100644
> index 0000000..fdbd39b
> --- /dev/null
> +++ b/meta/recipes-devtools/swupd/swupd-server_2.53.bb
> @@ -0,0 +1,33 @@
> +SUMMARY = "swupd sofware update from Clear Linux - server component"
> +LICENSE = "GPL-2.0"
> +LIC_FILES_CHKSUM = "file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
> +                    file://bsdiff/LICENSE;md5=0dbe7a50f028269750631fcbded3846a"
> +
> +DEPENDS = "file xz glib-2.0 zlib bzip2 tar rsync openssl"
> +
> +SRC_URI = "\
> +    https://download.clearlinux.org/releases/5940/clear/source/SRPMS/${BPN}-${PV}-4.src.rpm;extract=${BP}.tar.gz \

I'm going throught he patches in reverse order, but IIRC you used
release 5700 for swupd-client, here it's release 5940. Is there a chance
that client and server might be out of sync?


> +    file://0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch \
> +    file://0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch \
> +    file://0002-Add-configure-option-to-re-enable-config-files-in-ma.patch \
> +    file://0002-Fix-regression-that-introduced-a-directory-named.patch \
> +"
> +
> +SRC_URI[md5sum] = "14f25677b5a4f0b33785910b03860939"
> +SRC_URI[sha256sum] = "c2d0e595444fe198c4092dd83d20a929fd1402a13b66b410b76677ed3a993d99"
> +
> +inherit autotools
> +
> +EXTRA_OECONF = "--enable-bzip2 --enable-lzma --disable-stateless"
> +
> +# safer-calls-to-system-utilities.patch uses for loop initial declaration
> +CFLAGS_append = " -std=c99"
> +
> +do_install_append () {
> +    mkdir -p ${D}${sysconfdir}/swupd-certs
> +    install -m 0755 ${S}/test/signature/* ${D}${sysconfdir}/swupd-certs/
> +}
> +
> +RDEPENDS_${PN} = "tar rsync"
> +
> +BBCLASSEXTEND = "native"



--
Maciej Borzęcki
Senior Software Developer at Open-RnD Sp. z o.o., Poland
www.open-rnd.pl
mobile: +48 889 117 365, fax: +48 42 657 9079


Niniejsza wiadomość wraz z załącznikami może
zawierać chronione prawem lub poufne informacje i została
wysłana wyłącznie do wiadomości i użytku osób, do których
została zaadresowana. Jeśli wiadomość została otrzymana
przypadkowo zabrania się jej kopiowania lub rozsyłania do osób
trzecich. W takim przypadku uprasza się o natychmiastowe
zniszczenie wiadomości oraz poinformowanie nadawcy o
zaistniałej sytuacji za pomocą wiadomości zwrotnej.
Dziękujemy.

This message, including any attachments hereto,
may contain privileged or confidential information and is sent
solely for the attention and use of the intended addressee(s).
If you are not an intended addressee, you may neither use this
message nor copy or deliver it to anyone. In such case, you
should immediately destroy this message and kindly notify the
sender by reply email. Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
  2016-02-24 14:52 ` [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image Joshua Lock
@ 2016-02-25  8:19   ` Maciej Borzecki
  2016-02-25  8:47     ` Joshua G Lock
  2016-02-25 17:06   ` Patrick Ohly
  1 sibling, 1 reply; 35+ messages in thread
From: Maciej Borzecki @ 2016-02-25  8:19 UTC (permalink / raw)
  To: Joshua Lock; +Cc: openembedded-core

On 02/24 14:52, Joshua Lock wrote:
> Our initial strategy to generate bundles for consumption by swupd
> is to generate images which contain the base image (os-core) plus
> the additional contents of the bundle, then prune out the core
> contents. By generating images in this manner we hope to accomodate
> packages which modify the rootfs outside of installing files, i.e.
> with postinsts.
>
> To that end this class, to be used via BBCLASSEXTEND, will generate
> virtual image recipes that add extra packages to the extended
> image.
>
> Only extensions matching entries in a SWUPD_BUNDLES variable are
> valid and the bundle contents should be listed in a varFlag
> matching the bundle's name on the BUNDLE_CONTENTS variable.
>
> An example of usage in an image recipe follows:
>
> SWUPD_BUNDLES = "foo bar"
> BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
> BUNDLE_CONTENTS[bar] = "bar baz quux"
>
> BBCLASSEXTEND = "swupdbundle:foo"
>
> Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> ---
>  meta/classes/swupdbundle.bbclass | 59 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
>  create mode 100644 meta/classes/swupdbundle.bbclass
>
> diff --git a/meta/classes/swupdbundle.bbclass b/meta/classes/swupdbundle.bbclass
> new file mode 100644
> index 0000000..897666d
> --- /dev/null
> +++ b/meta/classes/swupdbundle.bbclass
> @@ -0,0 +1,59 @@
> +# Our initial strategy to generate bundles for consumption by swupd is to
> +# generate images which contain the base image (os-core) plus the additional
> +# contents of the bundle, then prune out the core contents. By generating
> +# images in this manner we hope to accomodate packages which modify the rootfs
> +# outside of installing files, i.e.with postinsts.
> +#
> +# To that end this class, to be used via BBCLASSEXTEND, will generate virtual
> +# image recipes that add extra packages to the extended image.
> +#
> +# Only extensions matching entries in a SWUPD_BUNDLES variable are valid and
> +# the bundle contents should be listed in a varFlag matching the bundle's name
> +# on the BUNDLE_CONTENTS variable. i.e in foo-image.bb:
> +#
> +# SWUPD_BUNDLES = "foo bar"
> +# BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
> +# BUNDLE_CONTENTS[bar] = "bar baz quux"
> +# BBCLASSEXTEND = "swupdbundle:foo"
> +
> +python swupdbundle_virtclass_handler () {
> +    pn = e.data.getVar("PN", True)
> +    cls = e.data.getVar("BBEXTENDCURR", True)
> +    bundle = e.data.getVar("BBEXTENDVARIANT", True)
> +
> +    if cls != 'swupdbundle':
> +        return
> +
> +    if not bundle:
> +        bb.fatal('swupdbundle must be used with a parameter i.e. BBCLASSEXTEND="swupdbundle:foo"')
> +
> +    # Rename the virtual recipe to create the desired image bundle variant.
> +    e.data.setVar("PN_BASE", pn)
> +    pn = pn + '-' + bundle
> +    e.data.setVar("PN", pn)
> +    e.data.setVar("BUNDLE_NAME", bundle)
> +
> +    bundles = (e.data.getVar('SWUPD_BUNDLES', True) or "").split()
> +    if not bundles:
> +        bb.fatal('SWUPD_BUNDLES is not defined, this variable should list bundles for the image.')
> +
> +    curr_install = (e.data.getVar('IMAGE_INSTALL', True) or "").split()
> +
> +    def get_bundle_contents(bndl):
> +        contents = e.data.getVarFlag('BUNDLE_CONTENTS', bndl, True)
> +        if contents:
> +            return contents.split()
> +        else:
> +            bb.fatal('BUNDLE_CONTENTS[%s] is not set, this should list the packages to be included in the bundle.' % bndl)
> +
> +    if bundle == 'mega':
> +        for bndl in bundles:
> +            curr_install += get_bundle_contents(bndl)

Bundle named 'mega' seems to be very specific (a bundle of bundles) but
is not documented as a reserved name.

> +    else:
> +        curr_install += get_bundle_contents(bundle)
> +
> +    e.data.setVar('IMAGE_INSTALL', ' '.join(curr_install))
> +}
> +
> +addhandler swupdbundle_virtclass_handler
> +swupdbundle_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise"
> --
> 2.5.0
>
> --
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.openembedded.org/mailman/listinfo/openembedded-core

--
Maciej Borzęcki
Senior Software Developer at Open-RnD Sp. z o.o., Poland


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
  2016-02-25  8:19   ` Maciej Borzecki
@ 2016-02-25  8:47     ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25  8:47 UTC (permalink / raw)
  To: Maciej Borzecki; +Cc: openembedded-core

On Thu, 2016-02-25 at 09:19 +0100, Maciej Borzecki wrote:
> On 02/24 14:52, Joshua Lock wrote:
> > 
> > Our initial strategy to generate bundles for consumption by swupd
> > is to generate images which contain the base image (os-core) plus
> > the additional contents of the bundle, then prune out the core
> > contents. By generating images in this manner we hope to accomodate
> > packages which modify the rootfs outside of installing files, i.e.
> > with postinsts.
> > 
> > To that end this class, to be used via BBCLASSEXTEND, will generate
> > virtual image recipes that add extra packages to the extended
> > image.
> > 
> > Only extensions matching entries in a SWUPD_BUNDLES variable are
> > valid and the bundle contents should be listed in a varFlag
> > matching the bundle's name on the BUNDLE_CONTENTS variable.
> > 
> > An example of usage in an image recipe follows:
> > 
> > SWUPD_BUNDLES = "foo bar"
> > BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
> > BUNDLE_CONTENTS[bar] = "bar baz quux"
> > 
> > BBCLASSEXTEND = "swupdbundle:foo"
> > 
> > Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> > ---
> >  meta/classes/swupdbundle.bbclass | 59
> > ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 59 insertions(+)
> >  create mode 100644 meta/classes/swupdbundle.bbclass
> > 
> > diff --git a/meta/classes/swupdbundle.bbclass
> > b/meta/classes/swupdbundle.bbclass
> > new file mode 100644
> > index 0000000..897666d
> > --- /dev/null
> > +++ b/meta/classes/swupdbundle.bbclass
> > @@ -0,0 +1,59 @@
> > +# Our initial strategy to generate bundles for consumption by
> > swupd is to
> > +# generate images which contain the base image (os-core) plus the
> > additional
> > +# contents of the bundle, then prune out the core contents. By
> > generating
> > +# images in this manner we hope to accomodate packages which
> > modify the rootfs
> > +# outside of installing files, i.e.with postinsts.
> > +#
> > +# To that end this class, to be used via BBCLASSEXTEND, will
> > generate virtual
> > +# image recipes that add extra packages to the extended image.
> > +#
> > +# Only extensions matching entries in a SWUPD_BUNDLES variable are
> > valid and
> > +# the bundle contents should be listed in a varFlag matching the
> > bundle's name
> > +# on the BUNDLE_CONTENTS variable. i.e in foo-image.bb:
> > +#
> > +# SWUPD_BUNDLES = "foo bar"
> > +# BUNDLE_CONTENTS[foo] = "foo foo-bar foobaz"
> > +# BUNDLE_CONTENTS[bar] = "bar baz quux"
> > +# BBCLASSEXTEND = "swupdbundle:foo"
> > +
> > +python swupdbundle_virtclass_handler () {
> > +    pn = e.data.getVar("PN", True)
> > +    cls = e.data.getVar("BBEXTENDCURR", True)
> > +    bundle = e.data.getVar("BBEXTENDVARIANT", True)
> > +
> > +    if cls != 'swupdbundle':
> > +        return
> > +
> > +    if not bundle:
> > +        bb.fatal('swupdbundle must be used with a parameter i.e.
> > BBCLASSEXTEND="swupdbundle:foo"')
> > +
> > +    # Rename the virtual recipe to create the desired image bundle
> > variant.
> > +    e.data.setVar("PN_BASE", pn)
> > +    pn = pn + '-' + bundle
> > +    e.data.setVar("PN", pn)
> > +    e.data.setVar("BUNDLE_NAME", bundle)
> > +
> > +    bundles = (e.data.getVar('SWUPD_BUNDLES', True) or "").split()
> > +    if not bundles:
> > +        bb.fatal('SWUPD_BUNDLES is not defined, this variable
> > should list bundles for the image.')
> > +
> > +    curr_install = (e.data.getVar('IMAGE_INSTALL', True) or
> > "").split()
> > +
> > +    def get_bundle_contents(bndl):
> > +        contents = e.data.getVarFlag('BUNDLE_CONTENTS', bndl,
> > True)
> > +        if contents:
> > +            return contents.split()
> > +        else:
> > +            bb.fatal('BUNDLE_CONTENTS[%s] is not set, this should
> > list the packages to be included in the bundle.' % bndl)
> > +
> > +    if bundle == 'mega':
> > +        for bndl in bundles:
> > +            curr_install += get_bundle_contents(bndl)
> Bundle named 'mega' seems to be very specific (a bundle of bundles)
> but
> is not documented as a reserved name.

Good point, I'll be sure to document that. I'll also add some code to
raise an error if one of SWUPD_BUNDLES (user-defined bundles) is mega.

Thanks for the review.

Regards,

Joshua

> > 
> > +    else:
> > +        curr_install += get_bundle_contents(bundle)
> > +
> > +    e.data.setVar('IMAGE_INSTALL', ' '.join(curr_install))
> > +}
> > +
> > +addhandler swupdbundle_virtclass_handler
> > +swupdbundle_virtclass_handler[eventmask] =
> > "bb.event.RecipePreFinalise"
> > --
> > 2.5.0
> > 
> > --
> > _______________________________________________
> > Openembedded-core mailing list
> > Openembedded-core@lists.openembedded.org
> > http://lists.openembedded.org/mailman/listinfo/openembedded-core
> --
> Maciej Borzęcki
> Senior Software Developer at Open-RnD Sp. z o.o., Poland


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-24 22:57   ` Andre McCurdy
@ 2016-02-25  8:48     ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25  8:48 UTC (permalink / raw)
  To: Andre McCurdy; +Cc: OE Core mailing list

On Wed, 2016-02-24 at 14:57 -0800, Andre McCurdy wrote:
> On Wed, Feb 24, 2016 at 6:52 AM, Joshua Lock <joshua.g.lock@intel.com
> > wrote:
> > 
> > ---
> >  meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19
> > +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >  create mode 100644 meta/recipes-
> > extended/hardlink/hardlink_0.3.0.bb
> > 
> > diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > new file mode 100644
> > index 0000000..2e06ac2
> > --- /dev/null
> > +++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > @@ -0,0 +1,19 @@
> > +SUMMARY = "hardlink is a tool which replaces multiple copies of a
> > file with hardlinks."
> > +LICENSE = "MIT"
> > +LIC_FILES_CHKSUM =
> > "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
> > +
> > +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar
> > .xz"
> > +SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
> > +SRC_URI[sha256sum] =
> > "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
> > +
> > +DEPENDS = "libpcre attr"
> According to the style guide, DEPENDS should come between
> LIC_FILES_CHKSUM and SRC_URI.

Good catch, I'll re-order.

Thanks,

Joshua



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 04/10] swupd-client: Add recipe
  2016-02-25  8:07   ` Maciej Borzecki
@ 2016-02-25  8:50     ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25  8:50 UTC (permalink / raw)
  To: Maciej Borzecki; +Cc: openembedded-core

On Thu, 2016-02-25 at 09:07 +0100, Maciej Borzecki wrote:
> On 02/24 14:52, Joshua Lock wrote:
> > 
> > From: Mariano Lopez <mariano.lopez@linux.intel.com>
> > 
> > This commit adds the Clear Linux client updater.
> > This is experimental and bleeding edge, including the comments on
> > the recipe.
> > 
> > Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
> > Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
> > ---
> >  .../0001-Tolerate-quotes-in-os-release-files.patch | 59
> > ++++++++++++++++++++++
> >  ...hange-systemctl-path-to-OE-systemctl-path.patch | 31
> > ++++++++++++
> >  .../swupd-client/Fix-build-failure-on-Yocto.patch  | 36
> > +++++++++++++
> >  .../Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch    | 38
> > ++++++++++++++
> >  meta/recipes-devtools/swupd/swupd-client_2.87.bb   | 49
> > ++++++++++++++++++
> >  5 files changed, 213 insertions(+)
> >  create mode 100644 meta/recipes-devtools/swupd/swupd-client/0001-
> > Tolerate-quotes-in-os-release-files.patch
> >  create mode 100644 meta/recipes-devtools/swupd/swupd-
> > client/Change-systemctl-path-to-OE-systemctl-path.patch
> >  create mode 100644 meta/recipes-devtools/swupd/swupd-client/Fix-
> > build-failure-on-Yocto.patch
> >  create mode 100644 meta/recipes-devtools/swupd/swupd-client/Right-
> > usage-of-AC_ARG_ENABLE-on-bzip2.patch
> >  create mode 100644 meta/recipes-devtools/swupd/swupd-
> > client_2.87.bb
> > 
> > diff --git a/meta/recipes-devtools/swupd/swupd-client/0001-
> > Tolerate-quotes-in-os-release-files.patch b/meta/recipes-
> > devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-
> > files.patch
> > new file mode 100644
> > index 0000000..49c71ae
> > --- /dev/null
> > +++ b/meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-
> > quotes-in-os-release-files.patch
> > @@ -0,0 +1,59 @@
> > +From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:00
> > 2001
> > +From: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> > +Date: Thu, 11 Feb 2016 13:29:57 +0200
> > +Subject: [PATCH 1/2] Tolerate quotes in os-release files
> > +
> > +Some systems like Yocto or OpenSUSE prefer to wrap values in
> > +/etc/os-release file with quotes always and that still conforms
> > +to the format defined in systemd.
> > +
> > +This patch removes quotes from the values before trying to
> > +transform them into integer version id.
> > +
> > +Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@intel.com>
> > +
> > +Upstream-Status: Backport (v3.0.0+)
> > +
> > +---
> > + src/version.c | 18 +++++++++++++++++-
> > + 1 file changed, 17 insertions(+), 1 deletion(-)
> > +
> > +diff --git a/src/version.c b/src/version.c
> > +index 0e09cd9..83d6ad4 100644
> > +--- a/src/version.c
> > ++++ b/src/version.c
> > +@@ -88,6 +88,7 @@ int read_version_from_subvol_file(char
> > *path_prefix)
> > + 	FILE *file;
> > + 	int v = -1;
> > + 	char *buildstamp;
> > ++	char *src, *dest;
> > +
> > + 	string_or_die(&buildstamp, "%s/usr/lib/os-release",
> > path_prefix);
> > + 	file = fopen(buildstamp, "rm");
> > +@@ -106,7 +107,22 @@ int read_version_from_subvol_file(char
> > *path_prefix)
> > + 			break;
> > + 		}
> > +
> > +-		if (strncmp(line,"VERSION_ID=", 11) == 0) {
> > ++		if (strncmp(line, "VERSION_ID=", 11) == 0) {
> > ++			src = &line[11];
> > ++
> > ++			/* Drop quotes and newline in value */
> > ++			dest = src;
> > ++			while (*src) {
> > ++				if (*src == '\'' || *src == '"'
> > || *src == '\n') {
> > ++					++src;
> > ++				} else {
> > ++					*dest = *src;
> > ++					++dest;
> > ++					++src;
> > ++				}
> > ++			}
> > ++			*dest = 0;
> > ++
> > + 			v = strtoull(&line[11], NULL, 10);
> > + 			break;
> > + 		}
> > +--
> > +2.5.0
> > +
> > diff --git a/meta/recipes-devtools/swupd/swupd-client/Change-
> > systemctl-path-to-OE-systemctl-path.patch b/meta/recipes-
> > devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-
> > path.patch
> > new file mode 100644
> > index 0000000..5ca6373
> > --- /dev/null
> > +++ b/meta/recipes-devtools/swupd/swupd-client/Change-systemctl-
> > path-to-OE-systemctl-path.patch
> > @@ -0,0 +1,31 @@
> > +From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:00
> > 2001
> > +From: Jaska Uimonen <jaska.uimonen@intel.com>
> > +Date: Thu, 14 Jan 2016 10:17:43 +0200
> > +Subject: [PATCH] change systemctl path to OE systemctl path
> > +
> > +Upstream-Status: Inappropriate
> > +
> > +---
> > + src/scripts.c | 4 ++--
> > + 1 file changed, 2 insertions(+), 2 deletions(-)
> > +
> > +diff --git a/src/scripts.c b/src/scripts.c
> > +index e426272..9bec0f5 100644
> > +--- a/src/scripts.c
> > ++++ b/src/scripts.c
> > +@@ -84,10 +84,10 @@ static void update_triggers(void)
> > + 	int ret;
> > + 	LOG_INFO(NULL, "calling systemd trigger", class_scripts,
> > "");
> > +
> > +-	ret = system("/usr/bin/systemctl daemon-reload");
> > ++	ret = system("/bin/systemctl daemon-reload");
> > + 	if (ret != 0)
> > + 		LOG_ERROR(NULL, "systemd daemon reload failed",
> > class_scripts, "%d", ret);
> > +-	ret = system("/usr/bin/systemctl restart update-
> > triggers.target");
> > ++	ret = system("/bin/systemctl restart update-
> > triggers.target");
> > + 	if (ret != 0)
> > + 		LOG_ERROR(NULL, "systemd update triggers failed",
> > class_scripts, "%d", ret);
> > + }
> > +--
> > +2.5.0
> > +
> > diff --git a/meta/recipes-devtools/swupd/swupd-client/Fix-build-
> > failure-on-Yocto.patch b/meta/recipes-devtools/swupd/swupd-
> > client/Fix-build-failure-on-Yocto.patch
> > new file mode 100644
> > index 0000000..73f1728
> > --- /dev/null
> > +++ b/meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-
> > on-Yocto.patch
> > @@ -0,0 +1,36 @@
> > +From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:00
> > 2001
> > +From: Amarnath Valluri <amarnath.valluri@intel.com>
> > +Date: Thu, 7 Jan 2016 16:19:34 +0200
> > +Subject: [PATCH] Fix build failure on Yocto
> > +
> > +On install phase certificate files are being installed twice as
> > included in
> > +_DATA twice. We can use EXTRA_DIST than dist_.
> > +
> > +Upstream-Status: Inappropriate
> > +
> > +Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
> > +---
> > + Makefile.am | 4 ++--
> > + 1 file changed, 2 insertions(+), 2 deletions(-)
> > +
> > +diff --git a/Makefile.am b/Makefile.am
> > +index 1e65d3d..4d15c55 100644
> > +--- a/Makefile.am
> > ++++ b/Makefile.am
> > +@@ -111,11 +111,11 @@ SWUPD_CERTS = certs/157753a5.0 \
> > + 	certs/d6325660.0 \
> > + 	certs/d6325660.1
> > + swupdcerts_DATA = $(SWUPD_CERTS)
> > +-dist_swupdcerts_DATA = $(SWUPD_CERTS)
> > +
> > + EXTRA_DIST += \
> > + 	data/check-update.service \
> > +-	data/check-update.timer
> > ++	data/check-update.timer \
> > ++	$(SWUPD_CERTS)
> > +
> > + DISTCHECK_CONFIGURE_FLAGS = \
> > +         --with-
> > systemdsystemunitdir=$$dc_install_base/$(systemdunitdir)
> > +--
> > +2.1.4
> > +
> > diff --git a/meta/recipes-devtools/swupd/swupd-client/Right-usage-
> > of-AC_ARG_ENABLE-on-bzip2.patch b/meta/recipes-
> > devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-
> > bzip2.patch
> > new file mode 100644
> > index 0000000..e5b53ef
> > --- /dev/null
> > +++ b/meta/recipes-devtools/swupd/swupd-client/Right-usage-of-
> > AC_ARG_ENABLE-on-bzip2.patch
> > @@ -0,0 +1,38 @@
> > +From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:00
> > 2001
> > +From: Amarnath Valluri <amarnath.valluri@intel.com>
> > +Date: Wed, 13 Jan 2016 15:46:19 +0200
> > +Subject: [PATCH] Right usage of AC_ARG_ENABLE on bzip2
> > +
> > +Upstream-Status: Pending[Not submitted]
> > +
> > +Signed-off-by: Amarnath Valluri <amarnath.valluri@intel.com>
> > +---
> > + configure.ac | 12 +++++++-----
> > + 1 file changed, 7 insertions(+), 5 deletions(-)
> > +
> > +diff --git a/configure.ac b/configure.ac
> > +index f94a17d..b11ef0a 100644
> > +--- a/configure.ac
> > ++++ b/configure.ac
> > +@@ -20,11 +20,13 @@ AC_CONFIG_HEADERS([config.h])
> > + PKG_CHECK_MODULES([lzma], [liblzma])
> > + PKG_CHECK_MODULES([zlib], [zlib])
> > + AC_ARG_ENABLE(
> > +-	bzip2,
> > +-	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2
> > compression (uses bzip2 by default)]),
> > +-	AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2
> > compression]) ,
> > +-	AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
> > +-	AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [],
> > [AC_MSG_ERROR([the libbz2 library is missing])])
> > ++	[bzip2],
> > ++	AS_HELP_STRING([--disable-bzip2],[Do not use bzip2
> > compression (uses bzip2 by default)])
> > ++)
> > ++AS_IF([test "x$enable_bzip2" = "xyes" ],
> > ++  [AC_DEFINE(SWUPD_WITH_BZIP2,1,[Use bzip2 compression])
> > ++	 AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [],
> > [AC_MSG_ERROR([the libbz2 library is missing])])],
> > ++  [AC_DEFINE(SWUPD_WITHOUT_BZIP2,1,[Do not use bzip2
> > compression])]
> > + )
> > +
> > + AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-
> > systemdsystemunitdir=DIR],
> > +--
> > +2.1.4
> > +
> > diff --git a/meta/recipes-devtools/swupd/swupd-client_2.87.bb
> > b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
> > new file mode 100644
> > index 0000000..a5afdd6
> > --- /dev/null
> > +++ b/meta/recipes-devtools/swupd/swupd-client_2.87.bb
> > @@ -0,0 +1,49 @@
> > +SUMMARY = "swupd sofware update from Clear Linux - client
> > component"
> > +LICENSE = "GPL-2.0"
> > +LIC_FILES_CHKSUM =
> > "file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
> > +                    file://bsdiff/LICENSE;md5=0dbe7a50f02826975063
> > 1fcbded3846a"
> > +
> > +SRC_URI = "\
> > +    https://download.clearlinux.org/releases/5700/clear/source/SRP
> > MS/${BPN}-${PV}-105.src.rpm;extract=${BP}.tar.gz \
> > +    file://Fix-build-failure-on-Yocto.patch \
> > +    file://Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch \
> > +    file://Change-systemctl-path-to-OE-systemctl-path.patch \
> > +    file://0001-Tolerate-quotes-in-os-release-files.patch \
> > +"
> > +
> > +SRC_URI[md5sum] = "5d272c62edb8a9c576005ac5e1182ea3"
> > +SRC_URI[sha256sum] =
> > "45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1c66fb8"
> > +
> > +DEPENDS = "glib-2.0 curl zlib bzip2 xz openssl"
> > +RDEPENDS_${PN} = "gzip bzip2 tar xz"
> > +# swupd requires at least an update-triggers target, should it be
> > part of the
> > +# swupd-client package?
> > +RDEPENDS_${PN} = "swupd-units"
> > +# We check /etc/os-release for the current OS version number
> > +RRECOMMENDS_${PN} = "os-release"
> > +
> > +inherit pkgconfig autotools-brokensep systemd
> > +
> > +EXTRA_OECONF = "--with-
> > systemdsystemunitdir=${systemd_system_unitdir}"
> > +
> > +#TODO: create and install /var/lib/swupd/{delta,staged/download}
> > +do_install_append () {
> > +    # swupd-client 2.87 doesn't (succesfully) create these and
> > fails to update
> > +    # should they not exist. This is due to a bash-specific shell
> > command
> > +    # called to create the directories 'mkdir -p
> > /var/lib/{delta,staged,download}'
> > +    install -d ${D}/var/lib/swupd/delta
> > +    install -d ${D}/var/lib/swupd/download
> > +    install -d ${D}/var/lib/swupd/staged
> > +
> > +    # TODO: This should be a less os-specific directory and not
> > hard-code datadir
> > +    install -d ${D}/usr/share/clear/bundles
> > +}
> > +
> > +FILES_${PN} += "\
> > +    /usr/share/clear \
> > +    ${systemd_system_unitdir}/multi-user.target.wants* \
> > +    /var/lib/swupd \
> Try using ${datadir} and ${localstatedir} if possible:
>     ${datadir}/clear
>     ${localstatedir}/lib//swupd
>     install -d ${D}${datadir}/clear/bundles

Unfortunately swupd hard-codes various paths including these, if we use
the variables and the distro has defined those differently than what
swupd expects this will fail. 

I do intend to fix swupd-client to take these paths as arguments and
will switch to the variables then.

Until that's done I will add a comment above FILES_${PN}.

Regards,

Joshua


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 02/10] swupd-server: initial recipe 2.53
  2016-02-25  8:11   ` Maciej Borzecki
@ 2016-02-25  8:51     ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25  8:51 UTC (permalink / raw)
  To: Maciej Borzecki; +Cc: openembedded-core

On Thu, 2016-02-25 at 09:11 +0100, Maciej Borzecki wrote:
> On 02/24 14:52, Joshua Lock wrote:
> > +SRC_URI = "\
> > +    https://download.clearlinux.org/releases/5940/clear/source/SRP
> > MS/${BPN}-${PV}-4.src.rpm;extract=${BP}.tar.gz \
> I'm going throught he patches in reverse order, but IIRC you used
> release 5700 for swupd-client, here it's release 5940. Is there a
> chance
> that client and server might be out of sync?

Well spotted! This combination do work together, both from my own
testing and that of colleagues using swupd, but I would like to sync up
on the same version soon.

Regards,

Joshua



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
  2016-02-24 14:52 ` [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image Joshua Lock
  2016-02-25  8:19   ` Maciej Borzecki
@ 2016-02-25 17:06   ` Patrick Ohly
  2016-03-01 13:45     ` Joshua G Lock
  1 sibling, 1 reply; 35+ messages in thread
From: Patrick Ohly @ 2016-02-25 17:06 UTC (permalink / raw)
  To: Joshua Lock; +Cc: openembedded-core

On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> Our initial strategy to generate bundles for consumption by swupd
> is to generate images which contain the base image (os-core) plus
> the additional contents of the bundle, then prune out the core
> contents. By generating images in this manner we hope to accomodate
> packages which modify the rootfs outside of installing files, i.e.
> with postinsts.
> 
> To that end this class, to be used via BBCLASSEXTEND, will generate
> virtual image recipes that add extra packages to the extended
> image.

Can this be combined with an image recipe which itself uses
BBCLASSEXTEND to generate virtual image recipes, i.e. create a virtual
recipes based on a virtual recipe?

I don't remember whether I ever posted the class here; what it does is
add or remove image features in the virtual image variants based on
BBCLASSEXTEND parameters.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.





^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
  2016-02-24 21:00   ` Burton, Ross
  2016-02-24 22:57   ` Andre McCurdy
@ 2016-02-25 17:13   ` Mark Hatle
  2016-02-25 21:40     ` Joshua G Lock
  2 siblings, 1 reply; 35+ messages in thread
From: Mark Hatle @ 2016-02-25 17:13 UTC (permalink / raw)
  To: Joshua Lock, openembedded-core

I just noticed this, any reason to use this over fdupes?

I've used fdupes in the past for this exact thing -- primarily with shrinking
the size of multilib SDKs with a lot of locales.

--Mark

On 2/24/16 8:52 AM, Joshua Lock wrote:
> ---
>  meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> 
> diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> new file mode 100644
> index 0000000..2e06ac2
> --- /dev/null
> +++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> @@ -0,0 +1,19 @@
> +SUMMARY = "hardlink is a tool which replaces multiple copies of a file with hardlinks."
> +LICENSE = "MIT"
> +LIC_FILES_CHKSUM = "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
> +
> +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar.xz"
> +SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
> +SRC_URI[sha256sum] = "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
> +
> +DEPENDS = "libpcre attr"
> +
> +do_compile () {
> +	oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
> +}
> +
> +do_install () {
> +	oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}' BINDIR='${bindir}'
> +}
> +
> +BBCLASSEXTEND = "native nativesdk"
> 



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-25 17:13   ` Mark Hatle
@ 2016-02-25 21:40     ` Joshua G Lock
  2016-02-25 21:57       ` Mark Hatle
  0 siblings, 1 reply; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25 21:40 UTC (permalink / raw)
  To: Mark Hatle, openembedded-core

On Thu, 2016-02-25 at 11:13 -0600, Mark Hatle wrote:
> I just noticed this, any reason to use this over fdupes?

No reason other than that hardlink is what the Clear Linux team, who
authored swupd, are using. Is there a compelling reason to look at
fdupes instead?

Thanks,

Joshua

> 
> I've used fdupes in the past for this exact thing -- primarily with
> shrinking
> the size of multilib SDKs with a lot of locales.
> 
> --Mark
> 
> On 2/24/16 8:52 AM, Joshua Lock wrote:
> > 
> > ---
> >  meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19
> > +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >  create mode 100644 meta/recipes-
> > extended/hardlink/hardlink_0.3.0.bb
> > 
> > diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > new file mode 100644
> > index 0000000..2e06ac2
> > --- /dev/null
> > +++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
> > @@ -0,0 +1,19 @@
> > +SUMMARY = "hardlink is a tool which replaces multiple copies of a
> > file with hardlinks."
> > +LICENSE = "MIT"
> > +LIC_FILES_CHKSUM =
> > "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
> > +
> > +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar
> > .xz"
> > +SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
> > +SRC_URI[sha256sum] =
> > "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
> > +
> > +DEPENDS = "libpcre attr"
> > +
> > +do_compile () {
> > +	oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}'
> > BINDIR='${bindir}'
> > +}
> > +
> > +do_install () {
> > +	oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}'
> > BINDIR='${bindir}'
> > +}
> > +
> > +BBCLASSEXTEND = "native nativesdk"
> > 


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 20:40       ` Philip Balister
@ 2016-02-25 21:42         ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-02-25 21:42 UTC (permalink / raw)
  To: Philip Balister, Paul Eggleton, openembedded-core

On Wed, 2016-02-24 at 15:40 -0500, Philip Balister wrote:
> On 02/24/2016 02:51 PM, Paul Eggleton wrote:
> > 
> > On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
> > > 
> > > On 02/24/2016 11:06 AM, Trevor Woerner wrote:
> > > > 
> > > > Ideally the work done here and the work done on meta-
> > > > swupdate[1] would
> > > > be somehow merged so people creating images/distros would only
> > > > have to
> > > > learn and integrate one software update solution, instead of
> > > > having to
> > > > evaluate and choose between the two (or more?).
> > > > 
> > > > [1] https://github.com/sbabic/meta-swupdate
> > > Amen. I had the same thoughts reading the patch set intro.
> > I think it would be hard to integrate these two, since they operate
> > quite 
> > differently to eachother.
> >  
> > > 
> > > Maybe the swupd should go in a seperate layer so we can see which
> > > project works best for oe users before moving something directly
> > > into
> > > oe-core?
> > This makes sense to me too though FWIW. The os-release patch should
> > probably 
> > go straight in, but everything else looks like it could comfortably
> > live in a 
> > separate layer without making things too difficult.
> It also makes it easier to update as problems in swupd are resolved
> since you do not need to go through the entire oe-core testing cycle.

I've pushed the series, including a couple of metadata fixes suggested
in reply, as a layer here: http://git.yoctoproject.org/cgit/cgit.cgi/me
ta-swupd/

Regards,

Joshua


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/10] hardlink: add new recipe
  2016-02-25 21:40     ` Joshua G Lock
@ 2016-02-25 21:57       ` Mark Hatle
  0 siblings, 0 replies; 35+ messages in thread
From: Mark Hatle @ 2016-02-25 21:57 UTC (permalink / raw)
  To: Joshua G Lock, openembedded-core

On 2/25/16 3:40 PM, Joshua G Lock wrote:
> On Thu, 2016-02-25 at 11:13 -0600, Mark Hatle wrote:
>> I just noticed this, any reason to use this over fdupes?
> 
> No reason other than that hardlink is what the Clear Linux team, who
> authored swupd, are using. Is there a compelling reason to look at
> fdupes instead?

I'd used fdupes since someone else had already integrated it.  (meta-tizen
maybe?)  Also because it could do more then just setup duplicates as hardlinks.
 It can also simply display the duplicates for external processing.

I don't have any reason to prefer one over the other...

--Mark


> Thanks,
> 
> Joshua
> 
>>
>> I've used fdupes in the past for this exact thing -- primarily with
>> shrinking
>> the size of multilib SDKs with a lot of locales.
>>
>> --Mark
>>
>> On 2/24/16 8:52 AM, Joshua Lock wrote:
>>>
>>> ---
>>>  meta/recipes-extended/hardlink/hardlink_0.3.0.bb | 19
>>> +++++++++++++++++++
>>>  1 file changed, 19 insertions(+)
>>>  create mode 100644 meta/recipes-
>>> extended/hardlink/hardlink_0.3.0.bb
>>>
>>> diff --git a/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
>>> b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
>>> new file mode 100644
>>> index 0000000..2e06ac2
>>> --- /dev/null
>>> +++ b/meta/recipes-extended/hardlink/hardlink_0.3.0.bb
>>> @@ -0,0 +1,19 @@
>>> +SUMMARY = "hardlink is a tool which replaces multiple copies of a
>>> file with hardlinks."
>>> +LICENSE = "MIT"
>>> +LIC_FILES_CHKSUM =
>>> "file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
>>> +
>>> +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar
>>> .xz"
>>> +SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad"
>>> +SRC_URI[sha256sum] =
>>> "e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"
>>> +
>>> +DEPENDS = "libpcre attr"
>>> +
>>> +do_compile () {
>>> +	oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}'
>>> BINDIR='${bindir}'
>>> +}
>>> +
>>> +do_install () {
>>> +	oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}'
>>> BINDIR='${bindir}'
>>> +}
>>> +
>>> +BBCLASSEXTEND = "native nativesdk"
>>>



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
  2016-02-25 17:06   ` Patrick Ohly
@ 2016-03-01 13:45     ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-03-01 13:45 UTC (permalink / raw)
  To: Patrick Ohly; +Cc: openembedded-core

Hi Patrick,

Apologies for the delayed response.

On Thu, 2016-02-25 at 18:06 +0100, Patrick Ohly wrote:
> On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> > 
> > Our initial strategy to generate bundles for consumption by swupd
> > is to generate images which contain the base image (os-core) plus
> > the additional contents of the bundle, then prune out the core
> > contents. By generating images in this manner we hope to accomodate
> > packages which modify the rootfs outside of installing files, i.e.
> > with postinsts.
> > 
> > To that end this class, to be used via BBCLASSEXTEND, will generate
> > virtual image recipes that add extra packages to the extended
> > image.
> Can this be combined with an image recipe which itself uses
> BBCLASSEXTEND to generate virtual image recipes, i.e. create a
> virtual
> recipes based on a virtual recipe?

Currently this doesn't work, but I've just filed a bug to handle this
scenario: https://bugzilla.yoctoproject.org/show_bug.cgi?id=9192

Regards,

Joshua



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] Integrate swupd software updater
  2016-02-24 18:49     ` Patrick Ohly
@ 2016-03-01 16:18       ` Joshua G Lock
  0 siblings, 0 replies; 35+ messages in thread
From: Joshua G Lock @ 2016-03-01 16:18 UTC (permalink / raw)
  To: Patrick Ohly; +Cc: openembedded-core@lists.openembedded.org

On Wed, 2016-02-24 at 19:49 +0100, Patrick Ohly wrote:
> On Wed, 2016-02-24 at 16:09 +0000, Lock, Joshua G wrote:
> > 
> > On Wed, 2016-02-24 at 16:37 +0100, Patrick Ohly wrote:
> > > 
> > > Hello!
> > > 
> > > I haven't had a chance to play with the actual code yet and I
> > > don't
> > > know
> > > yet when I'll be able to. Let me ask for some clarifications
> > > about
> > > the
> > > approach first anyway.
> > > 
> > > On Wed, 2016-02-24 at 14:52 +0000, Joshua Lock wrote:
> > > > 
> > > > 
> > > > Approach:
> > > > An image that inherits the swupd-image bbclass will
> > > > automatically
> > > > have bundle
> > > > 'chroots' created which contain the filesystem contents of the
> > > > specified
> > > > bundles, with the contents of the inheriting image forming the
> > > > default os-core
> > > > bundle.
> > > > 
> > > > The mechanism to achieve this is that several virtual image
> > > > recipes
> > > > are created
> > > > using the swupdbundle class, one for each defined bundle plus a
> > > > 'mega' image
> > > > recipe. The 'mega' image contains the base image plus the
> > > > contents
> > > > of all of the
> > > > bundles, whilst bundle images contain only the base image plus
> > > > the
> > > > contents of a
> > > > single bundle.
> > > Just to be sure, the actual "content" (a term that is a bit too
> > > overloaded to be used precisely in all cases) of a file and its
> > > meta
> > > attributes will come from the mega image, and the virtual image
> > > recipes,
> > > including the base image, are merely used to generate file lists?
> > That's not currently true, no — the file contents for a bundle come
> > from the bundle image and the file contents for os-core come from
> > the
> > base image. It shouldn't be too difficult a change to make, I'll
> > take a
> > look now.
> The prime example that needs to be handled correctly is where
> installing
> additional packages for one of the extra bundles adds a system user
> to /etc/passwd (*). The content of /etc/passwd must come from the
> mega
> rootfs.

Indeed,  I'm working on that issue now and have filed a ticket to keep
track: https://bugzilla.yoctoproject.org/show_bug.cgi?id=9193

> (*) Except that swupd assumes that the distro is stateless and thus
> automatically excludes /etc from bundles. The example is still valid
> because preparing bundles does not need to care about that.

One of the patches I developed for swupd was to turn this into a
configure time option for swupd-server, see: 

http://git.yoctoproject.org/cgit/cgit.cgi/meta-swupd/tree/recipes-core/
swupd-server/swupd-server/0002-Add-configure-option-to-re-enable-
config-files-in-ma.patch

Regards,

Joshua


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2016-03-01 16:18 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-24 14:52 [PATCH 00/10] Integrate swupd software updater Joshua Lock
2016-02-24 14:52 ` [PATCH 01/10] rsync: add native variant Joshua Lock
2016-02-24 14:52 ` [PATCH 02/10] swupd-server: initial recipe 2.53 Joshua Lock
2016-02-25  8:11   ` Maciej Borzecki
2016-02-25  8:51     ` Joshua G Lock
2016-02-24 14:52 ` [PATCH 03/10] hardlink: add new recipe Joshua Lock
2016-02-24 21:00   ` Burton, Ross
2016-02-24 22:57   ` Andre McCurdy
2016-02-25  8:48     ` Joshua G Lock
2016-02-25 17:13   ` Mark Hatle
2016-02-25 21:40     ` Joshua G Lock
2016-02-25 21:57       ` Mark Hatle
2016-02-24 14:52 ` [PATCH 04/10] swupd-client: Add recipe Joshua Lock
2016-02-25  8:07   ` Maciej Borzecki
2016-02-25  8:50     ` Joshua G Lock
2016-02-24 14:52 ` [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image Joshua Lock
2016-02-25  8:19   ` Maciej Borzecki
2016-02-25  8:47     ` Joshua G Lock
2016-02-25 17:06   ` Patrick Ohly
2016-03-01 13:45     ` Joshua G Lock
2016-02-24 14:52 ` [PATCH 06/10] swupd-image.bbclass: initial class to support swupd updater Joshua Lock
2016-02-24 14:52 ` [PATCH 07/10] oe-swupd-helpers: provide swupd-client required helper scripts and units Joshua Lock
2016-02-24 14:52 ` [PATCH 08/10] swupd-client: RDEPENDS on oe-swupd-helpers Joshua Lock
2016-02-24 14:52 ` [PATCH 09/10] swupd-client: enable native builds Joshua Lock
2016-02-24 14:52 ` [PATCH 10/10] os-release: sanitise VERSION_ID field Joshua Lock
2016-02-24 15:37 ` [PATCH 00/10] Integrate swupd software updater Patrick Ohly
2016-02-24 16:14   ` Joshua G Lock
     [not found]   ` <1456330147.5333.14.camel@intel.com>
2016-02-24 18:49     ` Patrick Ohly
2016-03-01 16:18       ` Joshua G Lock
2016-02-24 16:06 ` Trevor Woerner
2016-02-24 16:35   ` Philip Balister
2016-02-24 18:36     ` Maciej Borzecki
2016-02-24 19:51     ` Paul Eggleton
2016-02-24 20:40       ` Philip Balister
2016-02-25 21:42         ` Joshua G Lock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox