Skip to content

Commit

Permalink
Merge pull request #70 from ejoerns/v0/topic/rauc-info
Browse files Browse the repository at this point in the history
Add --output-format option for `rauc info`
  • Loading branch information
jluebbe committed Aug 24, 2016
2 parents 3877279 + e2d41c9 commit 87ab3fd
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 72 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ before_install:
- sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/
trusty main restricted universe multiverse" -y
- sudo apt-get update -qq
- sudo apt-get install -qq autoconf automake libglib2.0-dev libssl-dev
libcurl4-openssl-dev squashfs-tools lcov slirp
- sudo apt-get install -qq autoconf automake libglib2.0-dev libjson-glib-dev
libssl-dev libcurl4-openssl-dev squashfs-tools lcov slirp
- sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu/
vivid main restricted universe multiverse" -y
- sudo apt-get update -qq
Expand Down
6 changes: 3 additions & 3 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ bin_PROGRAMS = rauc

rauc_SOURCES = \
src/main.c
rauc_CFLAGS = $(AM_CFLAGS) $(CODE_COVERAGE_CFLAGS)
rauc_LDFLAGS = $(AM_LDFLAGS) $(CODE_COVERAGE_LDFLAGS)
rauc_LDADD = $(librauc_la_LIBADD) librauc.la
rauc_CFLAGS = $(AM_CFLAGS) $(JSON_GLIB_CFLAGS) $(CODE_COVERAGE_CFLAGS)
rauc_LDFLAGS = $(AM_LDFLAGS) $(JSON_GLIB_LDFLAGS) $(CODE_COVERAGE_LDFLAGS)
rauc_LDADD = $(JSON_GLIB_LIBS) $(librauc_la_LIBADD) librauc.la

if SYSTEMD
systemdunitdir=$(SYSTEMD_UNITDIR)
Expand Down
12 changes: 12 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ AS_IF([test "x$enable_network" != "xno"], [
])


AC_ARG_ENABLE([json],
AS_HELP_STRING([--disable-json], [Disable JSON support])
)
AM_CONDITIONAL([WANT_JSON], [test x$enable_json != xno])
AS_IF([test "x$enable_json" != "xno"], [
AC_DEFINE([ENABLE_JSON], [1], [Define to 1 to enable building with JSON support])
PKG_CHECK_MODULES([JSON_GLIB], [json-glib-1.0])
], [
AC_DEFINE([ENABLE_JSON], [0])
])


AX_CHECK_OPENSSL([],[AC_MSG_ERROR([OpenSSL not found])])

