Compare commits

..
37 Commits
Author SHA1 Message Date
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
Patrick McCarty bd002877c1 Release v3.2.0
This release adds support for a bundle includes feature, which allows
bundles that "include" other bundles to depend on each other. This
change reduces duplication of files in manifests and improves build
times for larger bundle sets that contain many includes.

The two other functional changes are:

- The --format option to swupd_create_update is now mandatory.
- The value passed to --format must now be a positive integer.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-05 21:44:00 -07:00
Patrick McCarty cb2706fb72 Move removal of old deleted files to a new function
Since removing of all of the matching deleted files between a build with
an older manifest format and current needs to happen *after*
match_manifests() finishes accounting for new and deleted entries in the
manifests, simply move the logic into a separate function to be called
after match_manifests().

Because one or more file deletions should trigger a fresh bundle manifest
creation, account for the return value of this new function in addition
to the result of manifest pruning and whether any bundle includes were
changed. Since "os-core" is treated specially, and it's expected to
contain changed files for every build, only the non-"os-core" bundle
manifests need the trigger.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-05 21:03:23 -07:00
Patrick McCarty 383ab112db Properly initialize format for new manifests
For the new full manifest and new bundle manifests, the format member
was not being initialized.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-05 16:29:29 -07:00
Patrick McCarty af7767a768 Add required -F option to basic_creator.sh
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-04 19:01:54 -07:00
Patrick McCarty b954d924f4 Update functional test suite for recent changes
For swupd_create_update, the required -F option needed to be added for
several tests, and the option parsing order changed.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-04 18:57:22 -07:00
Patrick McCarty e0049de3dc Fix remaining issues with handling the format number
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-04 18:48:42 -07:00
Patrick McCarty 2a9af990d6 Fix error in the previous rebase
Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-04 14:23:05 -07:00
Patrick McCarty 90c976fdaf Require the -F option for swupd_create_update
To decrease chances of specifying an incorrect format number, since the
default is a hardcoded value "3", always require the user to pass the -F
option to swupd_create_update.

In the future, it would be nice to read the default value from a config
file, with the -F option overriding the value.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-04-04 14:18:15 -07:00
Tim Pepper 3b43313c9e Compare current format versus prior format in manifest match
To better support a workflow for incrementing the format on the command
line, it's useful to have the format be an integer instead of a string.
When reading a manifest (ie: old manifest) we can read that into struct
manifest.  Then when building a new manifest we can compare against the
prior manifest's format.  If the format incremented, we can prune files
previously marked as deleted in the old manifest so they no longer
appear in the new manifest.

This is beneficial because a file that has a version number in its name
will repeatedly be deleted and replaced by a new similar file.  Over
time this leads to manifests getting bigger and bigger because they
retain the entire history of all file names which ever existed, even if
a huge number of them are and have been for a long time marked as
deleted.

Signed-off-by: Tim Pepper <timothy.c.pepper@linux.intel.com>
2016-04-04 14:18:10 -07:00
William Douglas 3d8b81fbcd Fix missing closing comment 2016-03-31 18:50:42 +00:00
William Douglas 9b05b06a9b Fix manifests not detecting include changes
When deciding if a new manifest should be generated for a new version,
the included manifests were not being used to detect a manifest
change. This caused manifests that had new includes: lines in the new
version to not be generated resulting in files from the included
manifest to be missed when adding/updating that bundle.

The fix was to compare includes: lines from the current and previous
manifest versions for differences and generate new manifests when that
was the case. In order to compare manifests duplicate includes: lines
are not allowed and previously os-core could be added multiple times to
a manifest because it was always added. This change also added detection
for os-core before automatically adding it to a bundle.
2016-03-31 18:45:33 +00:00
Patrick McCarty 1cd3cdb96f Update gitignore 2016-03-30 13:08:48 -07:00
William Douglas 9c920d65e8 Don't bump versions for deleted files
In Manifest.full, previously a file being deleted from a bundle caused
the version of the file in Manifest.full to increase incorrectly.
2016-03-29 20:06:57 +00:00
William Douglas 825dc6c75f Add functional tests to validate includes work
Check that os-core is subtracked correctly and that $bundle-includes
files are correctly subtracked as well. Also include testing for new
bundles being subtracked.
2016-03-24 21:17:56 +00:00
William Douglas 4fb32c570f Replace explicit os-core subtraction
Now that much of the includes plumbing present on the output/subtract
side, make sure all non os-core manifests explicitly include os-core,
and then use the new extra semantics of subtract_manifests() to subtract
all included bundles, not just os-core.
2016-03-24 21:17:56 +00:00
William Douglas 79e8a12b75 Populate the manifest->includes list
Using the $bundle-includes files for building submanifests from
directories and previous manifest files includes: sections, create the
manifest->includes list as the names of submanifests included in the
submanifest being instantiated.

This needs to then be processed into a list of pointers to the other
submanifests themselves once all other manifests have been
instantiated before use with functions that operate on the includes list
(subtract_manifest and write_manifest for now)..
2016-03-24 21:17:56 +00:00
William Douglas 9b8b1d5359 Make the subtract_manifests function include-aware
When subtracting a manifest from another, all the included manifests
also will need to be subtracted from the original. To do this build up a
unique list of all manifests included (directly or indirectly) from the
manifest being subtracted from.

With that in place, this gives an opportunity to provide the
functionality of subtracting all included manifests from the main
manifest by calling subtract_manifests(A, A);
2016-03-24 21:17:56 +00:00
William Douglas df7b2adc9d Print included bundles in the manifest header
If a bundle includes one or more other bundles, print out one or more
includes: lines as part of the header of the manifest file.

There will be as many includes: lines as included bundles (including
being omitted if a bundle does not include other bundles).
2016-03-24 21:17:56 +00:00
William Douglas 0dcad76694 Add field for expressing included bundles 2016-03-24 21:17:56 +00:00
William Douglas 24ef47f40c Fixups for clang-format v3.8.0 2016-03-24 21:17:56 +00:00
Patrick McCarty 0a41a7e2d5 basic creator: remove unneeded pushd/popd
Since full paths are used everywhere in this script, the pushd/popd
sequence is not needed.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-03-24 09:38:40 -07:00
Patrick McCarty 51c0bf2007 Release v3.1.2
This release enables logs for the three installed binaries and optimizes
swupd_make_pack performance by preferring to hardlink files to the pack
staging area whenever possible.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-03-22 17:21:48 -07:00
Patrick McCarty f27d0cf03a Capture logs for every binary
To capture all information that is logged, change init_log() to make
every log file name unique, and add a call to swupd_make_fullfiles to
enable logging.

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-03-22 17:04:17 -07:00
Arjan van de Ven 08fb540678 Speed up pack creation
A big chunk of time during pack creation is spent in untar'ing of
fullfiles tar files.  However, we also (most likely) have this exact
same content already in the image/ directory.

