Compare commits

...
55 Commits
Author SHA1 Message Date
Tudor Marcu b417fc4391 Release v3.3.1
This release fixes some git tagging errors that occured in the previous release.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-11-17 11:09:56 -08:00
Tudor Marcu 478cdc5272 Merge tag 'v3.3.0'
swupd-server release 3.3.0
2016-11-17 11:07:58 -08:00
Tudor Marcu 2992dc1978 Release v3.3.0
This release contains various changes to fix segfaults and memory misuse,
simplifying logic when iterating directories and populating file structs
from manifests, and changing the secondary sort to be lexographically sorted
filenames for version-sorted manifests.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-11-17 01:21:31 -08:00
Tudor Marcu ec31238e1a Release v3.3.0
This release contains various changes to fix segfaults and memory misuse,
simplifying logic when iterating directories and populating file structs
from manifests, and changing the secondary sort to be lexographically sorted
filenames for version-sorted manifests.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-11-17 01:14:42 -08:00
Patrick McCarty 9148ea8a8e Switch secondary sort order for version-sorted manifests
To ease human readability of manifests, but without impacting manifest
delta efficiency, use a lexicographic filename secondary sort order when
sorting manifests by version.

Below is an example of how this commit changes the sorted order (the
first column is the version, and the second column is the filename).

 # Before
 10	zyxw
 10	abcd
 20	test2
 20	test1
 20	abba
 20	aaaa
 30	zzyy

 # After
 10	abcd
 10	zyxw
 20	aaaa
 20	abba
 20	test1
 20	test2
 30	zzyy

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-11-16 22:28:26 -08:00
Tudor Marcu 74c8f86a94 Simplify logic for iterating directories
The file struct must be populated to contain the proper stats, so just
check if it is a directory and iterate, ignoring the case where d_type may
not be defined on the system.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-11-15 17:54:19 -08:00
Tudor Marcu a43964b110 Revert "Resort to lstat for FS not supporting dirent.d_type"
This reverts commit 983b17d68d.
2016-11-15 17:42:09 -08:00
Dmitry Rozhkov 983b17d68d Resort to lstat for FS not supporting dirent.d_type
According to POSIX.1 only d_name and d_ino fields of struct
dirent are standardized. d_type isn't always correctly set on file
systems like XFS. In such cases it makes sense to resort to
lstat(). Otherwise a user has hard time figuring out what's
wrong with her setup.

Also remove redundant populate_file_struct() as it's called
again in parallel threads.

Signed-off-by: Dmitry Rozhkov <dmitry.rozhkov@linux.intel.com>
2016-11-15 17:28:16 -08:00
Joshua Lock 5420a1ea1b Ensure os-core bundle is listed in groups.ini
If the os-core bundle is not listed in groups.ini we will run into
problems later on, including segfaults when processing bundle includes.

Check the os-core bundle is listed in the groups.ini during initialisation
and error gracefully when it is not.

Signed-off-by: Joshua Lock <joshua.g.lock@intel.com>
2016-11-15 17:26:45 -08:00
Patrick Ohly 1c75f53604 swupd_create_fullfiles: avoid segfault when nothing changes
In the (unlikely) case that nothing changed between two builds,
get_deduplicated_fullfile_list() segfaults because it uses
manifest->files without checking for NULL, aka the empty list.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2016-11-15 11:32:23 -08:00
Patrick Ohly 2890a11c5a delta.c: fix xattr test after patching
At the moment, swupd_create_pack fails when some files have xattrs and
get patched because the xattrs of the test file do not match the
original, unpatched file.

That's because xattrs_copy() was applied to the wrong target file.

Fixes: swupd-server/#35

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
2016-11-15 11:28:26 -08:00
Tudor Marcu 2401aae76e Release v3.2.9
This release fixes the path where the server reads the bundle metadata from.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-29 17:17:30 -07:00
Patrick McCarty 30b46b9027 Update for new noship dir location
The bundle-chroot-builder changed the location where it stores bundle
includes metadata, so swupd-server needs to read from the new location.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-09-29 13:40:12 -07:00
Tudor Marcu c8ae097ed0 Release v3.2.8
This release updates the latest.version file, and provides minor cleanups
for useability.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-29 11:21:43 -07:00
Tudor Marcu 076a76fc4e Update for latest.version name change
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-29 11:21:43 -07:00
Tudor Marcu 63fb5fb61b Change strcmp to strncmp for consistency
Signed-off-by: John Andersen <john.s.andersen@intel.com>
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-29 10:54:07 -07:00
Auke Kok 7758a6bb77 Document and ship bundle status string.
This patch extracts the [STATUS] field from our bundle information
metadata, and stores it in groups.ini. From there we put the contents
of this string verbatim into the manifest.

We don't interpret, encode or convert the contents of the [STATUS]
field in the manifest. Instead, we just strip non-alphanumeric
characters and pass the contents on. This leaves it entirely to the
client to parse and interpret the value of this field in the manifest.

If the bundle file, or the groups.ini file omits any status, nothing
is output to the Manifest file.
2016-09-29 10:45:03 -07:00
Tudor Marcu 36c4e6324f Change version file to more appropriate name
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-07 17:21:09 -07:00
Tudor Marcu c4f61cb023 Release v3.2.7
Bump release version to provide a new server for a format bump.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-09-06 14:15:52 -07:00
Tudor Marcu 379d5189fc Release v3.2.6
This release introduces a change to the hashing scheme regarding delta names,
and directory hashes, as well as minor fixes to support the new hashing.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-08-22 03:23:22 -07:00
Tudor Marcu 6eca4601b0 Update argument passed to system_argv
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-08-22 03:22:14 -07:00
Tudor Marcu 4940d0cf83 Fix functional test for server changes
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-08-22 02:47:16 -07:00
Tudor Marcu 04d2af2f64 Change delta's name from FROM-TO-HASH2 to FROM-TO-HASH1-HASH2 format.
There is an issue when two different files in a newer release have same hash:
This is, when swupd updates a file by applying a delta, it takes the HASH2 to
know the file where delta must be applyed. If files are different in current
release (before updating), there must be 2 deltas, one for each file but as
the two files have same hash in new release delta's name are the same:
FROM-TO-HASH2 and it is when issue arises due to just the last delta file is
kept when swupd server creates files and packs. So when swupd client tries to
apply the delta to one of the file that does not corresponds it will fail and
generates an error. At the first look it will seem like delta file is corrupted
however the issue is that delta file was created for another file.
To solve this issue we include the hash for the original file in the delta's
name so that swupd client can take the correct delta and apply it:
FROM-TO-HASH1-HASH2.

Signed-off-by: Jose R Guzman <jose.r.guzman.mosqueda@intel.com>
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-08-19 17:17:20 -07:00
Tudor Marcu 1f98322737 Make directory hashes independent on filename
Calculate the hash for directories is desiderable to be independent
on the dirname due to the subsequent calculation on the staged/HASH
file. Here is used const "DIRECTORY" string for input name for
all folders.

Signed-off-by: Jose R Guzman <jose.r.guzman.mosqueda@intel.com>
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-08-19 17:15:56 -07:00
Tudor Marcu ddca171dad Release v3.2.5
This release includes a fix to replace system calls by local system_argv
functions, cleanup patches for error output and code style, adding delta
manifests to delta packs, consistency changes for tar and string allocation,
and removes creation of delta manifests out of create_update.
This is a re-roll of release 3.2.4 to fix a time skew issue that caused some
build failures.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-07-19 16:32:20 -07:00
Tudor Marcu 62c31f0088 Release v3.2.4
This release includes a fix to replace system calls by local system_argv
functions, cleanup patches for error output and code style, adding delta
manifests to delta packs, consistency changes for tar and string allocation,
and removes creation of delta manifests out of create_update.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-07-19 23:21:18 -07:00
Tudor Marcu 54874bd4e1 Add null check before calling rmdir in manifest.c
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-07-19 19:15:33 -07:00
Tudor Marcu 9fe3ad2241 Remove delta manifest creation from create_update
Delta manifests are handled by the pack creation step, and should not be
part of the plain manifest/update content creation step. This reduces the time
swupd_create_update takes to run significantly.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-07-19 02:05:07 -07:00
Tudor Marcu be83996e48 Revert "Parallelize manifest creation code"
This reverts commit 7f3b760430 and commit
74f4afa655. The code introduced parallel manifest
creation, and removed delta manifests from being created, but needs some more
rigorous testing and refactoring to ensure all test suites pass.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-07-14 20:32:51 -07:00
Patrick McCarty 7f3b760430 Import latest version of previous patch
I had neglected to rebase to the latest revision of #21, so this commit
incorporates the additional changes.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-06-03 16:35:56 -07:00
Tudor Marcu 74f4afa655 Parallelize manifest creation and remove deltas
The code previously created all the bundle manifests and delta manifests
synchronously in 1 thread. While this worked, it was not optimal considering
the manifests can be created at the same time since they are unique. This
patch creates a threadpool that processes each bundle manifest in its own
thread. Delta manifest creation was removed from create_update because it
can already be handled by our delta pack creation process, and it is a huge
time-sink for create_update as it also runs single threaded.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-05-20 14:49:08 -07:00
Patrick McCarty ea02b67a93 Provide more information for pack hardlink errors
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 16:21:34 -07:00
Patrick McCarty 8af939c817 Update functional test to check for delta manifests in packs
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 15:59:14 -07:00
Patrick McCarty 4128fbbb9b Add delta manifests to delta packs
The delta manifests were being staged correctly but were not being added
to the delta packs.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 15:49:33 -07:00
Patrick McCarty 0d08824801 Permit allocating empty strings in string_or_die()
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 14:21:50 -07:00
Patrick McCarty 8f98e0f570 Update code comment to mention the os-core pack, instead of "base"
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 14:19:17 -07:00
Patrick McCarty 76e5af734b Use tar's -C option everywhere instead of --directory
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 14:14:51 -07:00
Patrick McCarty b7192ee686 Convert the recently added system() call
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 14:14:17 -07:00
Patrick McCarty b0e0b7f77d Fix some clang-format nitpicks
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-17 13:57:48 -07:00
Jose R Guzman 746b9a56a8 Replace system calls by local system_argv functions.
There are new functions that replace system() calls: system_argv(), system_argv_fd and system_argv_pipe().
They are based on execvp() function and they can manage any argument including filenames with characters
that could be interpreted as meta-characters in a regular system() function.
So no escape for the arguments needed and is less prone to errors.