AC_ARG_WITH([systemdunitdir], AC_HELP_STRING([--with-systemdunitdir=DIR],
Expand Down
2 changes: 2 additions & 0 deletions include/manifest.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ typedef struct {
typedef struct {
gchar *update_compatible;
gchar *update_version;
gchar *update_description;
gchar *update_build;

gchar *keyring;

Expand Down
196 changes: 168 additions & 28 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#if ENABLE_JSON
#include <json-glib/json-glib.h>
#include <json-glib/json-gobject.h>
#endif

#include <config.h>
#include <bootchooser.h>
Expand All @@ -19,6 +23,7 @@ GMainLoop *r_loop = NULL;
int r_exit_status = 0;

gboolean info_noverify = FALSE;
gchar *output_format = NULL;

static gboolean install_notify(gpointer data) {
RaucInstallArgs *args = data;
Expand Down Expand Up @@ -262,6 +267,154 @@ static gboolean checksum_start(int argc, char **argv)
return TRUE;
}

static gchar *info_formatter_shell(RaucManifest *manifest)
{
GString *text = g_string_new(NULL);
gint cnt;

g_string_append_printf(text, "RAUC_MF_COMPATIBLE=%s\n", manifest->update_compatible);
g_string_append_printf(text, "RAUC_MF_VERSION=%s\n", manifest->update_version ?: "");
g_string_append_printf(text, "RAUC_MF_DESCRIPTION=%s\n", manifest->update_description ?: "");
g_string_append_printf(text, "RAUC_MF_BUILD=%s\n", manifest->update_build ?: "");
g_string_append_printf(text, "RAUC_MF_IMAGES=%d\n", g_list_length(manifest->images));
g_string_append_printf(text, "RAUC_MF_FILES=%d\n", g_list_length(manifest->files));

cnt = 0;
for (GList *l = manifest->images; l != NULL; l = l->next) {
RaucImage *img = l->data;
g_string_append_printf(text, "RAUC_IMAGE_NAME_%d=%s\n", cnt, img->filename);
g_string_append_printf(text, "RAUC_IMAGE_CLASS_%d=%s\n", cnt, img->slotclass);
g_string_append_printf(text, "RAUC_IMAGE_DIGEST_%d=%s\n", cnt, img->checksum.digest);
g_string_append_printf(text, "RAUC_IMAGE_SIZE_%d=%"G_GSIZE_FORMAT"\n", cnt, img->checksum.size);
cnt++;
}

cnt = 0;
for (GList *l = manifest->files; l != NULL; l = l->next) {
RaucFile *file = l->data;
g_string_append_printf(text, "RAUC_FILE_NAME_%d=%s\n", cnt, file->filename);
g_string_append_printf(text, "RAUC_FILE_CLASS_%d=%s\n", cnt, file->slotclass);
g_string_append_printf(text, "RAUC_FILE_DEST_%d=%s\n", cnt, file->destname);
g_string_append_printf(text, "RAUC_FILE_DIGEST_%d=%s\n", cnt, file->checksum.digest);
g_string_append_printf(text, "RAUC_FILE_SIZE_%d=%"G_GSIZE_FORMAT"\n", cnt, file->checksum.size);
cnt++;
}

return g_string_free(text, FALSE);
}

static gchar *info_formatter_readable(RaucManifest *manifest)
{
GString *text = g_string_new(NULL);
gint cnt;

g_string_append_printf(text, "Compatible: \t'%s'\n", manifest->update_compatible);
g_string_append_printf(text, "Version: \t'%s'\n", manifest->update_version);
g_string_append_printf(text, "Description:\t'%s'\n", manifest->update_description);
g_string_append_printf(text, "Build: \t'%s'\n", manifest->update_build);

cnt = g_list_length(manifest->images);
g_string_append_printf(text, "%d Image%s%s\n", cnt, cnt == 1 ? "" : "s", cnt > 0 ? ":" : "");
cnt = 1;
for (GList *l = manifest->images; l != NULL; l = l->next) {
RaucImage *img = l->data;
g_string_append_printf(text, "(%d)\t%s\n", cnt, img->filename);
g_string_append_printf(text, "\tSlotclass: %s\n", img->slotclass);
g_string_append_printf(text, "\tChecksum: %s\n", img->checksum.digest);
g_string_append_printf(text, "\tSize: %"G_GSIZE_FORMAT"\n", img->checksum.size);
cnt++;
}

cnt = g_list_length(manifest->files);
g_string_append_printf(text, "%d File%s%s\n", cnt, cnt == 1 ? "" : "s", cnt > 0 ? ":" : "");
cnt = 1;
for (GList *l = manifest->files; l != NULL; l = l->next) {
RaucFile *file = l->data;
g_string_append_printf(text, "(%d)\t%s\n", cnt, file->filename);
g_string_append_printf(text, "\tSlotclass: %s\n", file->slotclass);
g_string_append_printf(text, "\tDest: %s\n", file->destname);
g_string_append_printf(text, "\tChecksum: %s\n", file->checksum.digest);
g_string_append_printf(text, "\tSize: %"G_GSIZE_FORMAT"\n", file->checksum.size);
cnt++;
}

return g_string_free(text, FALSE);
}


static gchar* info_formatter_json_base(RaucManifest *manifest, gboolean pretty)
{
#if ENABLE_JSON
JsonGenerator *gen;
JsonNode * root;
gchar *str;
JsonBuilder *builder = json_builder_new ();

json_builder_begin_object (builder);

json_builder_set_member_name (builder, "compatible");
json_builder_add_string_value (builder, manifest->update_compatible);

json_builder_set_member_name (builder, "version");
json_builder_add_string_value (builder, manifest->update_version);

json_builder_set_member_name (builder, "description");
json_builder_add_string_value (builder, manifest->update_description);

json_builder_set_member_name (builder, "build");
json_builder_add_string_value (builder, manifest->update_build);

json_builder_set_member_name (builder, "images");
json_builder_begin_array (builder);

for (GList *l = manifest->images; l != NULL; l = l->next) {
RaucImage *img = l->data;

json_builder_begin_object (builder);
json_builder_set_member_name (builder, img->slotclass);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "filename");
json_builder_add_string_value (builder, img->filename);
json_builder_set_member_name (builder, "checksum");
json_builder_add_string_value (builder, img->checksum.digest);
json_builder_set_member_name (builder, "size");
json_builder_add_int_value (builder, img->checksum.size);
json_builder_end_object (builder);
json_builder_end_object (builder);

}

json_builder_end_array (builder);

json_builder_end_object (builder);

gen = json_generator_new ();
root = json_builder_get_root (builder);
json_generator_set_root (gen, root);
json_generator_set_pretty (gen, pretty);
str = json_generator_to_data (gen, NULL);

json_node_free (root);
g_object_unref (gen);
g_object_unref (builder);

return str;
#else
g_error("json support is disabled");
return NULL;
#endif
}

static gchar* info_formatter_json(RaucManifest *manifest)
{
return info_formatter_json_base(manifest, FALSE);
}

static gchar* info_formatter_json_pretty(RaucManifest *manifest)
{
return info_formatter_json_base(manifest, TRUE);
}

static gboolean info_start(int argc, char **argv)
{
gchar* tmpdir = NULL;
Expand All @@ -270,15 +423,26 @@ static gboolean info_start(int argc, char **argv)
RaucManifest *manifest = NULL;
GError *error = NULL;
gboolean res = FALSE;
gint cnt = 0;
gchar* (*formatter)(RaucManifest *manifest) = NULL;

if (argc != 3) {
g_warning("a file name must be provided");
r_exit_status = 1;
return FALSE;
}

g_print("checking manifest for: %s\n", argv[2]);
if (!output_format || g_strcmp0(output_format, "readable") == 0) {
formatter = info_formatter_readable;
} else if (g_strcmp0(output_format, "shell") == 0) {
formatter = info_formatter_shell;
} else if (ENABLE_JSON && g_strcmp0(output_format, "json") == 0) {
formatter = info_formatter_json;
} else if (ENABLE_JSON && g_strcmp0(output_format, "json-pretty") == 0) {
formatter = info_formatter_json_pretty;
} else {
g_printerr("Unknown output format: '%s'\n", output_format);
goto out;
}

tmpdir = g_dir_make_tmp("bundle-XXXXXX", &error);
if (!tmpdir) {
Expand All @@ -297,39 +461,14 @@ static gboolean info_start(int argc, char **argv)
goto out;
}


res = load_manifest_file(manifestpath, &manifest, &error);
if (!res) {
g_warning("%s", error->message);
g_clear_error(&error);
goto out;
}

g_print("Compatible String:\t'%s'\n", manifest->update_compatible);
g_print("Update version: \t'%s'\n", manifest->update_version);

cnt = g_list_length(manifest->images);
g_print("%d Image%s%s\n", cnt, cnt == 1 ? "" : "s", cnt > 0 ? ":" : "");
cnt = 0;
for (GList *l = manifest->images; l != NULL; l = l->next) {
RaucImage *img = l->data;
g_print("(%d)\t%s\n", ++cnt, img->filename);
g_print("\tSlotclass: %s\n", img->slotclass);
g_print("\tChecksum: %s\n", img->checksum.digest);
g_print("\tSize: %"G_GSIZE_FORMAT"\n", img->checksum.size);
}

cnt = g_list_length(manifest->files);
g_print("%d File%s%s\n", cnt, cnt == 1 ? "" : "s", cnt > 0 ? ":" : "");
cnt = 0;
for (GList *l = manifest->files; l != NULL; l = l->next) {
RaucFile *file = l->data;
g_print("(%d)\t%s\n", ++cnt, file->filename);
g_print("\tSlotclass: %s\n", file->slotclass);
g_print("\tDest: %s\n", file->destname);
g_print("\tChecksum: %s\n", file->checksum.digest);
g_print("\tSize: %"G_GSIZE_FORMAT"\n", file->checksum.size);
}
g_print("%s\n", formatter(manifest));

out:
r_exit_status = res ? 0 : 1;
Expand Down Expand Up @@ -462,6 +601,7 @@ typedef struct {

GOptionEntry entries_info[] = {
{"no-verify", '\0', 0, G_OPTION_ARG_NONE, &info_noverify, "disable bundle verification", NULL},
{"output-format", '\0', 0, G_OPTION_ARG_STRING, &output_format, "output format", "FORMAT"},
{0}
};

Expand Down
8 changes: 8 additions & 0 deletions src/manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ static gboolean parse_manifest(GKeyFile *key_file, RaucManifest **manifest, GErr
goto free;
}
raucm->update_version = g_key_file_get_string(key_file, "update", "version", NULL);
raucm->update_description = g_key_file_get_string(key_file, "update", "description", NULL);
raucm->update_build = g_key_file_get_string(key_file, "update", "build", NULL);

/* parse [keyring] section */
raucm->keyring = g_key_file_get_string(key_file, "keyring", "archive", NULL);
Expand Down Expand Up @@ -188,6 +190,12 @@ gboolean save_manifest_file(const gchar *filename, RaucManifest *mf, GError **er
if (mf->update_version)
g_key_file_set_string(key_file, "update", "version", mf->update_version);

if (mf->update_description)
g_key_file_set_string(key_file, "update", "description", mf->update_description);

if (mf->update_build)
g_key_file_set_string(key_file, "update", "build", mf->update_build);

if (mf->keyring)
g_key_file_set_string(key_file, "keyring", "archive", mf->keyring);

Expand Down
24 changes: 24 additions & 0 deletions test/rauc.t
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ test_description="rauc binary tests"

. ./sharness.sh

# Prerequisite: JSON support enabled [JSON]
grep -q "ENABLE_JSON 1" $SHARNESS_TEST_DIRECTORY/../config.h && \
test_set_prereq JSON

test_expect_success "rauc noargs" "
test_must_fail rauc
"
Expand Down Expand Up @@ -60,6 +64,26 @@ test_expect_success "rauc info" "
info $SHARNESS_TEST_DIRECTORY/good-bundle.raucb
"

test_expect_success "rauc info shell" "
rauc -c $SHARNESS_TEST_DIRECTORY/test.conf --output-format=shell \
info $SHARNESS_TEST_DIRECTORY/good-bundle.raucb
"

test_expect_success JSON "rauc info json" "
rauc -c $SHARNESS_TEST_DIRECTORY/test.conf --output-format=json \
info $SHARNESS_TEST_DIRECTORY/good-bundle.raucb
"

test_expect_success JSON "rauc info json-pretty" "
rauc -c $SHARNESS_TEST_DIRECTORY/test.conf --output-format=json-pretty \
info $SHARNESS_TEST_DIRECTORY/good-bundle.raucb
"

test_expect_success "rauc info invalid" "
test_must_fail rauc -c $SHARNESS_TEST_DIRECTORY/test.conf --output-format=invalid \
info $SHARNESS_TEST_DIRECTORY/good-bundle.raucb
"

test_expect_success "rauc bundle" "
rauc \
--cert $SHARNESS_TEST_DIRECTORY/openssl-ca/dev/autobuilder-1.cert.pem \
Expand Down

0 comments on commit 87ab3fd

Please sign in to comment.