Integrate swupd software updater
cover Integrate swupd software updater
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
PATCH 1/10 rsync: add native variant
--- meta/recipes-devtools/rsync/rsync_3.1.2.bb | 2 ++ 1 file changed, 2 insertions(+)
meta/recipes-devtools/rsync/rsync_3.1.2.bb +2 -0
@@ -26,3 +26,5 @@ do_configure_prepend () { do_configure_append () { cp -f ${S}/configure ${S}/configure.sh } + +BBCLASSEXTEND = "native"
Signature · 1 line
2.5.0
PATCH 2/10 swupd-server: initial recipe 2.53
In reply to Joshua LockInclude some patches to remove hard-coded state directory and backport some fixes.
--- ...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
meta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch new file +782 -0
@@ -0,0 +1,782 @@ +From 83fbb8a78594cf9047e37ed0aa1e931b9d691f2a Mon Sep 17 00:00:00 2001 +From: Joshua Lock <[email protected]> +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 <[email protected]> + +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 +
meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch new file +133 -0
133 lines not on this page · raw message
meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch new file +66 -0
66 lines not on this page · raw message
meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch new file +29 -0
@@ -0,0 +1,29 @@ +From aba4418696ef31ab5afc9811903a044366619dc4 Mon Sep 17 00:00:00 2001 +From: Patrick McCarty <[email protected]> +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 <[email protected]> + +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 +
meta/recipes-devtools/swupd/swupd-server_2.53.bb new file +33 -0
@@ -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"
Signature · 1 line
2.5.0
Re: [PATCH 02/10] swupd-server: initial recipe 2.53
Quoted 1,057 lines · Joshua Lock
Include some patches to remove hard-coded state directory and backport some fixes.
Signed-off-by Joshua Lock <[email protected]>--- ...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.bbmeta/recipes-devtools/swupd/swupd-server/0001-Add-option-S-to-take-the-state-data-dir-as-an-argume.patch new file +782
-0@@ -0,0 +1,782 @@ +From 83fbb8a78594cf9047e37ed0aa1e931b9d691f2a Mon Sep 17 00:00:00 2001 +From: Joshua Lock <[email protected]> +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 <[email protected]> + +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 +meta/recipes-devtools/swupd/swupd-server/0001-Add-system_argv-helper-for-safer-calls-to-system-uti.patch new file +133
-0@@ -0,0 +1,133 @@ +From 8f24ef7f857c9d2c2eb2601a2a1e06123c086001 Mon Sep 17 00:00:00 2001 +From: Dmitry Rozhkov <[email protected]> +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 <[email protected]> + +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 +meta/recipes-devtools/swupd/swupd-server/0002-Add-configure-option-to-re-enable-config-files-in-ma.patch new file +66
-0@@ -0,0 +1,66 @@ +From e209255d8985eb4eb4c43f5e773ee1a0a16eb297 Mon Sep 17 00:00:00 2001 +From: Joshua Lock <[email protected]> +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 <[email protected]> + +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 +meta/recipes-devtools/swupd/swupd-server/0002-Fix-regression-that-introduced-a-directory-named.patch new file +29
-0@@ -0,0 +1,29 @@ +From aba4418696ef31ab5afc9811903a044366619dc4 Mon Sep 17 00:00:00 2001 +From: Patrick McCarty <[email protected]> +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 <[email protected]> + +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 +meta/recipes-devtools/swupd/swupd-server_2.53.bb new file +0
-0
meta/recipes-devtools/swupd/swupd-server_2.53.bb line 9
Quoted 9 lines
meta/recipes-devtools/swupd/swupd-server_2.53.bb new file +9
-0@@ -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?
Quoted 14 lines
meta/recipes-devtools/swupd/swupd-server_2.53.bb new file +14
-0+ 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
meta/recipes-devtools/swupd/swupd-server_2.53.bb line 33
Quoted 10 lines
meta/recipes-devtools/swupd/swupd-server_2.53.bb new file +10
-0+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.
Re: [PATCH 02/10] swupd-server: initial recipe 2.53
Quoted 8 lines · Maciej Borzecki
Quoted 3 lines · Joshua Lock
+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
PATCH 3/10 hardlink: add new recipe
In reply to Joshua Lock--- 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
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +19 -0
@@ -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"
Signature · 1 line
2.5.0
Re: [PATCH 03/10] hardlink: add new recipe
Quoted 9 lines · Joshua Lock
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +6
-0+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
Re: [PATCH 03/10] hardlink: add new recipe
In reply to Joshua LockQuoted 11 lines · Joshua Lock
--- 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.bbmeta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +0
-0
meta/recipes-extended/hardlink/hardlink_0.3.0.bb line 9
Quoted 9 lines
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +9
-0@@ -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.
Quoted 17 lines
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +9
-1+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
[email protected]
http://lists.openembedded.org/mailman/listinfo/openembedded-core
Re: [PATCH 03/10] hardlink: add new recipe
Quoted 24 lines · Andre McCurdy
On Wed, Feb 24, 2016 at 6:52 AM, Joshua Lock <[email protected]
Quoted 23 lines
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.bbmeta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +1
-0@@ -0,0 +1,19 @@ +SUMMARY = "hardlink is a tool which replaces multiple copies of afile with hardlinks."
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+LICENSE = "MIT" +LIC_FILES_CHKSUM ="file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+ +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar
Quoted 8 lines
meta/recipes-extended/hardlink/hardlink_0.3.0.bb
Quoted 6 lines
.xz"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad" +SRC_URI[sha256sum] ="
e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+ +DEPENDS = "libpcre attr"According to the style guide, DEPENDS should come between
LIC_FILES_CHKSUMandSRC_URI.
Good catch, I'll re-order.
Thanks,
Joshua
Re: [PATCH 03/10] hardlink: add new recipe
In reply to Joshua LockI 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
Quoted 31 lines · Joshua Lock
--- 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.bbmeta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +19
-0@@ -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"
Re: [PATCH 03/10] hardlink: add new recipe
Quoted 1 line · Mark Hatle
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
Quoted 49 lines
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
Quoted 41 lines · Joshua Lock
---
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.bbmeta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +1
-0@@ -0,0 +1,19 @@ +SUMMARY = "hardlink is a tool which replaces multiple copies of afile with hardlinks."
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+LICENSE = "MIT" +LIC_FILES_CHKSUM ="file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+ +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar.xz"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad" +SRC_URI[sha256sum] ="
e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +5
-0+ +DEPENDS = "libpcre attr" + +do_compile () { + oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}'BINDIR='${bindir}'
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +4
-0+} + +do_install () { + oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}'BINDIR='${bindir}'
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +3
-0+} + +BBCLASSEXTEND = "native nativesdk"
Re: [PATCH 03/10] hardlink: add new recipe
Quoted 6 lines · Joshua G Lock
Quoted 1 line · Mark Hatle
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
Quoted 53 lines
Thanks,
Joshua
Quoted 49 lines
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
Quoted 41 lines · Joshua Lock
--- 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
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +1
-0@@ -0,0 +1,19 @@ +SUMMARY = "hardlink is a tool which replaces multiple copies of afile with hardlinks."
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+LICENSE = "MIT" +LIC_FILES_CHKSUM ="file://hardlink.c;endline=22;md5=168464a4fc92fa7389c53b0755b39fbb"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+ +SRC_URI = "http://jak-linux.org/projects/hardlink/${BPN}_${PV}.tar.xz"
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +2
-0+SRC_URI[md5sum] = "72f1a460adb6874c151deab766e434ad" +SRC_URI[sha256sum] ="
e8c93dfcb24aeb44a75281ed73757cb862cc63b225d565db1c270af9dbb7300f"meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +5
-0+ +DEPENDS = "libpcre attr" + +do_compile () { + oe_runmake 'DESTDIR=${D}' 'PREFIX=${prefix}'BINDIR='${bindir}'
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +4
-0+} + +do_install () { + oe_runmake install 'DESTDIR=${D}' 'PREFIX=${prefix}'BINDIR='${bindir}'
meta/recipes-extended/hardlink/hardlink_0.3.0.bb new file +3
-0+} + +BBCLASSEXTEND = "native nativesdk"
PATCH 4/10 swupd-client: Add recipe
In reply to Joshua LockFrom: Mariano Lopez <[email protected]>
This commit adds the Clear Linux client updater.
This is experimental and bleeding edge, including the comments on the recipe.
--- .../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
meta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch new file +59 -0
@@ -0,0 +1,59 @@ +From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:00 2001 +From: Dmitry Rozhkov <[email protected]> +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 <[email protected]> + +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 +
meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch new file +31 -0
@@ -0,0 +1,31 @@ +From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:00 2001 +From: Jaska Uimonen <[email protected]> +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 +
meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch new file +36 -0
@@ -0,0 +1,36 @@ +From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:00 2001 +From: Amarnath Valluri <[email protected]> +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 <[email protected]> +--- + 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 +
meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch new file +38 -0
@@ -0,0 +1,38 @@ +From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:00 2001 +From: Amarnath Valluri <[email protected]> +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 <[email protected]> +--- + 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 +
meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
2.5.0
Re: [PATCH 04/10] swupd-client: Add recipe
Quoted 249 lines · Joshua Lock
From: Mariano Lopez <[email protected]>
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 <[email protected]>Signed-off-by Joshua Lock <[email protected]>--- .../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.bbmeta/recipes-devtools/swupd/swupd-client/0001-Tolerate-quotes-in-os-release-files.patch new file +59
-0@@ -0,0 +1,59 @@ +From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:00 2001 +From: Dmitry Rozhkov <[email protected]> +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 <[email protected]> + +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 +meta/recipes-devtools/swupd/swupd-client/Change-systemctl-path-to-OE-systemctl-path.patch new file +31
-0@@ -0,0 +1,31 @@ +From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:00 2001 +From: Jaska Uimonen <[email protected]> +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 +meta/recipes-devtools/swupd/swupd-client/Fix-build-failure-on-Yocto.patch new file +36
-0@@ -0,0 +1,36 @@ +From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:00 2001 +From: Amarnath Valluri <[email protected]> +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 <[email protected]> +--- + 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 +meta/recipes-devtools/swupd/swupd-client/Right-usage-of-AC_ARG_ENABLE-on-bzip2.patch new file +38
-0@@ -0,0 +1,38 @@ +From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:00 2001 +From: Amarnath Valluri <[email protected]> +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 <[email protected]> +--- + 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 +meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +35
-0@@ -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
meta/recipes-devtools/swupd/swupd-client_2.87.bb line 45
Quoted 10 lines
meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +10
-0+ 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
Re: [PATCH 04/10] swupd-client: Add recipe
Quoted 317 lines · Maciej Borzecki
Quoted 316 lines · Joshua Lock
From: Mariano Lopez <[email protected]>
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 <[email protected]>Signed-off-by Joshua Lock <[email protected]>---
.../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.patchcreate 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(quoted diff) +0
-0Tolerate-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..49c71aemeta/recipes-devtools/swupd/swupd-client/0001-Tolerate- new file +0
-0quotes-in-os-release-files.patch
meta/recipes-devtools/swupd/swupd-client/0001-Tolerate- new file +1
-0@@ -0,0 +1,59 @@ +From 586e7b927461f6604ee3a3159cd7a6d4ac22ef30 Mon Sep 17 00:00:002001
meta/recipes-devtools/swupd/swupd-client/0001-Tolerate- new file +24
-0+From: Dmitry Rozhkov <[email protected]> +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 <[email protected]> + +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 @@ intread_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.0meta/recipes-devtools/swupd/swupd-client/0001-Tolerate- new file +1
-0+(quoted diff) +0
-0systemctl-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..5ca6373meta/recipes-devtools/swupd/swupd-client/Change-systemctl- new file +0
-0path-to-OE-systemctl-path.patch
meta/recipes-devtools/swupd/swupd-client/Change-systemctl- new file +1
-0@@ -0,0 +1,31 @@ +From 259d86e64146c3156eccfcce0351a9cdc4714766 Mon Sep 17 00:00:002001
meta/recipes-devtools/swupd/swupd-client/Change-systemctl- new file +17
-0+From: Jaska Uimonen <[email protected]> +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.0meta/recipes-devtools/swupd/swupd-client/Change-systemctl- new file +1
-0+(quoted diff) +0
-0failure-on-Yocto.patch b/meta/recipes-devtools/swupd/swupd-
client/Fix-build-failure-on-Yocto.patch
new file mode 100644
index 0000000..73f1728meta/recipes-devtools/swupd/swupd-client/Fix-build-failure- new file +0
-0on-Yocto.patch
meta/recipes-devtools/swupd/swupd-client/Fix-build-failure- new file +1
-0@@ -0,0 +1,36 @@ +From ccce73a2d703e6789ded87ca5aa9f3b7c506892a Mon Sep 17 00:00:002001
meta/recipes-devtools/swupd/swupd-client/Fix-build-failure- new file +5
-0+From: Amarnath Valluri <[email protected]> +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 asincluded in
meta/recipes-devtools/swupd/swupd-client/Fix-build-failure- new file +27
-0+_DATA twice. We can use EXTRA_DIST than dist_. + +Upstream-Status: Inappropriate + +Signed-off-by: Amarnath Valluri <[email protected]> +--- + 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.4meta/recipes-devtools/swupd/swupd-client/Fix-build-failure- new file +1
-0+(quoted diff) +0
-0of-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..e5b53efmeta/recipes-devtools/swupd/swupd-client/Right-usage-of- new file +0
-0AC_ARG_ENABLE-on-bzip2.patch
meta/recipes-devtools/swupd/swupd-client/Right-usage-of- new file +1
-0@@ -0,0 +1,38 @@ +From d80ae9954c5e5b720766274249dbf5309b7c70a9 Mon Sep 17 00:00:002001
meta/recipes-devtools/swupd/swupd-client/Right-usage-of- new file +21
-0+From: Amarnath Valluri <[email protected]> +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 <[email protected]> +--- + 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 bzip2compression (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.4meta/recipes-devtools/swupd/swupd-client/Right-usage-of- new file +1
-0+meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +1
-0@@ -0,0 +1,49 @@ +SUMMARY = "swupd sofware update from Clear Linux - clientcomponent"
meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +2
-0+LICENSE = "GPL-2.0" +LIC_FILES_CHKSUM ="file://COPYING;md5=04d0b48662817042d80393e7511fa41b \
+ file://bsdiff/LICENSE;md5=0dbe7a50f028269750631fcbded3846a"meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +3
-0+ +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 \
+"meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +3
-0+ +SRC_URI[md5sum] = "5d272c62edb8a9c576005ac5e1182ea3" +SRC_URI[sha256sum] ="
45df259a7dc2fed985ee9961e112120fc46670dd75476c3262fc6804b1c66fb8"meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +4
-0+ +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 bepart of the
meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +8
-0+# 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}"
meta/recipes-devtools/swupd/swupd-client_2.87.bb new file +4
-0+ +#TODO: create and install /var/lib/swupd/{delta,staged/download} +do_install_append () { + # swupd-client 2.87 doesn't (succesfully) create these andfails 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/bundlesmeta/recipes-devtools/swupd/swupd-client_2.87.bb new file +2
-0+} +
Quoted 8 lines
Quoted 4 lines
+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
PATCH 5/10 swupdbundle: new class to generate virtual images for swupd-image
In reply to Joshua LockOur 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"
--- meta/classes/swupdbundle.bbclass | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 meta/classes/swupdbundle.bbclass
meta/classes/swupdbundle.bbclass new file +59 -0
@@ -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"
Signature · 1 line
2.5.0
Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
Quoted 76 lines · Joshua Lock
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_BUNDLESvariable are valid and the bundle contents should be listed in a varFlag matching the bundle's name on theBUNDLE_CONTENTSvariable.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 <[email protected]>--- meta/classes/swupdbundle.bbclass | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 meta/classes/swupdbundle.bbclassmeta/classes/swupdbundle.bbclass new file +41
-0@@ -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() +
meta/classes/swupdbundle.bbclass line 51
Quoted 10 lines
meta/classes/swupdbundle.bbclass new file +10
-0+ 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.
Quoted 11 lines
meta/classes/swupdbundle.bbclass new file +8
-1+ 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
Quoted 5 lines
--
_______________________________________________
Openembedded-core mailing list
[email protected]
http://lists.openembedded.org/mailman/listinfo/openembedded-core
--
Maciej Borzęcki
Senior Software Developer at Open-RnD Sp. z o.o., Poland
Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
Quoted 98 lines · Maciej Borzecki
Quoted 97 lines · Joshua Lock
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_BUNDLESvariable are valid and the bundle contents should be listed in a varFlag matching the bundle's name on theBUNDLE_CONTENTSvariable.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 <[email protected]>---
meta/classes/swupdbundle.bbclass | 59
++++++++++++++++++++++++++++++++++++++++1 file changed, 59 insertions(+)create mode 100644 meta/classes/swupdbundle.bbclass
meta/classes/swupdbundle.bbclass new file +1
-0@@ -0,0 +1,59 @@ +# Our initial strategy to generate bundles for consumption byswupd 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 rootfsmeta/classes/swupdbundle.bbclass new file +3
-0+# outside of installing files, i.e.with postinsts. +# +# To that end this class, to be used via BBCLASSEXTEND, willgenerate virtual
meta/classes/swupdbundle.bbclass new file +3
-0+# image recipes that add extra packages to the extended image. +# +# Only extensions matching entries in a SWUPD_BUNDLES variable arevalid and
+# the bundle contents should be listed in a varFlag matching the bundle's namemeta/classes/swupdbundle.bbclass new file +17
-0+# 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()
+
+ defget_bundle_contents(bndl):
+ contents =e.data.getVarFlag('BUNDLE_CONTENTS', bndl, True)
+ if contents:
+ returncontents.split()
+ else:
+ bb.fatal('BUNDLE_CONTENTS[%s] is not set, this should
Quoted 8 lines
Quoted 5 lines
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
Quoted 21 lines
Quoted 13 lines
+ else:
+ curr_install +=get_bundle_contents(bundle)meta/classes/swupdbundle.bbclass new file +6
-0+ + e.data.setVar('IMAGE_INSTALL', ' '.join(curr_install)) +} + +addhandler swupdbundle_virtclass_handler +swupdbundle_virtclass_handler[eventmask] ="bb.event.RecipePreFinalise"
--
2.5.0Quoted 5 lines
--
_______________________________________________
Openembedded-core mailing list
[email protected]
http://lists.openembedded.org/mailman/listinfo/openembedded-core--
Maciej Borzęcki
Senior Software Developer at Open-RnD Sp. z o.o., Poland
Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
In reply to Joshua LockQuoted 10 lines · Joshua Lock
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.
Signature · 6 lines
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.
Re: [PATCH 05/10] swupdbundle: new class to generate virtual images for swupd-image
Hi Patrick,
Apologies for the delayed response.
Quoted 9 lines · Patrick Ohly
Quoted 8 lines · Joshua Lock
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.
Quoted 7 lines
Quoted 3 lines
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
PATCH 6/10 swupd-image.bbclass: initial class to support swupd updater
In reply to Joshua LockThis 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
--- meta/classes/swupd-image.bbclass | 372 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 meta/classes/swupd-image.bbclass
meta/classes/swupd-image.bbclass new file +372 -0
@@ -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}"
Signature · 1 line
2.5.0
PATCH 7/10 oe-swupd-helpers: provide swupd-client required helper scripts and units
In reply to Joshua Lockswup-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.
--- 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
meta/recipes-devtools/swupd/oe-swupd-helpers.bb new file +39 -0
@@ -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}"
meta/recipes-devtools/swupd/oe-swupd-helpers/catalog-trigger.service new file +8 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/clr_pre_update.sh new file +16 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/kernel_updater.sh new file +9 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/ldconfig-trigger.service new file +8 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/systemdboot_updater.sh new file +10 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/tmpfiles-trigger.service new file +8 -0
@@ -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
meta/recipes-devtools/swupd/oe-swupd-helpers/update-triggers.target new file +5 -0
@@ -0,0 +1,5 @@ +[Unit] +Description=Post system update triggers +Wants=ldconfig-trigger.service +Wants=catalog-trigger.service +Wants=tmpfiles-trigger.service
Signature · 1 line
2.5.0
PATCH 8/10 swupd-client: RDEPENDS on oe-swupd-helpers
In reply to Joshua LockThe oe-swupd-helpers package provides scripts and units that swupd-client calls before, during and after the update process.
--- meta/recipes-devtools/swupd/swupd-client_2.87.bb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
meta/recipes-devtools/swupd/swupd-client_2.87.bb +1 -3
@@ -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"
Signature · 1 line
2.5.0
PATCH 9/10 swupd-client: enable native builds
In reply to Joshua LockThis is useful for debugging swupd generated artefacts on the build host i.e. swupd hashdump
--- meta/recipes-devtools/swupd/swupd-client_2.87.bb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
meta/recipes-devtools/swupd/swupd-client_2.87.bb +3 -1
@@ -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"
Signature · 1 line
2.5.0
PATCH 10/10 os-release: sanitise VERSION_ID field
In reply to Joshua LockPer 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.
--- meta/recipes-core/os-release/os-release.bb | 9 +++++++++ 1 file changed, 9 insertions(+)
meta/recipes-core/os-release/os-release.bb +9 -0
@@ -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':
Signature · 1 line
2.5.0
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.
Quoted 11 lines · Joshua Lock
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.
Quoted 4 lines
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.
Signature · 6 lines
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.
Quoted 28 lines · Patrick Ohly
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.Quoted 11 lines · Joshua Lock
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 recipesQuoted 8 lines
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.
Quoted 5 lines
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.
Quoted 11 lines
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.
Quoted 8 lines
Quoted 8 lines
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
withIMAGE_POSTPROCESS_COMMAND, etc.
Quoted 5 lines
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
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 35 lines · Joshua G
Quoted 28 lines · Patrick Ohly
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.Quoted 10 lines · Joshua Lock
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.Quoted 9 lines
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.Quoted 5 lines
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?
Quoted 4 lines
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.
Quoted 12 lines
Quoted 11 lines
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.
Quoted 5 lines
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.
Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
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
withIMAGE_POSTPROCESS_COMMAND, etc.Makes sense to me.
Quoted 8 lines
Quoted 3 lines
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.
Signature · 6 lines
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.
Quoted 51 lines · Patrick Ohly
Quoted 44 lines · Joshua G
Quoted 36 lines · Patrick Ohly
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.Quoted 12 lines · Joshua Lock
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.Quoted 12 lines
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.Quoted 6 lines
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?Quoted 6 lines
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.
Quoted 6 lines
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/passwdmust 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
Quoted 3 lines
(*) 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
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?).
Quoted 7 lines · Trevor Woerner
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?).
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
Quoted 10 lines
Dnia 24 luty 2016 o 17:35 Philip Balister <[email protected]> napisał(a):
Quoted 6 lines · Trevor Woerner
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?).
Quoted 8 lines
Quoted 1 line
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
Quoted 9 lines · On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
Quoted 6 lines · Trevor Woerner
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?).
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.
Quoted 3 lines
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
Signature · 2 lines
Paul Eggleton Intel Open Source Technology Centre
Quoted 14 lines · Paul Eggleton
Quoted 9 lines · On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
Quoted 6 lines · Trevor Woerner
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?).
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.
Quoted 7 lines
Quoted 3 lines
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
Quoted 4 lines
Cheers,
Paul
Quoted 25 lines · Philip Balister
Quoted 24 lines · Paul Eggleton
Quoted 11 lines · On Wed, 24 Feb 2016 11:35:25 Philip Balister wrote:
Quoted 9 lines · Trevor Woerner
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?).Quoted 2 lines
Quoted 1 line
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.Quoted 5 lines
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?
Quoted 7 lines
Quoted 5 lines
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