mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 05:37:57 +00:00
"rhizome add file" manifest field=value varargs
Now a new manifest can be formed, and an existing manifest modified, by giving "field=value" or "!field" command-line arguments at the end of the "rhizome add file" command (after the <bsk> argument). This makes it easier to script rhizome operations.
This commit is contained in:
parent
c95807b002
commit
e633c0fa0a
@ -988,6 +988,31 @@ rhizome_manifest_parse_field(rhizome_manifest *m, const char *field_label, size_
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Remove the field with the given label from the manifest.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int rhizome_manifest_remove_field(rhizome_manifest *m, const char *field_label, size_t field_label_len)
|
||||
{
|
||||
if (!rhizome_manifest_field_label_is_valid(field_label, field_label_len)) {
|
||||
if (config.debug.rhizome_manifest)
|
||||
DEBUGF("Invalid manifest field name: %s", alloca_toprint(100, field_label, field_label_len));
|
||||
return 0;
|
||||
}
|
||||
const char *label = alloca_strndup(field_label, field_label_len);
|
||||
struct rhizome_manifest_field_descriptor *desc = NULL;
|
||||
unsigned i;
|
||||
for (i = 0; desc == NULL && i < NELS(rhizome_manifest_fields); ++i)
|
||||
if (strcasecmp(label, rhizome_manifest_fields[i].label) == 0)
|
||||
desc = &rhizome_manifest_fields[i];
|
||||
if (!desc)
|
||||
return rhizome_manifest_del(m, label);
|
||||
if (!desc->test(m))
|
||||
return 0;
|
||||
desc->unset(m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If all essential (transport) fields are present and well formed then sets the m->finalised field
|
||||
* and returns 1, otherwise returns 0.
|
||||
*
|
||||
|
@ -104,7 +104,7 @@ static int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_con
|
||||
|
||||
DEFINE_CMD(app_rhizome_add_file, 0,
|
||||
"Add a file to Rhizome and optionally write its manifest to the given path",
|
||||
"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]");
|
||||
"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]","...");
|
||||
DEFINE_CMD(app_rhizome_add_file, 0,
|
||||
"Append content to a journal bundle",
|
||||
"rhizome", "journal", "append" KEYRING_PIN_OPTIONS, "<author_sid>", "<manifestid>", "<filepath>", "[<bsk>]");
|
||||
@ -134,6 +134,42 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
|
||||
if (bsktext && str_to_rhizome_bsk_t(&bsk, bsktext) == -1)
|
||||
return WHYF("invalid bsk: \"%s\"", bsktext);
|
||||
|
||||
unsigned nfields = (parsed->varargi == -1) ? 0 : parsed->argc - (unsigned)parsed->varargi;
|
||||
struct field {
|
||||
const char *label;
|
||||
size_t labellen;
|
||||
const char *value;
|
||||
size_t valuelen;
|
||||
}
|
||||
fields[nfields];
|
||||
if (nfields) {
|
||||
assert(parsed->varargi >= 0);
|
||||
unsigned i;
|
||||
for (i = 0; i < nfields; ++i) {
|
||||
struct field *field = &fields[i];
|
||||
unsigned n = (unsigned)parsed->varargi + i;
|
||||
assert(n < parsed->argc);
|
||||
const char *arg = parsed->args[n];
|
||||
size_t arglen = strlen(arg);
|
||||
const char *eq;
|
||||
if (arglen > 0 && arg[0] == '!') {
|
||||
field->label = arg + 1;
|
||||
field->labellen = arglen - 1;
|
||||
field->value = NULL;
|
||||
} else if ((eq = strchr(arg, '='))) {
|
||||
field->label = arg;
|
||||
field->labellen = eq - arg;
|
||||
field->value = eq + 1;
|
||||
field->valuelen = (arg + arglen) - field->value;
|
||||
} else
|
||||
return WHYF("invalid manifest field argument: %s", alloca_str_toprint(arg));
|
||||
if (!rhizome_manifest_field_label_is_valid(field->label, field->labellen))
|
||||
return WHYF("invalid manifest field label: %s", alloca_toprint(-1, field->label, field->labellen));
|
||||
if (field->value && !rhizome_manifest_field_value_is_valid(field->value, field->valuelen))
|
||||
return WHYF("invalid manifest field value: %s", alloca_toprint(-1, field->value, field->valuelen));
|
||||
}
|
||||
}
|
||||
|
||||
int journal = strcasecmp(parsed->args[1], "journal")==0;
|
||||
|
||||
if (create_serval_instance_dir() == -1)
|
||||
@ -194,6 +230,43 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (nfields) {
|
||||
unsigned i;
|
||||
for (i = 0; i != nfields; ++i) {
|
||||
struct field *field = &fields[i];
|
||||
rhizome_manifest_remove_field(m, field->label, field->labellen);
|
||||
if (field->value) {
|
||||
const char *label = alloca_strndup(field->label, field->labellen);
|
||||
enum rhizome_manifest_parse_status status = rhizome_manifest_parse_field(m, field->label, field->labellen, field->value, field->valuelen);
|
||||
int status_ok = 0;
|
||||
switch (status) {
|
||||
case RHIZOME_MANIFEST_ERROR:
|
||||
ret = WHY("Fatal error while updating manifest field");
|
||||
goto finish;
|
||||
case RHIZOME_MANIFEST_OK:
|
||||
status_ok = 1;
|
||||
break;
|
||||
case RHIZOME_MANIFEST_SYNTAX_ERROR:
|
||||
ret = WHYF("Manifest syntax error: %s=%s", label, alloca_toprint(-1, field->value, field->valuelen));
|
||||
goto finish;
|
||||
case RHIZOME_MANIFEST_DUPLICATE_FIELD:
|
||||
abort(); // should not happen, field was removed first
|
||||
case RHIZOME_MANIFEST_INVALID:
|
||||
ret = WHYF("Manifest invalid field: %s=%s", label, alloca_toprint(-1, field->value, field->valuelen));
|
||||
goto finish;
|
||||
case RHIZOME_MANIFEST_MALFORMED:
|
||||
ret = WHYF("Manifest malformed field: %s=%s", label, alloca_toprint(-1, field->value, field->valuelen));
|
||||
goto finish;
|
||||
case RHIZOME_MANIFEST_OVERFLOW:
|
||||
ret = WHYF("Too many fields in manifest at: %s=%s", label, alloca_toprint(-1, field->value, field->valuelen));
|
||||
goto finish;
|
||||
}
|
||||
if (!status_ok)
|
||||
FATALF("status = %d", status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsktext) {
|
||||
if (m->has_id) {
|
||||
if (!rhizome_apply_bundle_secret(m, &bsk)) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Tests for Serval rhizome operations.
|
||||
# Tests for Serval rhizome command-line operations.
|
||||
#
|
||||
# Copyright 2012 Serval Project, Inc.
|
||||
# Copyright 2012-2014 Serval Project, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@ -107,6 +107,23 @@ test_AddManifestFieldUnsupported() {
|
||||
assert_manifest_fields file1.manifest bogus=one
|
||||
}
|
||||
|
||||
doc_AddManifestFieldUnsupportedArgs="Add with unsupported manifest field argument"
|
||||
setup_AddManifestFieldUnsupportedArgs() {
|
||||
setup_servald
|
||||
setup_rhizome
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list
|
||||
echo "A test file" >file1
|
||||
echo "Another test file" >file2
|
||||
}
|
||||
test_AddManifestFieldUnsupportedArgs() {
|
||||
executeOk_servald rhizome add file $SIDB1 file1 file1.manifest '' bogus=two
|
||||
assert_stdout_add_file file1
|
||||
tfw_cat -v file1.manifest
|
||||
assert_manifest_complete file1.manifest
|
||||
assert_manifest_fields file1.manifest bogus=two
|
||||
}
|
||||
|
||||
doc_AddNoAuthor="Add with no author makes manifest without BK"
|
||||
setup_AddNoAuthor() {
|
||||
setup_servald
|
||||
@ -190,6 +207,22 @@ test_AddManifest() {
|
||||
assert_manifest_fields file1.manifest service=file name=wah date=12345
|
||||
}
|
||||
|
||||
doc_AddManifestArgs="Add with minimal manifest from arguments"
|
||||
setup_AddManifestArgs() {
|
||||
setup_servald
|
||||
setup_rhizome
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list
|
||||
echo "A test file" >file1
|
||||
}
|
||||
test_AddManifestArgs() {
|
||||
executeOk_servald rhizome add file $SIDB1 file1 file1.manifest '' name=wah date=12345
|
||||
tfw_cat --stdout --stderr -v file1.manifest
|
||||
assert_stdout_add_file file1 name=wah
|
||||
assert_manifest_complete file1.manifest
|
||||
assert_manifest_fields file1.manifest service=file name=wah date=12345
|
||||
}
|
||||
|
||||
doc_AddEmpty="Add with empty payload"
|
||||
setup_AddEmpty() {
|
||||
setup_servald
|
||||
@ -389,7 +422,7 @@ test_LargePayload() {
|
||||
assert diff file1 file1x
|
||||
}
|
||||
|
||||
doc_CorruptExternalBlob="A corrupted payload should fail to export"
|
||||
doc_CorruptExternalBlob="Corrupted payload fails to export"
|
||||
setup_CorruptExternalBlob() {
|
||||
setup_servald
|
||||
setup_rhizome
|
||||
@ -775,6 +808,25 @@ test_AddUpdateAutoVersion() {
|
||||
assert_rhizome_list --fromhere=1 file1_2 file2
|
||||
}
|
||||
|
||||
doc_AddUpdateArgs="Update existing bundle using manifest args"
|
||||
setup_AddUpdateArgs() {
|
||||
setup_AddDeDuplicate
|
||||
extract_manifest_id BID file1.manifest
|
||||
cp file1.manifest file1_2.manifest
|
||||
}
|
||||
test_AddUpdateArgs() {
|
||||
sleep 0.001 # Ensure that at least one millisecond has elapsed
|
||||
executeOk_servald rhizome add file $SIDB1 file1_2 file1_2.manifest '' !version !filesize !filehash !date
|
||||
assert_stdout_add_file file1_2 name=file1
|
||||
assert_manifest_fields file1_2.manifest name=file1
|
||||
extract_manifest_id BID2 file1_2.manifest
|
||||
assert [ $BID = $BID2 ]
|
||||
assert_manifest_newer file1.manifest file1_2.manifest
|
||||
# Rhizome store contents reflect new payload.
|
||||
executeOk_servald rhizome list
|
||||
assert_rhizome_list --fromhere=1 file1_2 file2
|
||||
}
|
||||
|
||||
doc_AddServiceInvalid="Add with invalid service fails"
|
||||
setup_AddServiceInvalid() {
|
||||
setup_servald
|
||||
|
Loading…
Reference in New Issue
Block a user