Signed-off-by: Jose R Guzman <jose.r.guzman.mosqueda@intel.com>
2016-05-17 13:56:10 -07:00
Patrick McCarty adfc1067ff Remove pack_maker.sh
Since delta pack creation is very much tied to a DevOps workflow, it
makes more sense for the pack_maker.sh to live outside of swupd-server.

This script will move to the clearlinux/mixer-tools repo, since the
Clear mixer is a DevOps-oriented tool.

Also, update the code comment in versions.c to describe another action
to be taken that is DevOps-specific, namely that the value of
WEBDIR/version/formatN/latest file should be set at release time.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-16 14:20:41 -07:00
Patrick McCarty 122f674e74 Make elapsed time progress messages more flexible
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-11 15:40:50 -07:00
Patrick McCarty 9d4df7e035 Release v3.2.3
This release fixes a bug with adding invalid bundle manifest hashes to
the Manifest.MoM and optimizes swupd_create_update to remove the
unnecessary rsync from the full chroot back to bundle chroots.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-11 11:20:13 -07:00
Tudor Marcu 4df4bf14c3 Remove rsync from full->bundle chroots
This is no longer needed with the current setup, and is just wasting time during
update creation.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-05-10 14:43:06 -07:00
Tudor Marcu 6affbd1ecb Free allocated variable
Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-05-05 12:23:59 -07:00
Patrick McCarty 77a0bcd9f9 Account for deleted manifests in the MoM population
Just in case we encounter a bundle manifest that does not exist anymore,
or the last_change is 0, which is an invalid version to create, make
sure we add the deleted entry in the MoM and do not attempt to untar
that manifest.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-05-05 12:17:49 -07:00
Tudor Marcu bf19e48917 Fix bundle manifest hashes from MoM
The bundle manifest hashes were calculated from the STATE_DIR Manifest.bundle
files, which caused a problem when they the permissions/owner were changed. The
hashes should be calculated by untarring the Manifest.BUNDLE.tar files
referenced in the Manifest.MoM.

Signed-off-by: Tudor Marcu <tudor.marcu@intel.com>
2016-05-05 17:57:59 +00:00
Patrick McCarty d45304c8b7 Add functional test for blacklisted file names
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-29 16:39:11 -07:00
Patrick McCarty 2b4e9eb3c9 test: quote echo strings to protect against shell interpretation
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-29 16:39:08 -07:00
Patrick McCarty b6bd8bf73b Release v3.2.2
This release includes a trivial improvement for reporting paths that
contain blacklisted characters.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-29 15:23:44 -07:00
Patrick McCarty 94240130be Report full paths for files containing blacklisted characters
To better track which files are excluded from manifests because they
contain blacklisted characters, the full path is more useful to log
rather than the file basename.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-29 15:04:16 -07:00
Patrick McCarty ae299e2126 Rename main.c to create_update.c
Since the source files for entry points to the other two binaries are
named after the binaries, do the same for swupd_create_update.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-14 11:14:36 -07:00
Patrick McCarty 64e65bca92 Run functional tests in separate directories
To more easily implement tests, analyze test results, etc, store each
test in a separate directory and dump all logs and the web-dir content
there as well.