This patch makes the pack creator skip the untar if its possible to link
the file directly, and falls back to the existing behavior if the link
fails

Signed-off-by: Patrick McCarty <patrick.mccarty@intel.com>
2016-03-22 13:04:45 -07:00
37 changed files with 974 additions and 351 deletions
+5 -4
View File
@@ -19,16 +19,17 @@ stamp-h1
DEADJOE
swupd_create_update
swupd_make_pack
swupd-update-server.log*
swupd_make_fullfiles
swupd-server-*.tar.gz
swupd-server.log.*
cscope.*
*.kdev4
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
+12 -9
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 \
@@ -96,24 +96,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/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
+1 -5
View File
@@ -23,11 +23,9 @@ export LEAF_CERT="leaf.cert.pem"
export CA_CHAIN_CERT="ca-chain.cert.pem"
export PASSPHRASE="${SWUPD_CERTS_DIR}/passphrase"
${SWUPDREPO}/swupd_create_update --osversion ${VER} --statedir ${UPDATEDIR}
${SWUPDREPO}/swupd_create_update --osversion ${VER} --statedir ${UPDATEDIR} --format 3
${SWUPDREPO}/swupd_make_fullfiles --statedir ${UPDATEDIR} ${VER}
pushd ${SWUPDREPO}
# create zero packs
MOM=${UPDATEDIR}/www/${VER}/Manifest.MoM
if [ ! -e ${MOM} ]; then
@@ -51,8 +49,6 @@ done
NUM_PACKS=2
${SWUPDREPO}/pack_maker.sh ${VER} ${NUM_PACKS}
popd
# expose the new build to staging / testing
echo ${VER} > ${UPDATEDIR}/image/latest.version
+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.1.1, timothy.c.pepper@linux.intel.com)
AC_INIT(swupd-server, 3.2.3, timothy.c.pepper@linux.intel.com)
AM_INIT_AUTOMAKE([foreign -Wall -W subdir-objects])
AM_SILENT_RULES([yes])
AC_PROG_CC
+10 -5
View File
@@ -13,7 +13,6 @@
// SWUPD_NUM_PACKS is also "PREV_CHECK" in releas tool swupd_bb.py (change both)
#define SWUPD_NUM_PACKS 4
#define SWUPD_NUM_MANIFEST_DELTAS 25
#define SWUPD_DEFAULT_FORMAT 3
#define SWUPD_SERVER_STATE_DIR "/var/lib/update"
@@ -61,6 +60,7 @@
#endif
struct manifest {
unsigned long long int format;
int version;
int prevversion;
char *component;
@@ -70,6 +70,8 @@ struct manifest {
GList *manifests; /* as struct file */
GList *submanifests; /* as struct manifest */
GList *includes; /* struct manifests for all bundles included into this one */
};
struct file;
@@ -134,7 +136,7 @@ struct packdata {
extern int current_version;
extern int newversion;
extern int minversion;
extern char *format_string;
extern unsigned long long int format;
extern bool enable_signing;
extern char *state_dir;
@@ -144,7 +146,7 @@ extern char *staging_dir;
extern bool init_globals(void);
extern void free_globals(void);
extern bool set_format_string(char *);
extern bool set_format(char *);
extern void check_root(void);
extern bool set_state_dir(char *);
extern bool init_state_globals(void);
@@ -173,10 +175,13 @@ extern void free_manifest(struct manifest *manifest);
extern struct manifest *alloc_manifest(int version, char *module);
extern int match_manifests(struct manifest *m1, struct manifest *m2);
extern void sort_manifest_by_version(struct manifest *manifest);
extern bool manifest_includes(struct manifest *manifest, char *component);
extern bool changed_includes(struct manifest *old, struct manifest *new);
extern int prune_manifest(struct manifest *manifest);
extern int remove_old_deleted_files(struct manifest *m1, struct manifest *m2);
extern void create_manifest_delta(int oldversion, int newversion, char *module);
extern void create_manifest_deltas(struct manifest *manifest, GList *last_versions_list);
extern void subtract_manifests(struct manifest *m1, struct manifest *m2);
extern void subtract_manifests_frontend(struct manifest *m1, struct manifest *m2);
extern void nest_manifest(struct manifest *parent, struct manifest *sub);
extern void nest_manifest_file(struct manifest *parent, struct file *file);
extern int manifest_subversion(struct manifest *parent, char *group);
@@ -222,7 +227,7 @@ extern void populate_file_struct(struct file *file, char *filename);
extern void download_exta_base_content(void);
extern char *get_elapsed_time(struct timeval *t1, struct timeval *t2);
extern void init_log(int version);
extern void init_log(const char *prefix, const char *bundle, int start, int end);
extern void init_log_stdout(void);
extern void close_log(int version, int exit_status);
extern void __log_message(struct file *file, char *msg, char *filename, int linenr, const char *fmt, ...);
+74 -15
View File
@@ -23,19 +23,19 @@
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <openssl/hmac.h>
#include <linux/limits.h>
#include <openssl/hmac.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
#include "xattrs.h"
@@ -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,7 +347,7 @@ 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);
@@ -402,6 +407,58 @@ struct manifest *full_manifest_from_directory(int version)
return manifest;
}
/* Read includes from $manifest-includes file */
GList *get_sub_manifest_includes(char *component, int version)
{
FILE *infile;
GList *includes = NULL;
char *c;
char *conf;
char *filename;
char *included;
char line[8192];
conf = config_output_dir();
if (conf == NULL) {
assert(0);
}
string_or_die(&filename, "%s/%i/noship/%s-includes", conf, version, component);
free(conf);
LOG(NULL, "Reading includes", "%s", filename);
infile = fopen(filename, "rb");
if (infile == NULL) {
if (errno != ENOENT) {
LOG(NULL, "Cannot read includes", "%s (%s)\n", filename, strerror(errno));
}
free(filename);
return NULL;
}
line[0] = 0;
while (strcmp(line, "\n") != 0) {
line[0] = 0;
if (fgets(line, 8191, infile) == NULL) {
break;
}
c = strchr(line, '\n');
if (c) {
*c = 0;
}
if (strlen(line) == 0) {
break;
}
included = strdup(line);
includes = g_list_prepend(includes, included);
}
fclose(infile);
includes = g_list_sort(includes, (GCompareFunc)strcmp);
return includes;
}
struct manifest *sub_manifest_from_directory(char *component, int version)
{
struct manifest *manifest;
@@ -419,6 +476,8 @@ struct manifest *sub_manifest_from_directory(char *component, int version)
manifest->files = g_list_sort(manifest->files, file_sort_filename);
manifest->includes = get_sub_manifest_includes(component, version);
return manifest;
}
+4 -25
View File
@@ -21,15 +21,14 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <glib.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
@@ -66,25 +65,5 @@ void chroot_create_full(int newversion)
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;
}
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(full_dir);
}
+2 -2
View File
@@ -20,11 +20,11 @@
*
*/
#include <assert.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <glib.h>
#include "swupd.h"
+79 -22
View File
@@ -25,17 +25,17 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <glib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <getopt.h>
#include <sys/wait.h>
#include <unistd.h>
#include "swupd.h"
@@ -69,7 +69,7 @@ static void print_help(const char *name)
printf("Application Options:\n");
printf(" -o, --osversion The OS version for which to create an update\n");
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(" -F, --format Format number for the update\n");
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(" -s, --signcontent Enables cryptographic signing of update content\n");
@@ -105,7 +105,7 @@ static bool parse_options(int argc, char **argv)
}
break;
case 'F':
if (!optarg || !set_format_string(optarg)) {
if (!optarg || !set_format(optarg)) {
printf("Invalid --format argument\n\n");
return false;
}
@@ -117,10 +117,10 @@ static bool parse_options(int argc, char **argv)
}
break;
case 'g':
if (format_string == NULL) {
printf("%d\n", SWUPD_DEFAULT_FORMAT);
if (format == 0) {
printf("No format specified\n");
} else {
printf("%s\n", format_string);
printf("%llu\n", format);
free_globals();
}
exit(0);
@@ -223,8 +223,11 @@ int main(int argc, char **argv)
struct manifest *old_full = NULL;
struct manifest *new_full = NULL;
GHashTable *new_manifests = g_hash_table_new(g_str_hash, g_str_equal);
GHashTable *old_manifests = g_hash_table_new(g_str_hash, g_str_equal);
GList *manifests_last_versions_list = NULL;
int newfiles = 0;
int old_deleted = 0;
struct timeval current_time;
struct timeval previous_time;
@@ -274,7 +277,7 @@ int main(int argc, char **argv)
populate_dirs(newversion);
printf("Next version is %i \n", newversion);
init_log(newversion);
init_log("swupd-create-update", "", current_version, newversion);
gettimeofday(&previous_time, NULL);
@@ -293,6 +296,13 @@ int main(int argc, char **argv)
apply_heuristics(old_full);
apply_heuristics(new_full);
match_manifests(old_full, new_full);
old_deleted = remove_old_deleted_files(old_full, new_full);
if (old_deleted > 0) {
LOG(NULL, "", "Old deleted files (%d) removed from full manifest", old_deleted);
printf("Old deleted files (%d) removed from full manifest\n", old_deleted);
}
apply_heuristics(new_full);
#warning disabled rename detection for some simplicity
// rename_detection(new_full);
@@ -332,6 +342,7 @@ 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);
if (newfiles <= 0) {
@@ -339,8 +350,8 @@ int main(int argc, char **argv)
printf("Core component has not changed (after pruning), exiting\n");
goto exit;
}
LOG(NULL, "", "Core component has changes (%d), writing out new manifest", newfiles);
printf("Core component has changes (%d), writing out new manifest\n", newfiles);
LOG(NULL, "", "Core component has changes (%d new, %d deleted), writing out new manifest", newfiles, old_deleted);
printf("Core component has changes (%d new, %d deleted), writing out new manifest\n", newfiles, old_deleted);
if (write_manifest(new_core) != 0) {
LOG(NULL, "", "Core component manifest write failed");
printf("Core component manifest write failed\n");
@@ -353,6 +364,43 @@ int main(int argc, char **argv)
/* Phase 3: the functional bundles */
printf("Entering phase 3: The bundles\n");
while (1) {
char *group = next_group();
if (!group) {
break;
}
(void)g_hash_table_insert(new_manifests, group, sub_manifest_from_directory(group, newversion));
(void)g_hash_table_insert(old_manifests, group, manifest_from_file(manifest_subversion(old_MoM, group), group));
}
while (1) {
GList *manifest_includes = NULL;
GList *name_includes;
char *group = next_group();
struct manifest *manifest;
if (!group) {
break;
}
manifest = g_hash_table_lookup(new_manifests, group);
name_includes = manifest->includes;
while (name_includes) {
char *name = name_includes->data;
name_includes = g_list_next(name_includes);
manifest_includes = g_list_prepend(manifest_includes, g_hash_table_lookup(new_manifests, name));
}
manifest->includes = manifest_includes;
manifest_includes = NULL;
manifest = g_hash_table_lookup(old_manifests, group);
name_includes = manifest->includes;
while (name_includes) {
char *name = name_includes->data;
name_includes = g_list_next(name_includes);
manifest_includes = g_list_prepend(manifest_includes, g_hash_table_lookup(old_manifests, name));
}
manifest->includes = manifest_includes;
}
while (1) {
char *group = next_group();
struct manifest *oldm;
@@ -369,19 +417,27 @@ int main(int argc, char **argv)
printf("Processing bundle %s\n", group);
/* Step 4: Make a manifest for this functonal group */
oldm = manifest_from_file(manifest_subversion(old_MoM, group), group);
newm = sub_manifest_from_directory(group, newversion);
oldm = g_hash_table_lookup(old_manifests, group);
newm = g_hash_table_lookup(new_manifests, group);
add_component_hashes_to_manifest(newm, new_full);
apply_heuristics(oldm);
apply_heuristics(newm);
newm->prevversion = oldm->version;
/* add os-core as an included manifest */
if (!manifest_includes(oldm, "os-core")) {
oldm->includes = g_list_prepend(oldm->includes, old_core);
}
if (!manifest_includes(newm, "os-core")) {
newm->includes = g_list_prepend(newm->includes, new_core);
}
/* Step 5: Subtract the core files from the manifest */
subtract_manifests(oldm, old_core);
subtract_manifests(newm, new_core);
subtract_manifests_frontend(oldm, oldm);
subtract_manifests_frontend(newm, newm);
/* Step 6: Compare manifest to the previous version... */
if (match_manifests(oldm, newm) == 0) {
if (match_manifests(oldm, newm) == 0 && !changed_includes(oldm, newm)) {
LOG(NULL, "", "%s components have not changed, no new manifest", group);
printf("%s components have not changed, no new manifest\n", group);
/* Step 6a: if nothing changed, stay at the old version */
@@ -390,12 +446,13 @@ 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);
if (newfiles > 0) {
LOG(NULL, "", "%s component has changes (%d), writing out new manifest", group, newfiles);
printf("%s component has changes (%d), writing out new manifest\n", group, newfiles);
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);
if (write_manifest(newm) != 0) {
LOG(NULL, "", "%s component manifest write failed", group);
printf("%s component manifest write failed\n", group);
+6 -8
View File
@@ -21,18 +21,16 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <bsdiff.h>
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <bsdiff.h>
#include <glib.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
#include "xattrs.h"
+9 -10
View File
@@ -22,18 +22,17 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <glib.h>
#include <libgen.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <errno.h>
#include <libgen.h>
#include <glib.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
@@ -92,8 +91,7 @@ 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",
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);
@@ -125,6 +123,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);
+13 -16
View File
@@ -21,19 +21,19 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include "swupd.h"
int newversion = -1;
int minversion = 0;
char *format_string = NULL;
unsigned long long int format = 0;
bool enable_signing = false;
char *state_dir = NULL;
@@ -41,20 +41,17 @@ char *packstage_dir = NULL;
char *image_dir = NULL;
char *staging_dir = NULL;
bool set_format_string(char *userinput)
bool set_format(char *userinput)
{
int version;
unsigned long long int user_format;
// expect a positive integer
// format string shall be a positive integer
errno = 0;
version = strtoull(userinput, NULL, 10);
if ((errno < 0) || (version <= 0)) {
user_format = strtoull(userinput, NULL, 10);
if ((errno < 0) || (user_format == 0)) {
return false;
}
if (format_string) {
free(format_string);
}
string_or_die(&format_string, "%d", version);
format = user_format;
return true;
}
@@ -81,8 +78,9 @@ bool set_state_dir(char *dir)
bool init_globals(void)
{
if (format_string == NULL) {
string_or_die(&format_string, "%d", SWUPD_DEFAULT_FORMAT);
if (format == 0) {
printf("Error: Missing format parameter. Please specify a format with -F.\n");
return false;
}
if (!init_state_globals()) {
@@ -101,7 +99,6 @@ bool init_globals(void)
void free_globals(void)
{
free(format_string);
free(state_dir);
free(packstage_dir);
free(image_dir);
+2 -2
View File
@@ -23,11 +23,11 @@
*
*/
#include <assert.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <glib.h>
#include "swupd.h"
+6 -7
View File
@@ -21,19 +21,18 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <glib.h>
#include <unistd.h>
#include "swupd.h"
+3 -4
View File
@@ -21,13 +21,12 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <glib.h>
#include <unistd.h>
#include "swupd.h"
+8 -8
View File
@@ -22,15 +22,14 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <glib.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <sys/time.h>
#include <glib.h>
#include <unistd.h>
#include "swupd.h"
@@ -38,11 +37,12 @@ static FILE *logfile;
static struct timeval start_time;
void init_log(int version)
void init_log(const char *prefix, const char *bundle, int start, int end)
{
char filename[4096];
sprintf(filename, "swupd-server.log.%i", version);
char *filename;
string_or_die(&filename, "%s%s-from-%i-to-%i.log", prefix, bundle, start, end);
logfile = fopen(filename, "w");
free(filename);
gettimeofday(&start_time, NULL);
}
void init_log_stdout(void)
+5 -4
View File
@@ -21,13 +21,12 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <unistd.h>
#include "swupd.h"
@@ -113,6 +112,8 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
init_log("swupd-make-fullfiles", "", 0, version);
manifest = manifest_from_file(version, "full");
create_fullfiles(manifest);
+10 -14
View File
@@ -21,20 +21,18 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <getopt.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <getopt.h>
#include <glib.h>
#include <getopt.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
@@ -116,10 +114,6 @@ int main(int argc, char **argv)
banner();
check_root();
/* FIXME: should use "end_version" not "0" and a unique filename
init_log(0);
*/
/* Initilize the crypto signature module */
if (!signature_initialize()) {
printf("Can't initialize the crypto signature module!\n");
@@ -141,6 +135,8 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
init_log("swupd-make-pack-", module, start_version, end_version);
printf("Making pack-%s %i to %li\n", module, start_version, end_version);
pack = calloc(1, sizeof(struct packdata));
+240 -27
View File
@@ -23,19 +23,17 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <bsdiff.h>
#include <errno.h>
#include <glib.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <bsdiff.h>
#include <glib.h>
#include <unistd.h>
#include "swupd.h"
#include "xattrs.h"
@@ -101,6 +99,7 @@ struct manifest *alloc_manifest(int version, char *component)
manifest->version = version;
manifest->component = strdup(component);
manifest->format = format;
return manifest;
}
@@ -108,11 +107,13 @@ struct manifest *alloc_manifest(int version, char *component)
struct manifest *manifest_from_file(int version, char *component)
{
FILE *infile;
GList *includes = NULL;
char line[8192], *c, *c2;
int count = 0;
struct manifest *manifest;
char *filename, *conf;
int previous = 0;
unsigned long long int format_number;
conf = config_output_dir();
if (conf == NULL) {
@@ -144,7 +145,9 @@ struct manifest *manifest_from_file(int version, char *component)
return NULL;
}
c = &line[9];
if (strtoull(c, NULL, 10) == 0) {
format_number = strtoull(c, NULL, 10);
if ((errno < 0) || (format_number == 0)) {
//format string shall be a positive integer
printf("Unknown file format version in MANIFEST line: %s\n", c);
fclose(infile);
return NULL;
@@ -178,10 +181,18 @@ struct manifest *manifest_from_file(int version, char *component)
if (strncmp(line, "previous:", 9) == 0) {
previous = strtoull(c, NULL, 10);
}
if (strncmp(line, "includes:", 9) == 0) {
includes = g_list_prepend(includes, strdup(c));
if (!includes->data) {
abort();
}
}
}
manifest = alloc_manifest(version, component);
manifest->format = format_number;
manifest->prevversion = previous;
manifest->includes = includes;
/* empty line */
while (!feof(infile)) {
@@ -509,29 +520,57 @@ int match_manifests(struct manifest *m1, struct manifest *m2)
return count;
}
/* removes all files from m2 from m1 */
static GList *get_unique_includes(struct manifest *manifest)
{
GHashTable *unique_includes = g_hash_table_new(g_str_hash, g_str_equal);
GHashTableIter iter;
GList *includes = NULL;
GList *l1, *l2;
gpointer k, v;
l1 = g_list_first(manifest->includes);
while (l1) {
struct manifest *m = l1->data;
l1 = g_list_next(l1);
(void)g_hash_table_replace(unique_includes, m->component, m);
l2 = get_unique_includes(m);
while (l2) {
struct manifest *m = l2->data;
l2 = g_list_next(l2);
(void)g_hash_table_replace(unique_includes, m->component, m);
}
g_list_free(l2);
}
g_hash_table_iter_init(&iter, unique_includes);
while (g_hash_table_iter_next(&iter, &k, &v)) {
includes = g_list_prepend(includes, v);
}
return includes;
}
/*
* removes all files from m2 from m1
* This will recurse over all included manifests to also
* subtract those from the m1 manifest.
*
* As a special convenient semantics,
* subtract_manifests(M, M)
* will subtract all included manifests from M,
* but will not subtract M from M itself.
*/
void subtract_manifests(struct manifest *m1, struct manifest *m2)
{
GList *list1, *list2;
struct file *file1, *file2;
if (!m1) {
printf("Subtracting manifests failed: No m1 manifest!\n");
return;
}
if (!m2) {
printf("Subtracting manifests failed: No m2 manifest!\n");
return;
}
m1->files = g_list_sort(m1->files, file_sort_filename);
m2->files = g_list_sort(m2->files, file_sort_filename);
list1 = g_list_first(m1->files);
list2 = g_list_first(m2->files);
while (list1 && list2) {
while (list1 && list2 && m1 != m2) {
int ret;
file1 = list1->data;
file2 = list2->data;
@@ -555,6 +594,31 @@ void subtract_manifests(struct manifest *m1, struct manifest *m2)
}
}
void subtract_manifests_frontend(struct manifest *m1, struct manifest *m2)
{
GList *includes;
struct manifest *m;
if (!m1) {
printf("Subtracting manifests failed: No m1 manifest!\n");
return;
}
if (!m2) {
printf("Subtracting manifests failed: No m2 manifest!\n");
return;
}
subtract_manifests(m1, m2);
includes = get_unique_includes(m2);
while (includes) {
m = includes->data;
includes = g_list_next(includes);
subtract_manifests(m1, m);
}
}
char *file_type_to_string(struct file *file)
{
static char type[5];
@@ -657,6 +721,7 @@ exit:
/* Returns 0 == success, -1 == failure */
static int write_manifest_plain(struct manifest *manifest)
{
GList *includes;
GList *list;
struct file *file;
FILE *out = NULL;
@@ -664,6 +729,9 @@ static int write_manifest_plain(struct manifest *manifest)
char *conf = config_output_dir();
char *filename = NULL;
char *submanifest_filename = NULL;
char *manifest_tempdir = NULL;
char *tarcommand = NULL;
char *tempmanifest = NULL;
int ret = -1;
if (conf == NULL) {
@@ -687,13 +755,19 @@ static int write_manifest_plain(struct manifest *manifest)
goto exit;
}
fprintf(out, "MANIFEST\t%s\n", format_string);
fprintf(out, "MANIFEST\t%llu\n", format);
fprintf(out, "version:\t%i\n", manifest->version);
fprintf(out, "previous:\t%i\n", manifest->prevversion);
fprintf(out, "filecount:\t%i\n", manifest->count);
fprintf(out, "timestamp:\t%i\n", (int)time(NULL));
compute_content_size(manifest);
fprintf(out, "contentsize:\t%llu\n", (long long unsigned int)manifest->contentsize);
includes = manifest->includes;
while (includes) {
struct manifest *sub = includes->data;
includes = g_list_next(includes);
fprintf(out, "includes:\t%s\n", sub->component);
}
fprintf(out, "\n");
list = g_list_first(manifest->files);
@@ -705,24 +779,54 @@ 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;
}
/* 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(&tarcommand, TAR_COMMAND " -C %s " TAR_PERM_ATTR_ARGS " -xf %s.tar 2> /dev/null",
manifest_tempdir, submanifest_filename);
if (system(tarcommand) != 0) {
LOG(NULL, "Failed to run command:", "%s", tarcommand);
assert(0);
}
free(tarcommand);
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 (rmdir(manifest_tempdir) != 0) {
LOG(NULL, "rmdir failed for %s: %s", manifest_tempdir, strerror(errno));
}
free(manifest_tempdir);
if (out) {
fclose(out);
}
@@ -747,12 +851,12 @@ static int write_manifest_tar(struct manifest *manifest)
/* 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",
"%s/%i/Manifest.%s.tar Manifest.%s Manifest.%s.signed",
conf, manifest->version, conf, manifest->version, manifest->component,
manifest->component, manifest->component);
} else {
string_or_die(&tarcmd, TAR_COMMAND " --directory=%s/%i " TAR_PERM_ATTR_ARGS " -Jcf "
"%s/%i/Manifest.%s.tar Manifest.%s",
"%s/%i/Manifest.%s.tar Manifest.%s",
conf, manifest->version, conf, manifest->version, manifest->component,
manifest->component);
}
@@ -811,6 +915,115 @@ void sort_manifest_by_version(struct manifest *manifest)
}
}
bool manifest_includes(struct manifest *manifest, char *component)
{
GList *includes = g_list_first(manifest->includes);
while (includes) {
if (strcmp(((struct manifest *)includes->data)->component,
component) == 0) {
return true;
}
includes = g_list_next(includes);
}
return false;
}
/* This requires the manifest to have the includes sorted.
* The manifests will be sorted when constructed from
* get_sub_manifest_includes (and then replacing the manifest
* strings with actual manifest structs in the same order as
* is done in the main.c's main()).
*/
bool changed_includes(struct manifest *old, struct manifest *new)
{
GList *includes_old = g_list_first(old->includes);
GList *includes_new = g_list_first(new->includes);
if (g_list_length(includes_old) != g_list_length(includes_new)) {
return true;
}
while (includes_old && includes_new) {
char *bundle_old = ((struct manifest *)includes_old->data)->component;
char *bundle_new = ((struct manifest *)includes_new->data)->component;
if (strcmp(bundle_old, bundle_new) != 0) {
return true;
}
includes_old = g_list_next(includes_old);
includes_new = g_list_next(includes_new);
}
return false;
}
/* For a format bump, it's convenient to remove deleted files from manifests
* that last changed prior to the format bump, since they are no longer
* considered for deletion as part of an update.
*
* Note: this function should be called after match_manifests().
*/
int remove_old_deleted_files(struct manifest *m1, struct manifest *m2)
{
GList *list1, *list2;
struct file *file1, *file2;
int count = 0;
if (!m1) {
printf("No old manifest!\n");
return -1;
}
if (!m2) {
printf("No new manifest!\n");
return -1;
}
/* This is the common case, so bail early, reporting no deletions */
if (m1->format == m2->format) {
return 0;
}
/* At this point, the manifest formats mismatch, and it's assumed that
* m1 is the old manifest, and m2 is the new.
*/
m1->files = g_list_sort(m1->files, file_sort_filename);
m2->files = g_list_sort(m2->files, file_sort_filename);
list1 = g_list_first(m1->files);
list2 = g_list_first(m2->files);
while (list1 && list2) {
int ret;
file1 = list1->data;
file2 = list2->data;
ret = strcmp(file1->filename, file2->filename);
if (ret == 0) {
if (file1->is_deleted && file2->is_deleted) {
GList *to_delete = list2;
list1 = g_list_next(list1);
list2 = g_list_next(list2);
m2->files = g_list_delete_link(m2->files, to_delete);
m2->count--;
count++;
continue;
}
list1 = g_list_next(list1);
list2 = g_list_next(list2);
} else if (ret < 0) {
list1 = g_list_next(list1);
} else {
list2 = g_list_next(list2);
}
}
return count;
}
/* Conditionally remove some things from a manifest.
* Returns > 0 when the pruned manifest has new files.
* Returns 0 when the pruned manifest no longer has new files.
@@ -1001,7 +1214,7 @@ static void maximize_version_manifests(struct manifest *m1, struct manifest *m2)
ret = strcmp(file1->filename, file2->filename);
if (ret == 0) {
if (file1->last_change > file2->last_change) {
if (!file1->is_deleted && file1->last_change > file2->last_change) {
LOG(file1, "Update", "Moving %s to version %i", file1->filename, file1->last_change);
file2->last_change = file1->last_change;
}
+63 -23
View File
@@ -24,18 +24,17 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <glib.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
@@ -118,8 +117,7 @@ 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",
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) {
@@ -168,21 +166,44 @@ static void make_pack_full_files(struct packdata *pack)
item = g_list_next(item);
if ((!file->peer || file->peer->is_deleted) && !file->is_deleted && !file->rename_peer) {
char *from, *to;
char *fullfrom, *fullto;
/* hardlink each file that is in <end> but not in <X> */
string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
string_or_die(&fullto, "%s/%s/%i_to_%i/staged/%s", packstage_dir,
pack->module, pack->from, pack->to, 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_to_%i/staged/%s.tar", packstage_dir,
pack->module, pack->from, pack->to, file->hash);
ret = link(from, to);
if (ret) {
if (errno != EEXIST) {
LOG(NULL, "Failure to link", "%s to %s (%s) %i", from, to, strerror(errno), errno);
ret = -1;
errno = 0;
/* Prefer to hardlink uncompressed files (excluding
* directories) first, and fall back to the compressed
* versions if the hardlink fails.
*/
if (!file->is_dir) {
ret = link(fullfrom, fullto);
if (ret && errno != EEXIST) {
LOG(NULL, "Failure to link for fullfile pack", "%s to %s (%s) %i", fullfrom, fullto, strerror(errno), errno);
}
} else {
}
if (ret) {
ret = link(from, to);
if (ret && errno != EEXIST) {
LOG(NULL, "Failure to link for fullfile pack", "%s to %s (%s) %i", from, to, strerror(errno), errno);
}
}
if (ret == 0) {
pack->fullcount++;
}
free(from);
free(to);
free(fullfrom);
free(fullto);
}
}
@@ -321,7 +342,7 @@ static int make_final_pack(struct packdata *pack)
item = g_list_first(pack->end_manifest->files);
while (item) {
char *from, *to, *tarfrom, *tarto;
char *from, *to, *tarfrom, *tarto, *fullfrom, *fullto;
struct stat stat_delta, stat_tar;
file = item->data;
@@ -344,6 +365,9 @@ static int make_final_pack(struct packdata *pack)
file->last_change, file->hash);
string_or_die(&tarto, "%s/%s/%i_to_%i/staged/%s.tar", packstage_dir,
pack->module, pack->from, pack->to, file->hash);
string_or_die(&fullfrom, "%s/%i/full/%s", image_dir, file->last_change, file->filename);
string_or_die(&fullto, "%s/%s/%i_to_%i/staged/%s", packstage_dir,
pack->module, pack->from, pack->to, file->hash);
ret = stat(from, &stat_delta);
if (ret) {
@@ -375,13 +399,28 @@ static int make_final_pack(struct packdata *pack)
}
}
} else {
/* include full file in pack */
ret = link(tarfrom, tarto);
if (ret) {
if (errno != EEXIST) {
LOG(NULL, "Failure to link", "%s to %s (%s) %i\n", tarfrom, tarto, strerror(errno), errno);
ret = -1;
errno = 0;
/* Prefer to hardlink uncompressed files (excluding
* directories) first, and fall back to the compressed
* versions if the hardlink fails.
*/
if (!file->is_dir) {
ret = link(fullfrom, fullto);
if (ret && errno != EEXIST) {
LOG(NULL, "Failure to link for final pack", "%s to %s (%s) %i\n", fullfrom, fullto, strerror(errno), errno);
}
} else {
}
if (ret) {
ret = link(tarfrom, tarto);
if (ret && errno != EEXIST) {
LOG(NULL, "Failure to link for final pack", "%s to %s (%s) %i\n", tarfrom, tarto, strerror(errno), errno);
}
}
if (ret == 0) {
pack->fullcount++;
}
}
@@ -390,6 +429,8 @@ static int make_final_pack(struct packdata *pack)
free(to);
free(tarfrom);
free(tarto);
free(fullfrom);
free(fullto);
}
if (pack->fullcount > 0) {
@@ -411,7 +452,6 @@ static int make_final_pack(struct packdata *pack)
create_manifest_delta(pack->from, pack->to, pack->module);
}
string_or_die(&to, "%s/%s/%i_to_%i/Manifest-%s-delta-from-%i", packstage_dir,
pack->module, pack->from, pack->to, pack->module, pack->from);
@@ -452,7 +492,7 @@ 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",
"--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);
+6 -6
View File
@@ -22,16 +22,16 @@
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <glib.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "swupd.h"
+1 -1
View File
@@ -21,6 +21,7 @@
*/
#define _GNU_SOURCE
#include <err.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
@@ -29,7 +30,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <err.h>
#include "swupd.h"
+3 -4
View File
@@ -22,13 +22,12 @@
*/
#define _GNU_SOURCE
#include <assert.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <glib.h>
#include <unistd.h>
#include "swupd.h"
+7 -8
View File
@@ -23,17 +23,16 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "swupd.h"
@@ -140,7 +139,7 @@ void write_cookiecrumbs_to_download_area(int version)
}
free(cmd);
string_or_die(&cmd, "echo %s > %s/%i/format", format_string, conf, version);
string_or_die(&cmd, "echo %llu > %s/%i/format", format, conf, version);
if (system(cmd) != 0) {
assert(0);
}
+5 -5
View File
@@ -20,15 +20,15 @@
*
*/
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/xattr.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include "swupd.h"
#include "xattrs.h"
@@ -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 ]
}
+48
View File
@@ -0,0 +1,48 @@
#!/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 test-bundle1 test-bundle2
set_os_release 10 os-core
set_os_release 10 test-bundle1
set_os_release 10 test-bundle2
track_bundle 10 os-core
track_bundle 10 test-bundle1
track_bundle 10 test-bundle2
set_os_release 20 os-core
set_os_release 20 test-bundle1
set_os_release 20 test-bundle2
track_bundle 20 os-core
track_bundle 20 test-bundle1
track_bundle 20 test-bundle2
gen_file_plain 10 test-bundle1 foo
gen_file_plain 10 test-bundle2 foo
gen_file_plain 20 test-bundle1 foo
}
@test "delete no version bump update creation" {
sudo $CREATE_UPDATE --osversion 10 --statedir $DIR --format 3
sudo $MAKE_FULLFILES --statedir $DIR 10
set_latest_ver 10
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) ]
}
# 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
-58
View File
@@ -1,58 +0,0 @@
#!/usr/bin/env bats
# common functions
load swupdlib
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
init_server_ini
set_latest_ver 0
init_groups_ini os-core test-bundle
set_os_release 10 os-core
track_bundle 10 os-core
track_bundle 10 test-bundle
set_os_release 20 os-core
track_bundle 20 os-core
track_bundle 20 test-bundle
gen_file_to_delta 10 4096 20 4 test-bundle
}
@test "full run update creation with delta packs" {
# build the first version
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR
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
set_latest_ver 10
# then the second version...
sudo $srcdir/swupd_create_update --osversion 20 --statedir $DIR
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
# 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
# zero packs should exist (non-zero size) for both versions
[ -s $DIR/www/10/pack-os-core-from-0.tar ]
[ -s $DIR/www/10/pack-test-bundle-from-0.tar ]
[ -s $DIR/www/20/pack-os-core-from-0.tar ]
[ -s $DIR/www/20/pack-test-bundle-from-0.tar ]
# and delta packs should exist (non-zero size) for the latest version
[ -s $DIR/www/20/pack-os-core-from-10.tar ]
[ -s $DIR/www/20/pack-test-bundle-from-10.tar ]
}
teardown() {
sudo rm -rf $DIR
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
+84
View File
@@ -0,0 +1,84 @@
#!/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 test-bundle included included-two included-nested
set_os_release 10 os-core
track_bundle 10 os-core
track_bundle 10 test-bundle
set_os_release 20 os-core
track_bundle 20 os-core
track_bundle 20 test-bundle
track_bundle 20 included
track_bundle 20 included-two
track_bundle 20 included-nested
gen_file_to_delta 10 4096 20 4 test-bundle
gen_file_plain 10 test-bundle foo
gen_file_plain 10 test-bundle foobarbaz
gen_file_plain 20 test-bundle foo
gen_file_plain 20 included foo
gen_file_plain 20 included-two foo
gen_file_plain 20 included-two foobar
gen_file_plain 20 included-nested foobarbaz
gen_includes_file test-bundle 20 included included-two
gen_includes_file included 20 included-nested
}
@test "full run update creation with delta packs" {
# build the first version
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 $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 $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 ]
[ -s $DIR/www/10/pack-test-bundle-from-0.tar ]
[ -s $DIR/www/20/pack-os-core-from-0.tar ]
[ -s $DIR/www/20/pack-test-bundle-from-0.tar ]
# and delta packs should exist (non-zero size) for the latest version
[ -s $DIR/www/20/pack-os-core-from-10.tar ]
[ -s $DIR/www/20/pack-test-bundle-from-10.tar ]
[[ 1 -eq $(grep '^includes: os-core$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/foo$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/foobarbaz$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 0 -eq $(grep '/foobar$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: os-core$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: included$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: included-two$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^.d.. 0000000000000000000000000000000000000000000000000000000000000000 20 /foo$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^.d.. 0000000000000000000000000000000000000000000000000000000000000000 20 /foobarbaz$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/foo$' $DIR/www/20/Manifest.included | wc -l) ]]
[[ 1 -eq $(grep '/foo$' $DIR/www/20/Manifest.included-two | wc -l) ]]
[[ 1 -eq $(grep '/foobar$' $DIR/www/20/Manifest.included-two | wc -l) ]]
[[ 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) ]]
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/env bats
# common functions
load swupdlib
setup() {
DIR=$(init_web_dir "$srcdir/web-dir")
export DIR
init_server_ini
set_latest_ver 0
init_groups_ini os-core test-bundle
set_os_release 10 os-core
set_os_release 10 test-bundle
track_bundle 10 os-core
track_bundle 10 test-bundle
}
@test "full run update creation" {
sudo $srcdir/swupd_create_update --osversion 10 --statedir $DIR
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
# zero packs should exist (non-zero size) for the build
[ -s $DIR/www/10/pack-os-core-from-0.tar ]
[ -s $DIR/www/10/pack-test-bundle-from-0.tar ]
}
teardown() {
sudo rm -rf $DIR
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
+45
View File
@@ -0,0 +1,45 @@
#!/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 test-bundle
set_os_release 10 os-core
set_os_release 10 test-bundle
track_bundle 10 os-core
track_bundle 10 test-bundle
gen_file_plain 10 test-bundle foo
}
@test "full run update creation" {
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 ]
[ -s $DIR/www/10/pack-test-bundle-from-0.tar ]
[[ 1 -eq $(grep '^includes: os-core$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/usr/share/clear/bundles/test-bundle$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/foo$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/usr/share/clear/bundles/os-core$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 1 -eq $(grep '/usr$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 1 -eq $(grep '/usr/lib$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 1 -eq $(grep '/usr/share$' $DIR/www/10/Manifest.os-core | wc -l) ]]
[[ 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) ]]
}
# 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" ]]
}
+99
View File
@@ -0,0 +1,99 @@
#!/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 test-bundle included included-two included-nested
set_os_release 10 os-core
track_bundle 10 os-core
track_bundle 10 test-bundle
set_os_release 20 os-core
track_bundle 20 os-core
track_bundle 20 test-bundle
track_bundle 20 included
track_bundle 20 included-two
set_os_release 30 os-core
track_bundle 30 os-core
track_bundle 30 test-bundle
track_bundle 30 included
track_bundle 30 included-two
track_bundle 30 included-nested
gen_file_plain 10 test-bundle foo
gen_file_plain 20 test-bundle foo
gen_file_plain 20 included bar
gen_file_plain 20 included-two baz
gen_file_plain 30 test-bundle foo
gen_file_plain 30 included bar
gen_file_plain 30 included-two baz
gen_file_plain 30 included-nested foobarbaz
gen_includes_file test-bundle 20 included included-two
gen_includes_file test-bundle 30 included included-two
gen_includes_file included 30 included-nested
}
@test "full run update creation with delta packs" {
# build the first version
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 $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 $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 ]
[ -s $DIR/www/10/pack-test-bundle-from-0.tar ]
[ -s $DIR/www/20/pack-os-core-from-0.tar ]
[ -s $DIR/www/20/pack-test-bundle-from-0.tar ]
[ -s $DIR/www/20/pack-included-from-0.tar ]
[ -s $DIR/www/20/pack-included-two-from-0.tar ]
[ -s $DIR/www/30/pack-os-core-from-0.tar ]
[ -s $DIR/www/30/pack-test-bundle-from-0.tar ]
[ -s $DIR/www/30/pack-included-from-0.tar ]
[ -s $DIR/www/30/pack-included-two-from-0.tar ]
[ -s $DIR/www/30/pack-included-nested-from-0.tar ]
[[ 1 -eq $(grep '^includes: os-core$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/foo$' $DIR/www/10/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: os-core$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: included$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '^includes: included-two$' $DIR/www/20/Manifest.test-bundle | wc -l) ]]
[[ 1 -eq $(grep '/bar$' $DIR/www/20/Manifest.included | wc -l) ]]
[[ 1 -eq $(grep '/baz$' $DIR/www/20/Manifest.included-two | wc -l) ]]
[[ 1 -eq $(grep '^includes: included-nested$' $DIR/www/30/Manifest.included | wc -l) ]]
[[ 1 -eq $(grep '/foobarbaz$' $DIR/www/30/Manifest.included-nested | wc -l) ]]
[[ 0 -eq $(ls $DIR/www/30/Manifest.test-bundle | wc -l) ]]
[[ 0 -eq $(ls $DIR/www/30/Manifest.included-two | wc -l) ]]
}
# 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" ]]
}
+52 -6
View File
@@ -1,14 +1,28 @@
# 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
}
@@ -39,6 +53,18 @@ track_bundle() {
touch $DIR/image/$ver/$bundle/usr/share/clear/bundles/$bundle
}
gen_includes_file() {
local bundle=$1
local ver=$2
local includes="${@:3}"
mkdir -p $DIR/www/$ver/noship
for b in $includes; do
cat >> $DIR/www/$ver/noship/"$bundle"-includes << EOF
$b
EOF
done
}
gen_file_to_delta() {
local origver=$1
local origsize=$2
@@ -58,4 +84,24 @@ gen_file_to_delta() {
rm $TMP
}
gen_file_plain() {
local ver=$1
local bundle=$2
local name="$3"
# Add plain text file into a bundle
mkdir -p $DIR/image/$ver/$bundle
echo "$name" > $DIR/image/$ver/$bundle/"$name"
}
gen_file_plain_change() {
local ver=$1
local bundle=$2
local name="$3"
# Add plain text file into a bundle
mkdir -p $DIR/image/$ver/$bundle
echo "$ver $name" > $DIR/image/$ver/$bundle/"$name"
}
# vi: ft=sh ts=8 sw=2 sts=2 et tw=80
@@ -1,13 +1,21 @@
#!/usr/bin/env bats
@test "create_update required arg" {
run $srcdir/swupd_create_update
load "../swupdlib"
@test "create_update required format" {
run $CREATE_UPDATE
[ "$status" -eq 1 ]
[[ "$output" =~ "Missing format parameter" ]]
}
@test "create_update required version" {
run $CREATE_UPDATE -F 3
[ "$status" -eq 1 ]
[[ "$output" =~ "Missing version parameter:" ]]
}
@test "create_update root priv check" {
run $srcdir/swupd_create_update -o 10
run $CREATE_UPDATE -F 3 -o 10
[ "$status" -eq 1 ]
[[ "$output" =~ "not being run as root.. exiting" ]]
}