The test suite can be run with 'make check', as before, but now tests
can be run individually by directly invoking the appropriate test.bats
file (at toplevel, or within the test directory).

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-10 21:03:06 -07:00
Patrick McCarty e78ef77e06 Release v3.2.1
This release fixes a sorting issue with bundle manifests: they should be
version sorted, not filename sorted.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-05 23:51:22 -07:00
Patrick McCarty a329cc93a9 Fix sorting issue with bundle manifests
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-05 23:50:42 -07:00
29 changed files with 574 additions and 417 deletions
+4 -2
View File
@@ -27,7 +27,9 @@ coverage/
src/*.gcno
src/*.gcda
tap-driver.sh
test/functional/*.log
test/functional/*.trs
test/functional/*/*.log
test/functional/*/*.trs
test/functional/*/logs/
test/functional/*/web-dir/
swupd-*.log
test-suite.log
+14 -11
View File
@@ -15,6 +15,7 @@ swupd_create_update_SOURCES = \
src/analyze_fs.c \
src/chroot.c \
src/config.c \
src/create_update.c \
src/delta.c \
src/fullfiles.c \
src/globals.c \
@@ -22,7 +23,6 @@ swupd_create_update_SOURCES = \
src/helpers.c \
src/heuristics.c \
src/log.c \
src/main.c \
src/manifest.c \
src/pack.c \
src/rename.c \
@@ -37,6 +37,7 @@ swupd_make_pack_SOURCES = \
src/config.c \
src/delta.c \
src/globals.c \
src/groups.c \
src/helpers.c \
src/log.c \
src/make_packs.c \
@@ -53,6 +54,7 @@ swupd_make_fullfiles_SOURCES = \
src/delta.c \
src/fullfiles.c \
src/globals.c \
src/groups.c \
src/helpers.c \
src/log.c \
src/make_fullfiles.c \
@@ -96,26 +98,27 @@ noinst_HEADERS = \
include/swupd.h \
include/xattrs.h
TEST_EXTENSIONS = .sh
TEST_EXTENSIONS = .bats
if ENABLE_TESTS
tap_driver = env AM_TAP_AWK='$(AWK)' $(SHELL) \
$(top_srcdir)/tap-driver.sh
LOG_DRIVER = $(tap_driver)
SH_LOG_DRIVER = $(tap_driver)
BATS_LOG_DRIVER = $(tap_driver)
TESTS = $(dist_check_SCRIPTS)
dist_check_SCRIPTS = \
test/functional/basic.bats \
test/functional/delete-no-version-bump.bats \
test/functional/include-version-bump.bats \
test/functional/update.bats \
test/functional/fullfiles.bats \
test/functional/pack.bats \
test/functional/full-run.bats \
test/functional/full-run-delta.bats
test/functional/basic/test.bats \
test/functional/delete-no-version-bump/test.bats \
test/functional/include-version-bump/test.bats \
test/functional/update/test.bats \
test/functional/fullfiles/test.bats \
test/functional/pack/test.bats \
test/functional/full-run/test.bats \
test/functional/full-run-delta/test.bats \
test/functional/file-name-blacklisted/test.bats
endif
if COVERAGE
+2 -6
View File
@@ -15,7 +15,7 @@ error() {
# eg: all of openstack, pnp, bat, cloud stuff, non-basic scripting language bundles
${SWUPDREPO}/mk_groups_ini.sh
PREVREL=`cat ${UPDATEDIR}/image/latest.version`
PREVREL=`cat ${UPDATEDIR}/image/LAST_VER`
export SWUPD_CERTS_DIR=${SWUPD_CERTS_DIR:-"/root/swupd-certs"}
export LEAF_KEY="leaf.key.pem"
@@ -45,12 +45,8 @@ for job in $(jobs -p); do
fi
done
# create delta packs for 2 versions back
NUM_PACKS=2
${SWUPDREPO}/pack_maker.sh ${VER} ${NUM_PACKS}
# expose the new build to staging / testing
echo ${VER} > ${UPDATEDIR}/image/latest.version
echo ${VER} > ${UPDATEDIR}/image/LAST_VER
STAGING_FILE="${UPDATEDIR}/www/version/formatstaging/latest"
if [ ! -f "${STAGING_FILE}" ]; then
+1 -1
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.66])
AC_INIT(swupd-server, 3.2.0, timothy.c.pepper@linux.intel.com)
AC_INIT(swupd-server, 3.3.1, tudor.marcu@intel.com)
AM_INIT_AUTOMAKE([foreign -Wall -W subdir-objects])
AM_SILENT_RULES([yes])
AC_PROG_CC
+12 -2
View File
@@ -19,19 +19,25 @@
#if SWUPD_WITH_BSDTAR
#define TAR_COMMAND "bsdtar"
#define TAR_XATTR_ARGS ""
#define TAR_XATTR_ARGS_STRLIST
#define TAR_WARN_ARGS ""
#else
#define TAR_COMMAND "tar"
#define TAR_XATTR_ARGS "--xattrs --xattrs-include='*'"
#define TAR_XATTR_ARGS_STRLIST "--xattrs", "--xattrs-include='*'",
#define TAR_WARN_ARGS "--warning=no-timestamp"
#endif
#if SWUPD_WITH_SELINUX
#define TAR_PERM_ATTR_ARGS "--preserve-permissions --selinux " TAR_XATTR_ARGS
#define TAR_PERM_ATTR_ARGS_STRLIST TAR_XATTR_ARGS_STRLIST "--preserve-permissions", "--selinux"
#else
#define TAR_PERM_ATTR_ARGS "--preserve-permissions " TAR_XATTR_ARGS
#define TAR_PERM_ATTR_ARGS_STRLIST TAR_XATTR_ARGS_STRLIST "--preserve-permissions"
#endif
#define SWUPD_HASH_DIRNAME "DIRECTORY"
#if SWUPD_WITH_STATELESS
#define OS_IS_STATELESS 1
#else
@@ -215,6 +221,7 @@ extern void read_group_file(char *filename);
extern void release_group_file(void);
extern char *group_groups(char *group);
extern char *group_packages(char *group);
extern char *group_status(char *group);
extern char *next_group(void);
extern void apply_heuristics(struct manifest *manifest);
@@ -238,7 +245,7 @@ extern void type_change_detection(struct manifest *manifest);
extern void rename_detection(struct manifest *manifest, int last_change, GList *last_versions_list);
extern void link_renames(GList *newfiles, struct manifest *from_manifest);
extern void __create_delta(struct file *file, int from_version);
extern void __create_delta(struct file *file, int from_version, char *from_hash);
extern void account_delta_hit(void);
extern void account_delta_miss(void);
@@ -246,8 +253,11 @@ extern void account_delta_miss(void);
extern FILE *fopen_exclusive(const char *filename); /* no mode, opens for write only */
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 void print_elapsed_time(const char *step, struct timeval *previous_time, struct timeval *current_time);
extern int system_argv(char *const argv[]);
extern int system_argv_fd(char *const argv[], int newstdin, int newstdout, int newstderr);
extern int system_argv_pipe(char *const argvp1[], int stdinp1, int stderrp1,
char *const argvp2[], int stdoutp2, int stderrp2);
extern bool signature_initialize(void);
extern void signature_terminate(void);
+6 -2
View File
@@ -18,8 +18,8 @@ if [ ! -f "$SWUPD_SERVER_INI" ]; then
sed -i "s|/var/lib/update|$UPDATEDIR|" $SWUPD_SERVER_INI
fi
if [ ! -f "$UPDATEDIR/image/latest.version" ]; then
echo "0" > $UPDATEDIR/image/latest.version
if [ ! -f "$UPDATEDIR/image/LAST_VER" ]; then
echo "0" > $UPDATEDIR/image/LAST_VER
fi
echo "rebuilding $SWUPD_GROUPS_INI based on $BUNDLEREPO"
@@ -27,7 +27,11 @@ rm -f $SWUPD_GROUPS_INI
for bundle in $(ls $BUNDLEREPO/bundles)
do
status=$(awk -F: '/^# .STATUS/ {print $2}' $BUNDLEREPO/$bundle | tr -cd '[[:alnum:]]')
echo "[$bundle]" >> $SWUPD_GROUPS_INI
echo "group=$bundle" >> $SWUPD_GROUPS_INI
if [ -n "$status" ]; then
echo "status=$status" >> $SWUPD_GROUPS_INI
fi
echo "" >> $SWUPD_GROUPS_INI
done
-112
View File
@@ -1,112 +0,0 @@
#!/bin/bash -e
# usage:
# pack_maker.sh <to version> <back_count>
# pack_maker.sh 2820 2
# pack_maker.sh 2730 3
#
# For each bundle changed as of the Manifest.MoM at the <to version>,
# create version-pair packs going back <back_count>
# versions of that bundle. For example if bundle "editors" changed in 2650
# and the script is run as "pack_maker.sh 2650 2", it will find that
# "editors" last two change points were 2550 and 2260 and thus create a
# 2550-to-2650 and a 2260-to-2650 version pair pack for the "editors"
# bundle.
#NOTE: fullfiles must be created before calling this script
#NOTE: zero packs need similarly created
#NOTE: build numbers are sparse, search back for the next oldest existing build
#NOTE: in the future isn't simply -10, and when that change happens we must also
# consider which version-pair packs are meaningful for intermediate builds
# and revert builds.
SWUPDREPO=${SWUPDREPO:-"/usr/src/clear-projects/swupd-server"}
BUNDLEREPO=${BUNDLEREPO:-"/usr/src/clear-projects/clr-bundles"}
UPDATEDIR=${UPDATEDIR:-"/var/lib/update"}
SWUPDWEBDIR="${UPDATEDIR}/www"
SWUPD_CERTS_DIR=${SWUPD_CERTS_DIR=:-"/root/swupd-certs"}
export XZ_DEFAULTS="--threads 0"
export SWUPD_CERTS_DIR
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"
VER=$1
BACK_COUNT=$2
if [ "${BACK_COUNT}" == "" ]; then
echo "missing to pack count"
exit 1
fi
if [ "${VER}" == "" ]; then
echo "missing to version"
exit 1
fi
MOM=${SWUPDWEBDIR}/${VER}/Manifest.MoM
if [ ! -e ${MOM} ]; then
echo "invalid version (no ${MOM})"
exit 1
fi
#time ${SWUPDREPO}/swupd_make_fullfiles --statedir ${UPDATEDIR} ${VER}
BUNDLE_LIST=$(cat ${MOM} | awk -v V=${VER} '$1 ~ /^M\./ && $3 == V { print $4 }')
# build packs for all bundles changed in $VER
for BUNDLE in $BUNDLE_LIST; do
#${SWUPDREPO}/swupd_make_pack --statedir ${UPDATEDIR} 0 ${VER} ${BUNDLE} &
BUNDLE_VER_LIST=""
MANIFEST_VER=$(cat ${SWUPDWEBDIR}/$VER/Manifest.MoM | grep "^previous:" | cut -f 2)
BUNDLE_VER=""
COUNT=0
while [ $COUNT -lt $BACK_COUNT ] && [ $MANIFEST_VER -gt 0 ]; do
MOM=${SWUPDWEBDIR}/$MANIFEST_VER/Manifest.MoM
if [ -e ${MOM} ]; then
BUNDLE_VER=$(cat ${MOM} | grep " ${BUNDLE}$" | cut -f 3)
if [ "$BUNDLE_VER" != "" ]; then
BUNDLE_VER_LIST="$BUNDLE_VER $BUNDLE_VER_LIST"
MANIFEST_VER=$(cat ${SWUPDWEBDIR}/$BUNDLE_VER/Manifest.MoM | grep "^previous:" | cut -f 2)
let COUNT=$((COUNT+1))
else
# back in history to where bundle didn't exist yet
MANIFEST_VER=0
fi
else
# seek backwards until a manifest if found
MANIFEST_VER=$((MANIFEST_VER-10))
fi
done
for v in $BUNDLE_VER_LIST; do
if [ -e ${SWUPDWEBDIR}/${VER}/pack-${BUNDLE}-from-$v.tar ]; then
echo "${VER}/pack-${BUNDLE}-from-$v.tar already exists, skipping."
else
${SWUPDREPO}/swupd_make_pack --statedir ${UPDATEDIR} $v ${VER} ${BUNDLE} &
fi
done
done
for job in $(jobs -p)
do
wait ${job}
RET=$?
if [ "$RET" != "0" ]; then
echo "pack creation failure!"
exit $RET
fi
done
# NOTE: your devops will want to expose the completed swupd server build to
# trial usage at some point. This would be done via code like:
#
# echo ${VER} > ${SWUPDWEBDIR}/../image/latest.version
# STAGING=$(cat ${SWUPDWEBDIR}/version/formatstaging/latest)
# if [ "${STAGING}" -lt "${VER}" ]; then
# echo ${VER} > ${SWUPDWEBDIR}/version/formatstaging/latest
# fi
+14 -9
View File
@@ -222,7 +222,7 @@ int compute_hash(struct file *file, char *filename)
hmac_sha256_for_string(file->hash,
(const unsigned char *)key,
key_len,
file->filename); //file->filename not filename
SWUPD_HASH_DIRNAME); // Make independent of dirname
return 0;
}
@@ -286,18 +286,15 @@ static bool illegal_characters(char *filename)
// these breaks the tar transform sed-like expression,
// hopefully can remove this check after moving to libtar
if (strncmp(filename, "+", 1) == 0) {
printf("WARNING: Filename %s begins with '+'! ...skipping.\n", filename);
return true;
}
if (strstr(filename, "+package+") != NULL) {
printf("WARNING: Filename %s contains \"+package+\"! ...skipping.\n", filename);
return true;
}
for (i = 0; i < BAD_CHAR_COUNT; i++) {
c = bad_chars[i];
if (strchr(filename, c) != NULL) {
printf("WARNING: Filename %s includes illegal character '%c'! ...skipping.\n", filename, c);
return true;
}
}
@@ -323,6 +320,7 @@ static void iterate_directory(struct manifest *manifest, char *pathprefix,
while (dir) {
struct file *file;
char *sub_filename;
char *fullname;
entry = readdir(dir);
@@ -331,8 +329,15 @@ static void iterate_directory(struct manifest *manifest, char *pathprefix,
}
if ((strcmp(entry->d_name, ".") == 0) ||
(strcmp(entry->d_name, "..") == 0) ||
(illegal_characters(entry->d_name))) {
(strcmp(entry->d_name, "..") == 0)) {
continue;
}
string_or_die(&sub_filename, "%s/%s", subpath, entry->d_name);
if (illegal_characters(entry->d_name)) {
printf("WARNING: Filename %s includes illegal character(s) ...skipping.\n", sub_filename);
free(sub_filename);
continue;
}
@@ -342,13 +347,13 @@ static void iterate_directory(struct manifest *manifest, char *pathprefix,
}
file->last_change = manifest->version;
string_or_die(&file->filename, "%s/%s", subpath, entry->d_name);
file->filename = sub_filename;
string_or_die(&fullname, "%s/%s", fullpath, entry->d_name);
populate_file_struct(file, fullname);
free(fullname);
if (entry->d_type == DT_DIR) {
if (file->is_dir) {
iterate_directory(manifest, pathprefix, file->filename, do_hash);
}
@@ -413,7 +418,7 @@ GList *get_sub_manifest_includes(char *component, int version)
char *included;
char line[8192];
conf = config_output_dir();
conf = config_image_base();
if (conf == NULL) {
assert(0);
}
+12 -31
View File
@@ -34,9 +34,8 @@
void chroot_create_full(int newversion)
{
int ret;
char *group;
char *command;
char *param;
char *full_dir;
string_or_die(&full_dir, "%s/%i/full/", image_dir, newversion);
@@ -45,11 +44,12 @@ void chroot_create_full(int newversion)
/* start with base */
LOG(NULL, "Copying chroot os-core to full", "");
string_or_die(&command, "rsync -aAX %s/%i/os-core/ %s",
image_dir, newversion, full_dir);
ret = system(command);
assert(ret == 0);
free(command);
string_or_die(&param, "%s/%i/os-core/", image_dir, newversion);
char *const rsynccmd[] = { "rsync", "-aAX", param, full_dir, NULL };
if (system_argv(rsynccmd) != 0) {
assert(0);
}
free(param);
/* overlay any new files from each group */
while (1) {
@@ -59,31 +59,12 @@ void chroot_create_full(int newversion)
}
LOG(NULL, "Overlaying bundle chroot onto full", "%s", group);
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);
}
/* and since some dumb files have things like install timestamps in
* them, we pull files from full back to bundles so each instance
* of the "same" file is truly identical across bundles. It may
* make sense at some point to add more logic here for conflict
* detection and resolution, including work to insure renames are
* consistent across groups. */
while (1) {
group = next_group();
if (!group) {
break;
string_or_die(&param, "%s/%i/%s/", image_dir, newversion, group);
char *const rsynccmd[] = { "rsync", "-aAX", "--ignore-existing", param, full_dir, NULL };
if (system_argv(rsynccmd) != 0) {
assert(0);
}
LOG(NULL, "Recopy bundle chroot out of full", "%s", 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);
free(param);
}
free(full_dir);
}
+34 -13
View File
@@ -146,7 +146,7 @@ static void populate_dirs(int version)
if ((access(newversiondir, F_OK | R_OK) != 0) && (version == 0)) {
char *latestpath = NULL;
string_or_die(&latestpath, "%s/latest.version", image_dir);
string_or_die(&latestpath, "%s/LAST_VER", image_dir);
printf("** %s does not exist... creating and populating\n", newversiondir);
if (mkdir(newversiondir, 0755) != 0) {
@@ -212,6 +212,25 @@ static int check_build_env(void)
return 0;
}
static int check_group_file(void)
{
int ret = -1;
// Ensure the os-core group is defined
while (1) {
char *group = next_group();
if (!group) {
break;
}
if (strcmp(group, "os-core") == 0) {
ret = 0;
break;
}
}
return ret;
}
int main(int argc, char **argv)
{
struct manifest *new_core = NULL;
@@ -270,8 +289,13 @@ int main(int argc, char **argv)
string_or_die(&file_path, "%s/groups.ini", state_dir);
read_group_file(file_path);
free(file_path);
ret = check_group_file();
if (ret != 0) {
printf("os-core bundle is not listed in groups.ini, this is required.\n");
goto exit;
}
read_current_version("latest.version");
read_current_version("LAST_VER");
printf("Last processed version is %i\n", current_version);
populate_dirs(newversion);
@@ -288,7 +312,7 @@ int main(int argc, char **argv)
printf("Syncing bundle chroots with full chroot\n");
chroot_create_full(newversion);
print_elapsed_time(&previous_time, &current_time);
print_elapsed_time("full chroot creation", &previous_time, &current_time);
printf("Calculating full manifest (this is expensive/slow)\n");
old_full = manifest_from_file(current_version, "full");
@@ -307,7 +331,7 @@ int main(int argc, char **argv)
#warning disabled rename detection for some simplicity
// rename_detection(new_full);
print_elapsed_time(&previous_time, &current_time);
print_elapsed_time("full manifest creation", &previous_time, &current_time);
printf("Entering phase 2: Doing the os-core bundle\n");
/* Phase 2 : the os-core set */
@@ -342,9 +366,9 @@ int main(int argc, char **argv)
/* Detect renamed files specifically for each pack */
// rename_detection(...);
old_deleted = remove_old_deleted_files(old_core, new_core);
sort_manifest_by_version(new_core);
newfiles = prune_manifest(new_core);
old_deleted = remove_old_deleted_files(old_core, new_core);
if (newfiles <= 0) {
LOG(NULL, "", "Core component has not changed (after pruning), exiting");
printf("Core component has not changed (after pruning), exiting\n");
@@ -357,7 +381,6 @@ int main(int argc, char **argv)
printf("Core component manifest write failed\n");
goto exit;
}
create_manifest_deltas(new_core, manifests_last_versions_list);
}
nest_manifest(new_MoM, new_core);
@@ -446,10 +469,10 @@ int main(int argc, char **argv)
apply_heuristics(newm);
#warning missing rename_detection here
/* Step 6b: otherwise, write out the manifest */
old_deleted = remove_old_deleted_files(oldm, newm);
sort_manifest_by_version(newm);
type_change_detection(newm);
newfiles = prune_manifest(newm);
old_deleted = remove_old_deleted_files(oldm, newm);
if (newfiles > 0 || old_deleted > 0 || changed_includes(oldm, newm)) {
LOG(NULL, "", "%s component has changes (%d new, %d deleted), writing out new manifest", group, newfiles, old_deleted);
printf("%s component has changes (%d new, %d deleted), writing out new manifest\n", group, newfiles, old_deleted);
@@ -458,7 +481,6 @@ int main(int argc, char **argv)
printf("%s component manifest write failed\n", group);
goto exit;
}
create_manifest_deltas(newm, manifests_last_versions_list);
} else {
LOG(NULL, "", "%s component has not changed (after pruning), no new manifest", group);
printf("%s component has not changed (after pruning), no new manifest\n", group);
@@ -469,7 +491,7 @@ int main(int argc, char **argv)
nest_manifest(new_MoM, newm);
}
print_elapsed_time(&previous_time, &current_time);
print_elapsed_time("bundle manifest creation", &previous_time, &current_time);
printf("Entering phase 4: completion manifests \n");
/* Phase 4 : manifest completion */
@@ -480,9 +502,8 @@ int main(int argc, char **argv)
printf("Failed to write new MoM\n");
goto exit;
}
create_manifest_deltas(new_MoM, manifests_last_versions_list);
print_elapsed_time(&previous_time, &current_time);
print_elapsed_time("MoM creation", &previous_time, &current_time);
printf("Entering phase 5: creating download content\n");
/* Phase 5: wrapping up */
@@ -499,13 +520,13 @@ int main(int argc, char **argv)
/* Step 8: Prepare delta directory */
prepare_delta_dir(new_full);
print_elapsed_time(&previous_time, &current_time);
print_elapsed_time("finalize update", &previous_time, &current_time);
exit_status = EXIT_SUCCESS;
exit:
if (exit_status == EXIT_SUCCESS) {
write_cookiecrumbs_to_download_area(newversion);
//write_new_version("latest.version", newversion);
//write_new_version("LAST_VER", newversion);
}
release_configuration_data();
release_group_file();
+10 -12
View File
@@ -35,10 +35,9 @@
#include "swupd.h"
#include "xattrs.h"
void __create_delta(struct file *file, int from_version)
void __create_delta(struct file *file, int from_version, char *from_hash)
{
char *original, *newfile, *outfile, *dotfile, *testnewfile, *sanitycheck;
char *conf;
char *original, *newfile, *outfile, *dotfile, *testnewfile, *conf;
int ret;
if (file->is_link) {
@@ -62,10 +61,9 @@ void __create_delta(struct file *file, int from_version)
conf = config_output_dir();
string_or_die(&outfile, "%s/%i/delta/%i-%i-%s", conf, file->last_change, from_version, file->last_change, file->hash);
string_or_die(&dotfile, "%s/%i/delta/.%i-%i-%s", conf, file->last_change, from_version, file->last_change, file->hash);
string_or_die(&testnewfile, "%s/%i/delta/.%i-%i-%s.testnewfile", conf, file->last_change, from_version, file->last_change, file->hash);
string_or_die(&sanitycheck, "cmp -s \"%s\" \"%s\"", newfile, testnewfile);
string_or_die(&outfile, "%s/%i/delta/%i-%i-%s-%s", conf, file->last_change, from_version, file->last_change, from_hash, file->hash);
string_or_die(&dotfile, "%s/%i/delta/.%i-%i-%s-%s", conf, file->last_change, from_version, file->last_change, from_hash, file->hash);
string_or_die(&testnewfile, "%s/%i/delta/.%i-%i-%s-%s.testnewfile", conf, file->last_change, from_version, file->last_change, from_hash, file->hash);
LOG(file, "Making delta", "%s->%s", original, newfile);
@@ -99,7 +97,7 @@ void __create_delta(struct file *file, int from_version)
ret = 0;
goto out;
}
xattrs_copy(original, newfile);
xattrs_copy(original, testnewfile);
/* does xattrs have been correctly copied?*/
if (xattrs_compare(original, testnewfile) != 0) {
@@ -110,13 +108,14 @@ void __create_delta(struct file *file, int from_version)
goto out;
}
ret = system(sanitycheck);
if (ret == -1 || !WIFEXITED(ret) || WEXITSTATUS(ret) == 2) {
char *const sanitycheck[] = { "cmp", "-s", newfile, testnewfile, NULL };
ret = system_argv(sanitycheck);
if (ret == -1 || ret == 2) {
printf("Sanity check system command failed %i. \n", ret);
printf("%s->%s via diff %s yielded %s\n", original, newfile, dotfile, testnewfile);
assert(0);
goto out;
} else if (WEXITSTATUS(ret) == 1) {
} else if (ret == 1) {
printf("Delta application resulted in file mismatch %i. \n", ret);
printf("%s->%s via diff %s yielded %s\n", original, newfile, dotfile, testnewfile);
LOG(file, "Delta mismatch:", "%s->%s via diff %s yielded %s", original, newfile, dotfile, testnewfile);
@@ -137,7 +136,6 @@ void __create_delta(struct file *file, int from_version)
LOG(NULL, "Failed to rename", "");
}
out:
free(sanitycheck);
free(testnewfile);
free(conf);
free(newfile);
+50 -32
View File
@@ -24,6 +24,7 @@
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <libgen.h>
#include <stdint.h>
@@ -41,7 +42,6 @@
static void create_fullfile(struct file *file)
{
char *origin;
char *tarcommand = NULL;
char *tarname = NULL;
char *rename_source = NULL;
char *rename_target = NULL;
@@ -49,6 +49,8 @@ static void create_fullfile(struct file *file)
int ret;
struct stat sbuf;
char *empty, *indir, *outdir;
char *param1, *param2;
int stderrfd;
if (file->is_deleted) {
return; /* file got deleted -> by definition we cannot tar it up */
@@ -91,13 +93,22 @@ static void create_fullfile(struct file *file)
assert(0);
}
string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -cf - --exclude='%s/?*' './%s' 2> /dev/null | " TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -xf - 2> /dev/null",
dir, base, base, rename_tmpdir);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
string_or_die(&param1, "--exclude=%s/?*", base);
string_or_die(&param2, "./%s", base);
char *const tarcfcmd[] = { TAR_COMMAND, "-C", dir, TAR_PERM_ATTR_ARGS_STRLIST, "-cf", "-", param1, param2, NULL };
char *const tarxfcmd[] = { TAR_COMMAND, "-C", rename_tmpdir, TAR_PERM_ATTR_ARGS_STRLIST, "-xf", "-", NULL };
stderrfd = open("/dev/null", O_WRONLY);
if (stderrfd == -1) {
LOG(NULL, "Failed to open /dev/null", "");
assert(0);
}
free(tarcommand);
if (system_argv_pipe(tarcfcmd, -1, stderrfd, tarxfcmd, -1, stderrfd) != 0) {
assert(0);
}
free(param1);
free(param2);
close(stderrfd);
string_or_die(&rename_source, "%s/%s", rename_tmpdir, base);
string_or_die(&rename_target, "%s/%s", rename_tmpdir, file->hash);
@@ -108,13 +119,13 @@ static void create_fullfile(struct file *file)
free(rename_source);
/* for a directory file, tar up simply with gzip */
string_or_die(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar %s",
rename_tmpdir, outdir, file->last_change, file->hash, file->hash);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
string_or_die(&param1, "%s/%i/files/%s.tar", outdir, file->last_change, file->hash);
char *const tarcmd[] = { TAR_COMMAND, "-C", rename_tmpdir, TAR_PERM_ATTR_ARGS_STRLIST, "-zcf", param1, file->hash, NULL };
if (system_argv(tarcmd) != 0) {
assert(0);
}
free(tarcommand);
free(param1);
if (rmdir(rename_target)) {
LOG(NULL, "rmdir failed for %s", rename_target);
@@ -123,6 +134,7 @@ static void create_fullfile(struct file *file)
if (rmdir(rename_tmpdir)) {
LOG(NULL, "rmdir failed for %s", rename_tmpdir);
}
free(rename_tmpdir);
free(tmp1);
free(tmp2);
@@ -143,29 +155,38 @@ static void create_fullfile(struct file *file)
/* step 2a: tar it with each compression type */
// lzma
string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -Jcf %s/%i/files/%s.tar.xz %s",
empty, outdir, file->last_change, file->hash, file->hash);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
string_or_die(&param1, "--directory=%s", empty);
string_or_die(&param2, "%s/%i/files/%s.tar.xz", outdir, file->last_change, file->hash);
char *const tarlzmacmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-Jcf", param2, file->hash, NULL };
if (system_argv(tarlzmacmd) != 0) {
assert(0);
}
free(tarcommand);
free(param1);
free(param2);
// gzip
string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -zcf %s/%i/files/%s.tar.gz %s",
empty, outdir, file->last_change, file->hash, file->hash);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
string_or_die(&param1, "--directory=%s", empty);
string_or_die(&param2, "%s/%i/files/%s.tar.gz", outdir, file->last_change, file->hash);
char *const targzipcmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-zcf", param2, file->hash, NULL };
if (system_argv(targzipcmd) != 0) {
assert(0);
}
free(tarcommand);
free(param1);
free(param2);
#ifdef SWUPD_WITH_BZIP2
string_or_die(&tarcommand, TAR_COMMAND " --directory=%s " TAR_PERM_ATTR_ARGS " -jcf %s/%i/files/%s.tar.bz2 %s",
empty, outdir, file->last_change, file->hash, file->hash);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
string_or_die(&param1, "--directory=%s", empty);
string_or_die(&param2, "%s/%i/files/%s.tar.bz2", outdir, file->last_change, file->hash);
char *const tarbzip2cmd[] = { TAR_COMMAND, param1, TAR_PERM_ATTR_ARGS_STRLIST, "-jcf", param2, file->hash, NULL };
if (system_argv(tarbzip2cmd) != 0) {
assert(0);
}
free(tarcommand);
free(param1);
free(param2);
#endif
/* step 2b: pick the smallest of the three compression formats */
@@ -231,7 +252,7 @@ static GList *get_deduplicated_fullfile_list(struct manifest *manifest)
manifest->files = g_list_sort(manifest->files, file_sort_hash);
list = g_list_first(manifest->files);
while (prev == NULL) {
while (prev == NULL && list != NULL) {
tmp = list->data;
list = g_list_next(list);
@@ -301,17 +322,14 @@ void create_fullfiles(struct manifest *manifest)
{
GList *deduped_file_list;
char *path;
char *cmd;
char *conf, *empty;
empty = config_empty_dir();
string_or_die(&cmd, "rm -rf %s", empty);
if (system(cmd) != 0) {
LOG(NULL, "Failed to run command:", "%s", cmd);
char *const rmcmd[] = { "rm", "-rf", empty, NULL };
if (system_argv(rmcmd) != 0) {
assert(0);
}
free(cmd);
g_mkdir_with_parents(empty, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
free(empty);
+7
View File
@@ -51,6 +51,13 @@ char *group_groups(char *group)
return g_key_file_get_value(groupfile, group, "groups", NULL);
}
char *group_status(char *group)
{
assert(groupfile != NULL);
return g_key_file_get_value(groupfile, group, "status", NULL);
}
void read_group_file(char *filename)
{
GError *error = NULL;
+96 -7
View File
@@ -101,22 +101,27 @@ void string_or_die(char **strp, const char *fmt, ...)
va_list ap;
va_start(ap, fmt);
if (vasprintf(strp, fmt, ap) <= 0) {
if (vasprintf(strp, fmt, ap) < 0) {
assert(0);
}
va_end(ap);
}
void print_elapsed_time(struct timeval *previous_time, struct timeval *current_time)
/* "step" should be a descriptive string for the process that completed before
* this function is called */
void print_elapsed_time(const char *step, struct timeval *previous_time,
struct timeval *current_time)
{
char *elapsed;
assert(strlen(step) > 0);
gettimeofday(current_time, NULL);
elapsed = get_elapsed_time(previous_time, current_time);
if (strcmp(elapsed, " ") == 0) {
printf("\t~0.0 elapsed for Manifest.full creation\n");
printf("\t~0.0 elapsed for '%s' step\n", step);
} else {
printf("\t%s elapsed for full chroot creation\n", elapsed);
printf("\t%s elapsed for '%s' step\n", elapsed, step);
}
previous_time->tv_sec = current_time->tv_sec;
previous_time->tv_usec = current_time->tv_usec;
@@ -148,7 +153,7 @@ int system_argv(char *const argv[])
{
int child_exit_status;
pid_t pid;
int status;
int status = -1;
pid = fork();
@@ -181,9 +186,93 @@ int system_argv(char *const argv[])
LOG(NULL, "Failed to run command:", "%s", cmdline);
free(cmdline);
}
return status;
}
return status;
}
int system_argv_fd(char *const argv[], int newstdin, int newstdout, int newstderr)
{
int child_exit_status;
pid_t pid;
int status = -1;
pid = fork();
if (pid == 0) { /* child */
if (newstdin >= 0) {
if (dup2(newstdin, STDIN_FILENO) == -1) {
LOG(NULL, "Could not redirect stdin", "");
assert(0);
}
close(newstdin);
}
if (newstdout >= 0) {
if (dup2(newstdout, STDOUT_FILENO) == -1) {
LOG(NULL, "Could not redirect stdout", "");
assert(0);
}
close(newstdout);
}
if (newstderr >= 0) {
if (dup2(newstderr, STDERR_FILENO) == -1) {
LOG(NULL, "Could not redirect stderr", "");
assert(0);
}
close(newstderr);
}
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;
}
int system_argv_pipe(char *const argvp1[], int stdinp1, int stderrp1,
char *const argvp2[], int stdoutp2, int stderrp2)
{
int statusp2;
int pipefd[2];
if (pipe(pipefd)) {
LOG(NULL, "Failed to create a pipe", "");
return -1;
}
system_argv_fd(argvp1, stdinp1, pipefd[1], stderrp1);
close(pipefd[1]);
statusp2 = system_argv_fd(argvp2, pipefd[0], stdoutp2, stderrp2);
close(pipefd[0]);
/* Returns the status of the failed process if any
If both processes failed returns the status of first one */
return statusp2;
}
void check_root(void)
+9 -9
View File
@@ -44,15 +44,15 @@ static void runtime_state_heuristics(struct file *file)
{
/* these are shipped directories that are not themselves state,
* rather only their contents are state */
if ((strcmp(file->filename, "/usr/src/debug") == 0) ||
(strcmp(file->filename, "/dev") == 0) ||
(strcmp(file->filename, "/home") == 0) ||
(strcmp(file->filename, "/proc") == 0) ||
(strcmp(file->filename, "/root") == 0) ||
(strcmp(file->filename, "/run") == 0) ||
(strcmp(file->filename, "/sys") == 0) ||
(strcmp(file->filename, "/tmp") == 0) ||
(strcmp(file->filename, "/var") == 0)) {
if ((strncmp(file->filename, "/usr/src/debug", 14) == 0) ||
(strncmp(file->filename, "/dev", 4) == 0) ||
(strncmp(file->filename, "/home", 5) == 0) ||
(strncmp(file->filename, "/proc", 5) == 0) ||
(strncmp(file->filename, "/root", 5) == 0) ||
(strncmp(file->filename, "/run", 4) == 0) ||
(strncmp(file->filename, "/sys", 4) == 0) ||
(strncmp(file->filename, "/tmp", 4) == 0) ||
(strncmp(file->filename, "/var", 4) == 0)) {
return;
}
+67 -20
View File
@@ -64,7 +64,7 @@ int file_sort_version(gconstpointer a, gconstpointer b)
return 1;
}
return strcmp(B->filename, A->filename);
return strcmp(A->filename, B->filename);
}
int file_sort_filename(gconstpointer a, gconstpointer b)
@@ -728,7 +728,10 @@ static int write_manifest_plain(struct manifest *manifest)
char *base = NULL, *dir;
char *conf = config_output_dir();
char *filename = NULL;
char *status = NULL;
char *submanifest_filename = NULL;
char *manifest_tempdir = NULL;
char *tempmanifest = NULL;
int ret = -1;
if (conf == NULL) {
@@ -760,6 +763,10 @@ static int write_manifest_plain(struct manifest *manifest)
compute_content_size(manifest);
fprintf(out, "contentsize:\t%llu\n", (long long unsigned int)manifest->contentsize);
includes = manifest->includes;
status = group_status(manifest->component);
if (status) {
fprintf(out, "status:\t%s\n", status);
}
while (includes) {
struct manifest *sub = includes->data;
includes = g_list_next(includes);
@@ -776,24 +783,61 @@ static int write_manifest_plain(struct manifest *manifest)
}
list = g_list_first(manifest->manifests);
string_or_die(&manifest_tempdir, "%s/XXXXXX", state_dir);
if (!mkdtemp(manifest_tempdir)) {
LOG(NULL, "Failed to create temporary directory %s for untarring Manifests", manifest_tempdir);
assert(0);
}
while (list) {
file = list->data;
list = g_list_next(list);
string_or_die(&submanifest_filename, "%s/%i/Manifest.%s", conf, file->last_change, file->filename);
populate_file_struct(file, submanifest_filename);
ret = compute_hash(file, submanifest_filename);
if (file->is_deleted) {
goto write_entry;
}
char *param1, *param2;
/* Untar the Manifest.BUNDLE.tar and calculate the hash on that,
* otherwise we may get incorrect hashes due to owner permissions on
* the files. */
string_or_die(&param1, "%s", manifest_tempdir);
string_or_die(&param2, "%s.tar", submanifest_filename);
char *const tarcmd[] = { TAR_COMMAND, "-C", param1, TAR_PERM_ATTR_ARGS_STRLIST, "-xf", param2, NULL };
ret = system_argv(tarcmd);
free(param1);
free(param2);
if (ret != 0) {
assert(0);
}
string_or_die(&tempmanifest, "%s/Manifest.%s", manifest_tempdir, file->filename);
populate_file_struct(file, tempmanifest);
ret = compute_hash(file, tempmanifest);
if (ret != 0) {
printf("Hash computation failed\n");
assert(0);
}
unlink(tempmanifest);
free(tempmanifest);
write_entry:
fprintf(out, "%s\t%s\t%i\t%s\n", file_type_to_string(file), file->hash, file->last_change, file->filename);
free(submanifest_filename);
}
ret = 0;
exit:
if (manifest_tempdir) {
if (rmdir(manifest_tempdir) != 0) {
LOG(NULL, "rmdir failed for %s: %s", manifest_tempdir, strerror(errno));
}
free(manifest_tempdir);
}
if (out) {
fclose(out);
}
@@ -807,34 +851,37 @@ exit:
static int write_manifest_tar(struct manifest *manifest)
{
char *conf = config_output_dir();
char *tarcmd = NULL;
int ret = -1;
char *directory, *manifesttar, *manifestcomp, *manifestsigned;
int ret = 0;
if (conf == NULL) {
assert(0);
}
string_or_die(&directory, "--directory=%s/%i", conf, manifest->version);
string_or_die(&manifesttar, "%s/%i/Manifest.%s.tar", conf, manifest->version, manifest->component);
string_or_die(&manifestcomp, "Manifest.%s", manifest->component);
string_or_die(&manifestsigned, "Manifest.%s.signed", manifest->component);
/* now, tar the thing up for efficient full file download */
/* and put the signature of the plain manifest into the archive, too */
if (enable_signing) {
string_or_die(&tarcmd, TAR_COMMAND " --directory=%s/%i " TAR_PERM_ATTR_ARGS " -Jcf "
"%s/%i/Manifest.%s.tar Manifest.%s Manifest.%s.signed",
conf, manifest->version, conf, manifest->version, manifest->component,
manifest->component, manifest->component);
char *const tarcmd[] = { TAR_COMMAND, directory, TAR_PERM_ATTR_ARGS_STRLIST, "-Jcf",
manifesttar, manifestcomp, manifestsigned, NULL };
ret = system_argv(tarcmd);
} else {
string_or_die(&tarcmd, TAR_COMMAND " --directory=%s/%i " TAR_PERM_ATTR_ARGS " -Jcf "
"%s/%i/Manifest.%s.tar Manifest.%s",
conf, manifest->version, conf, manifest->version, manifest->component,
manifest->component);
char *const tarcmd[] = { TAR_COMMAND, directory, TAR_PERM_ATTR_ARGS_STRLIST, "-Jcf",
manifesttar, manifestcomp, NULL };
ret = system_argv(tarcmd);
}
if (ret) {
fprintf(stderr, "Creation of Manifest.tar failed\n");
}
if (system(tarcmd) != 0) {
fprintf(stderr, "Creation of Manifest.tar failed\n");
goto exit;
}
ret = 0;
exit:
free(tarcmd);
free(directory);
free(manifesttar);
free(manifestcomp);
free(manifestsigned);
free(conf);
return ret;
}
+37 -32
View File
@@ -40,21 +40,19 @@
static void empty_pack_stage(int full, int from_version, int to_version, char *module)
{
char *cmd;
char *param;
char *path;
int ret;
// clean any stale data (eg: re-run after a failure)
string_or_die(&cmd, "rm -rf %s/%s/%i_to_%i/", packstage_dir, module,
from_version, to_version);
ret = system(cmd);
if (ret) {
string_or_die(&param, "%s/%s/%i_to_%i/", packstage_dir, module, from_version, to_version);
char *const rmcmd[] = { "rm", "-fr", param, NULL };
if (system_argv(rmcmd) != 0) {
fprintf(stderr, "Failed to clean %s/%s/%i_to_%i\n",
packstage_dir, module, from_version, to_version);
free(cmd);
free(param);
exit(EXIT_FAILURE);
}
free(cmd);
free(param);
if (!full) {
// (re)create module/version/{delta,staged}
@@ -89,7 +87,7 @@ static void explode_pack_stage(int from_version, int to_version, char *module)
}
free(path);
while (1) {
char *path, *tar;
char *path, *param;
int ret;
entry = readdir(dir);
@@ -117,13 +115,12 @@ static void explode_pack_stage(int from_version, int to_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_COMMAND " --directory=%s/%s/%i_to_%i/staged " TAR_WARN_ARGS " " TAR_PERM_ATTR_ARGS " -xf %s",
packstage_dir, module, from_version, to_version, path);
ret = system(tar);
if (!ret) {
string_or_die(&param, "%s/%s/%i_to_%i/staged", packstage_dir, module, from_version, to_version);
char *const tarcmd[] = { TAR_COMMAND, "-C", param, TAR_WARN_ARGS, TAR_PERM_ATTR_ARGS_STRLIST, "-xf", path, NULL };
if (system_argv(tarcmd) == 0) {
unlink(path);
}
free(tar);
free(param);
free(path);
}
closedir(dir);
@@ -257,8 +254,8 @@ static GList *consolidate_packs_delta_files(GList *files, struct packdata *pack)
continue;
}
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(&from, "%s/%i/delta/%i-%i-%s-%s", staging_dir, file->last_change,
file->peer->last_change, file->last_change, file->peer->hash, file->hash);
ret = stat(from, &stat_delta);
if (ret && !find_file_in_list(files, file)) {
@@ -277,7 +274,7 @@ static void create_delta(gpointer data, __unused__ gpointer user_data)
/* if the file was not found in the from version, skip delta creation */
if (file->peer) {
__create_delta(file, file->peer->last_change);
__create_delta(file, file->peer->last_change, file->peer->hash);
}
}
@@ -334,7 +331,7 @@ static int make_final_pack(struct packdata *pack)
GList *item;
struct file *file;
int ret;
char *tar;
char *param1, *param2;
double penalty;
LOG(NULL, "make_final_pack", "%s: %i to %i", pack->module, pack->from, pack->to);
@@ -356,11 +353,11 @@ 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, "%s/%i/delta/%i-%i-%s", staging_dir, file->last_change,
file->peer->last_change, file->last_change, file->hash);
string_or_die(&to, "%s/%s/%i_to_%i/delta/%i-%i-%s", packstage_dir,
string_or_die(&from, "%s/%i/delta/%i-%i-%s-%s", staging_dir, file->last_change,
file->peer->last_change, file->last_change, file->peer->hash, file->hash);
string_or_die(&to, "%s/%s/%i_to_%i/delta/%i-%i-%s-%s", packstage_dir,
pack->module, pack->from, pack->to, file->peer->last_change,
file->last_change, file->hash);
file->last_change, file->peer->hash, 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_to_%i/staged/%s.tar", packstage_dir,
@@ -438,6 +435,8 @@ static int make_final_pack(struct packdata *pack)
explode_pack_stage(pack->from, pack->to, pack->module);
}
char *bundle_delta = NULL;
/* now... link in the Manifest pack */
if (pack->from != 0) {
char *from, *to;
@@ -457,14 +456,18 @@ static int make_final_pack(struct packdata *pack)
ret = link(from, to);
if (ret) {
LOG(NULL, "Failed to link", "Manifest-delta-from-%i", pack->from);
LOG(NULL, "Failed to link", "Manifest-%s-delta-from-%i (%s)", pack->module, pack->from, strerror(errno));
} else {
string_or_die(&bundle_delta, "Manifest-%s-delta-from-%i", pack->module, pack->from);
}
free(from);
free(to);
}
/* now... link in the MoM Manifest into the base pack */
char *mom_delta = NULL;
/* now... link in the MoM Manifest into the os-core pack */
if ((pack->from != 0) && (strcmp(pack->module, "os-core") == 0)) {
char *from, *to;
struct stat st;
@@ -482,7 +485,9 @@ static int make_final_pack(struct packdata *pack)
ret = link(from, to);
if (ret) {
LOG(NULL, "Failed to link", "Manifest-delta-from-%i", pack->from);
LOG(NULL, "Failed to link", "Manifest-MoM-delta-from-%i (%s)", pack->from, strerror(errno));
} else {
string_or_die(&mom_delta, "Manifest-MoM-delta-from-%i", pack->from);
}
free(from);
@@ -491,15 +496,15 @@ 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_COMMAND " " TAR_PERM_ATTR_ARGS " --directory=%s/%s/%i_to_%i/ "
"--numeric-owner -Jcf %s/%i/pack-%s-from-%i.tar delta staged",
packstage_dir, pack->module, pack->from, pack->to, staging_dir, pack->to,
pack->module, pack->from);
ret = system(tar);
free(tar);
string_or_die(&param1, "%s/%s/%i_to_%i/", packstage_dir, pack->module, pack->from, pack->to);
string_or_die(&param2, "%s/%i/pack-%s-from-%i.tar", staging_dir, pack->to, pack->module, pack->from);
char *const tarcmd[] = { TAR_COMMAND, "-C", param1, TAR_PERM_ATTR_ARGS_STRLIST, "--numeric-owner", "-Jcf", param2, "delta", "staged", bundle_delta, mom_delta, NULL };
ret = system_argv(tarcmd);
free(param1);
free(param2);
LOG(NULL, "finished tar for pack", "%s: %i to %i", pack->module, pack->from, pack->to);
/* FIXME: this is a hack workaround, needs diagnosed and removed */
if ((ret != 0) && (ret != 256)) {
if ((ret != 0) && (ret != 1)) {
fprintf(stderr, "Unexpected return value (%d) creating tar of pack %s from %i to %i\n",
ret, pack->module, pack->from, pack->to);
} else {
+13 -11
View File
@@ -35,10 +35,6 @@
static char *make_filename(const char *, const char *, const char *);
static const char *CMD_FMT = "openssl smime -sign -in %s -binary "
"-out %s.signed -outform PEM -md sha256 -inkey %s -signer %s "
"-certfile %s -passin file:%s";
static char *leaf_key = NULL;
static char *leaf_cert = NULL;
static char *ca_chain_cert = NULL;
@@ -150,7 +146,7 @@ void signature_terminate(void)
*/
bool signature_sign(const char *filename)
{
char *cmd = NULL;
char *param1, *param2;
int status;
if (!enable_signing) {
@@ -160,12 +156,18 @@ bool signature_sign(const char *filename)
if (!initialized) {
return false;
}
string_or_die(&cmd, CMD_FMT, filename, filename, leaf_key, leaf_cert,
ca_chain_cert, passphrase);
status = system(cmd);
if (status) {
printf("Bad status %d from signing command:%s\n", status, cmd);
string_or_die(&param1, "%s.signed", filename);
string_or_die(&param2, "file:%s", passphrase);
char *const opensslcmd[] = { "openssl", "smime", "-sign", "-in", (char *)filename, "-binary",
"-out", param1, "-outform", " PEM", "-md", "sha256", "-inkey",
leaf_key, "-signer", leaf_cert, "-certfile", ca_chain_cert,
"-passin", param2, NULL };
status = system_argv(opensslcmd);
if (status != 0) {
printf("Bad status %d from signing command\n", status);
}
free(cmd);
free(param1);
free(param2);
return status == 0;
}
+41 -12
View File
@@ -27,6 +27,7 @@
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
@@ -126,35 +127,63 @@ void ensure_version_image_exists(int version)
void write_cookiecrumbs_to_download_area(int version)
{
char *conf;
char *cmd;
char *filename, *strformat;
FILE *versionfd, *formatfd;
conf = config_output_dir();
if (conf == NULL) {
assert(0);
}
string_or_die(&cmd, "echo %s > %s/%i/swupd-server-src-version", VERSION, conf, version);
if (system(cmd) != 0) {
string_or_die(&filename, "%s/%i/swupd-server-src-version", conf, version);
versionfd = fopen(filename, "w");
if (versionfd == NULL) {
assert(0);
}
free(cmd);
string_or_die(&cmd, "echo %llu > %s/%i/format", format, conf, version);
if (system(cmd) != 0) {
if (fwrite(VERSION, 1, strlen(VERSION), versionfd) != strlen(VERSION)) {
assert(0);
}
free(cmd);
fclose(versionfd);
free(filename);
/* written from pack_maker.sh */
string_or_die(&filename, "%s/%i/format", conf, version);
string_or_die(&strformat, "%llu", format);
formatfd = fopen(filename, "w");
if (formatfd == NULL) {
assert(0);
}
if (fwrite(strformat, 1, strlen(strformat), formatfd) != strlen(strformat)) {
assert(0);
}
fclose(formatfd);
free(filename);
free(strformat);
/* Updating the WEBDIR/version/formatN/latest file is an operation very closely tied to a DevOps
* workflow and not something swupd should make a decision about.
*
* The supported format values (replacing the "N" in the path above) are:
*
* - "staging": intended for testing only
* - [1-+inf] (positive integer): the number that a corresponding version of swupd-client
* understands to run software updates. For example, if a given swupd-client release understands
* format 1, then WEBDIR/version/format1/latest contains the value of most recent release that
* that swupd-client can update to.
*
* Adapt this step appropriately for your DevOps flow.
*/
#if 0
FILE *file;
char *fullfile = NULL;
char *param;
string_or_die(&cmd, "mkdir -p %s/version/formatstaging/", conf);
if (system(cmd) != 0) {
string_or_die($param, "%s/version/formatstaging/", conf);
char *const mkdircmd[] = { "mkdir", "-p", param, NULL };
if (system_argv(mkdircmd) != 0) {
assert(0);
}
free(cmd);
free(param);
string_or_die(&fullfile, "%s/version/formatstaging/latest", conf);
file = fopen(fullfile, "w");
@@ -1,23 +1,25 @@
#!/usr/bin/env bats
load "../swupdlib"
@test "create_update help output" {
run $srcdir/swupd_create_update --help
run $CREATE_UPDATE --help
[ "$status" -eq 1 ]
run $srcdir/swupd_create_update -h
run $CREATE_UPDATE -h
[ "$status" -eq 1 ]
}
@test "make_fullfiles help output" {
run $srcdir/swupd_make_fullfiles --help
run $MAKE_FULLFILES --help
[ "$status" -eq 1 ]
run $srcdir/swupd_make_fullfiles -h
run $MAKE_FULLFILES -h
[ "$status" -eq 1 ]
}
@test "make_pack help output" {
run $srcdir/swupd_make_pack --help
run $MAKE_PACK --help
[ "$status" -eq 1 ]
run $srcdir/swupd_make_pack -h
run $MAKE_PACK -h
[ "$status" -eq 1 ]
}
@@ -1,11 +1,11 @@
#!/usr/bin/env bats
# common functions
load swupdlib
load "../swupdlib"
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
clean_test_dir
init_test_dir
init_server_ini
set_latest_ver 0
@@ -32,21 +32,17 @@ setup() {
}
@test "delete no version bump update creation" {
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 10
sudo $CREATE_UPDATE --osversion 10 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 10
set_latest_ver 10
sudo $srcdir/swupd_create_update --osversion 20 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 20
sudo $CREATE_UPDATE --osversion 20 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 20
[ 1 -eq $(grep '10 /foo' $DIR/www/10/Manifest.full | wc -l) ]
[ 1 -eq $(grep '10 /foo' $DIR/www/20/Manifest.full | wc -l) ]
[ 0 -eq $(grep '20 /foo' $DIR/www/20/Manifest.full | wc -l) ]
}
teardown() {
sudo rm -rf $DIR
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bats
# common functions
load "../swupdlib"
setup() {
clean_test_dir
init_test_dir
init_server_ini
set_latest_ver 0
init_groups_ini os-core
set_os_release 10 os-core
track_bundle 10 os-core
gen_file_plain 10 os-core "semicolon;"
}
assert_illegal_char() {
local output="$1"
local str=$(echo "Filename $2 includes illegal character(s)")
[[ "$output" =~ "$str" ]]
}
assert_valid_char() {
local output="$1"
local str=$(echo "Filename $2 includes illegal character(s)")
[[ ! "$output" =~ "$str" ]]
}
@test "file names with blacklisted characters" {
run sudo sh -c "$CREATE_UPDATE --osversion 10 --statedir $DIR --format 3"
echo "$output"
assert_illegal_char "$output" "/semicolon;"
assert_valid_char "$output" "/usr"
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,11 +1,11 @@
#!/usr/bin/env bats
# common functions
load swupdlib
load "../swupdlib"
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
clean_test_dir
init_test_dir
init_server_ini
set_latest_ver 0
@@ -37,22 +37,22 @@ setup() {
@test "full run update creation with delta packs" {
# build the first version
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 10
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 test-bundle
sudo $CREATE_UPDATE --osversion 10 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 10
sudo $MAKE_PACK --statedir $DIR 0 10 os-core
sudo $MAKE_PACK --statedir $DIR 0 10 test-bundle
set_latest_ver 10
# then the second version...
sudo $srcdir/swupd_create_update --osversion 20 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 20
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 test-bundle
sudo $CREATE_UPDATE --osversion 20 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 20
sudo $MAKE_PACK --statedir $DIR 0 20 os-core
sudo $MAKE_PACK --statedir $DIR 0 20 test-bundle
# and with delta packs this time
sudo $srcdir/swupd_make_pack --statedir $DIR 10 20 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 10 20 test-bundle
sudo $MAKE_PACK --statedir $DIR 10 20 os-core
sudo $MAKE_PACK --statedir $DIR 10 20 test-bundle
# zero packs should exist (non-zero size) for both versions
[ -s $DIR/www/10/pack-os-core-from-0.tar ]
@@ -79,10 +79,11 @@ setup() {
[[ 1 -eq $(grep '/foobarbaz$' $DIR/www/20/Manifest.included-nested | wc -l) ]]
[[ 6 -eq $(tar -tf $DIR/www/10/pack-test-bundle-from-0.tar | wc -l) ]]
[[ 4 -eq $(tar -tf $DIR/www/20/pack-test-bundle-from-0.tar | wc -l) ]]
}
teardown() {
sudo rm -rf $DIR
# delta packs should contain appropriate delta manifests
[[ $(tar -tf $DIR/www/20/pack-os-core-from-10.tar | grep '^Manifest-os-core-delta-from-10') ]]
[[ $(tar -tf $DIR/www/20/pack-os-core-from-10.tar | grep '^Manifest-MoM-delta-from-10') ]]
[[ $(tar -tf $DIR/www/20/pack-test-bundle-from-10.tar | grep '^Manifest-test-bundle-delta-from-10') ]]
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,11 +1,11 @@
#!/usr/bin/env bats
# common functions
load swupdlib
load "../swupdlib"
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
clean_test_dir
init_test_dir
init_server_ini
set_latest_ver 0
@@ -20,10 +20,10 @@ setup() {
}
@test "full run update creation" {
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 10
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 test-bundle
sudo $CREATE_UPDATE --osversion 10 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 10
sudo $MAKE_PACK --statedir $DIR 0 10 os-core
sudo $MAKE_PACK --statedir $DIR 0 10 test-bundle
# zero packs should exist (non-zero size) for the build
[ -s $DIR/www/10/pack-os-core-from-0.tar ]
@@ -39,11 +39,7 @@ setup() {
[[ 1 -eq $(grep '/usr/share/clear$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 1 -eq $(grep '/usr/share/clear/bundles$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 4 -eq $(tar -tf $DIR/www/10/pack-test-bundle-from-0.tar | wc -l) ]]
[[ 9 -eq $(tar -tf $DIR/www/10/pack-os-core-from-0.tar | wc -l) ]]
}
teardown() {
sudo rm -rf $DIR
[[ 5 -eq $(tar -tf $DIR/www/10/pack-os-core-from-0.tar | wc -l) ]]
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,18 +1,20 @@
#!/usr/bin/env bats
load "../swupdlib"
@test "make_fullfiles required arg" {
run $srcdir/swupd_make_fullfiles
run $MAKE_FULLFILES
[ "$status" -eq 1 ]
}
@test "make_fullfiles too many arguments" {
# exactly one argument must be passed
run $srcdir/swupd_make_fullfiles foo bar
run $MAKE_FULLFILES foo bar
[ "$status" -eq 1 ]
}
@test "make_fullfiles root priv check" {
run $srcdir/swupd_make_fullfiles foo
run $MAKE_FULLFILES foo
[ "$status" -eq 1 ]
[[ "$output" =~ "not being run as root.. exiting" ]]
}
@@ -1,11 +1,11 @@
#!/usr/bin/env bats
# common functions
load swupdlib
load "../swupdlib"
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
clean_test_dir
init_test_dir
init_server_ini
set_latest_ver 0
@@ -44,31 +44,31 @@ setup() {
@test "full run update creation with delta packs" {
# build the first version
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 10
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 10 test-bundle
sudo $CREATE_UPDATE --osversion 10 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 10
sudo $MAKE_PACK --statedir $DIR 0 10 os-core
sudo $MAKE_PACK --statedir $DIR 0 10 test-bundle
set_latest_ver 10
# then the second version...
sudo $srcdir/swupd_create_update --osversion 20 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 20
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 test-bundle
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 included
sudo $srcdir/swupd_make_pack --statedir $DIR 0 20 included-two
sudo $CREATE_UPDATE --osversion 20 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 20
sudo $MAKE_PACK --statedir $DIR 0 20 os-core
sudo $MAKE_PACK --statedir $DIR 0 20 test-bundle
sudo $MAKE_PACK --statedir $DIR 0 20 included
sudo $MAKE_PACK --statedir $DIR 0 20 included-two
set_latest_ver 20
# then the third version...
sudo $srcdir/swupd_create_update --osversion 30 --statedir $DIR --format 3
sudo $srcdir/swupd_make_fullfiles --statedir $DIR 30
sudo $srcdir/swupd_make_pack --statedir $DIR 0 30 os-core
sudo $srcdir/swupd_make_pack --statedir $DIR 0 30 test-bundle
sudo $srcdir/swupd_make_pack --statedir $DIR 0 30 included
sudo $srcdir/swupd_make_pack --statedir $DIR 0 30 included-two
sudo $srcdir/swupd_make_pack --statedir $DIR 0 30 included-nested
sudo $CREATE_UPDATE --osversion 30 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 30
sudo $MAKE_PACK --statedir $DIR 0 30 os-core
sudo $MAKE_PACK --statedir $DIR 0 30 test-bundle
sudo $MAKE_PACK --statedir $DIR 0 30 included
sudo $MAKE_PACK --statedir $DIR 0 30 included-two
sudo $MAKE_PACK --statedir $DIR 0 30 included-nested
# zero packs should exist (non-zero size) for both versions
[ -s $DIR/www/10/pack-os-core-from-0.tar ]
@@ -96,8 +96,4 @@ setup() {
[[ 0 -eq $(ls $DIR/www/30/Manifest.included-two | wc -l) ]]
}
teardown() {
sudo rm -rf $DIR
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,24 +1,26 @@
#!/usr/bin/env bats
load "../swupdlib"
@test "make_pack required arg" {
run $srcdir/swupd_make_pack
run $MAKE_PACK
[ "$status" -eq 1 ]
}
@test "make_pack too few arguments" {
run $srcdir/swupd_make_pack foo
run $MAKE_PACK foo
[ "$status" -eq 1 ]
run $srcdir/swupd_make_pack foo bar
run $MAKE_PACK foo bar
[ "$status" -eq 1 ]
}
@test "make_pack too many arguments" {
run $srcdir/swupd_make_pack foo bar foo bar
run $MAKE_PACK foo bar foo bar
[ "$status" -eq 1 ]
}
@test "make_pack root priv check" {
run $srcdir/swupd_make_pack foo bar foo
run $MAKE_PACK foo bar foo
[ "$status" -eq 1 ]
[[ "$output" =~ "not being run as root.. exiting" ]]
}
+28 -13
View File
@@ -1,19 +1,33 @@
# NOTE: source this file from a *.bats file
init_web_dir() {
# absolute path is a hard requirement right now
local dir=$(realpath $1)
mkdir -p $dir/{image,www}
echo $dir
# The location of the swupd_* binaries
export SRCDIR="$BATS_TEST_DIRNAME/../../../"
export CREATE_UPDATE="$SRCDIR/swupd_create_update"
export MAKE_FULLFILES="$SRCDIR/swupd_make_fullfiles"
export MAKE_PACK="$SRCDIR/swupd_make_pack"
export DIR="$BATS_TEST_DIRNAME/web-dir"
init_test_dir() {
local testdir="$BATS_TEST_DIRNAME"
mkdir -p "$testdir"/logs
mkdir -p $DIR/{image,www}
# run swupd_* inside the directory to dump the logs
cd "$testdir"/logs
}
clean_test_dir() {
sudo rm -rf $DIR "$BATS_TEST_DIRNAME"/logs
}
init_server_ini() {
cp $srcdir/server.ini $DIR
cp $SRCDIR/server.ini $DIR
sed -i "s|/var/lib/update|$DIR|" $DIR/server.ini
}
set_latest_ver() {
echo "$1" > $DIR/image/latest.version
echo "$1" > $DIR/image/LAST_VER
}
init_groups_ini() {
@@ -21,6 +35,7 @@ init_groups_ini() {
cat >> $DIR/groups.ini << EOF
[$bundle]
group=$bundle
status=ACTIVE
EOF
done
}
@@ -43,9 +58,9 @@ gen_includes_file() {
local bundle=$1
local ver=$2
local includes="${@:3}"
mkdir -p $DIR/www/$ver/noship
mkdir -p $DIR/image/$ver/noship
for b in $includes; do
cat >> $DIR/www/$ver/noship/"$bundle"-includes << EOF
cat >> $DIR/image/$ver/noship/"$bundle"-includes << EOF
$b
EOF
done
@@ -73,21 +88,21 @@ gen_file_to_delta() {
gen_file_plain() {
local ver=$1
local bundle=$2
local name=$3
local name="$3"
# Add plain text file into a bundle
mkdir -p $DIR/image/$ver/$bundle
echo $name > $DIR/image/$ver/$bundle/$name
echo "$name" > $DIR/image/$ver/$bundle/"$name"
}
gen_file_plain_change() {
local ver=$1
local bundle=$2
local name=$3
local name="$3"
# Add plain text file into a bundle
mkdir -p $DIR/image/$ver/$bundle
echo $ver $name > $DIR/image/$ver/$bundle/$name
echo "$ver $name" > $DIR/image/$ver/$bundle/"$name"
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,19 +1,21 @@
#!/usr/bin/env bats
load "../swupdlib"
@test "create_update required format" {
run $srcdir/swupd_create_update
run $CREATE_UPDATE
[ "$status" -eq 1 ]
[[ "$output" =~ "Missing format parameter" ]]
}
@test "create_update required version" {
run $srcdir/swupd_create_update -F 3
run $CREATE_UPDATE -F 3
[ "$status" -eq 1 ]
[[ "$output" =~ "Missing version parameter:" ]]
}
@test "create_update root priv check" {
run $srcdir/swupd_create_update -F 3 -o 10
run $CREATE_UPDATE -F 3 -o 10
[ "$status" -eq 1 ]
[[ "$output" =~ "not being run as root.. exiting" ]]
}