diff --git a/bin/ch-run.c b/bin/ch-run.c index 5470e595b..45de86fdf 100644 --- a/bin/ch-run.c +++ b/bin/ch-run.c @@ -189,7 +189,7 @@ int main(int argc, char *argv[]) if (arg_next >= argc - 1) { printf("usage: ch-run [OPTION...] IMAGE -- COMMAND [ARG...]\n"); - FATAL("IMAGE and/or COMMAND not specified"); + FATAL(0, "IMAGE and/or COMMAND not specified"); } args.c.img_ref = argv[arg_next++]; args.c.newroot = realpath_(args.c.newroot, true); @@ -210,11 +210,11 @@ int main(int argc, char *argv[]) break; case IMG_SQUASH: #ifndef HAVE_LIBSQUASHFUSE - FATAL("this ch-run does not support internal SquashFS mounts"); + FATAL(0, "this ch-run does not support internal SquashFS mounts"); #endif break; case IMG_NONE: - FATAL("unknown image type: %s", args.c.img_ref); + FATAL(0, "unknown image type: %s", args.c.img_ref); break; } @@ -461,7 +461,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) #endif } else - FATAL("unknown feature: %s", arg); + FATAL(0, "unknown feature: %s", arg); break; case -12: // --home Tf (args->c.host_home = getenv("HOME"), "--home failed: $HOME not set"); @@ -492,7 +492,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) else if (!strcmp(arg, "log-fail")) test_logging(true); else - FATAL("invalid --test argument: %s; see source code", arg); + FATAL(0, "invalid --test argument: %s; see source code", arg); break; case 'b': { // --bind char *src, *dst; diff --git a/bin/ch_core.c b/bin/ch_core.c index 50a85b159..445bd3dcd 100644 --- a/bin/ch_core.c +++ b/bin/ch_core.c @@ -218,7 +218,7 @@ void bind_mount(const char *src, const char *dst, enum bind_dep dep, if (!path_exists(dst_full, NULL, true)) switch (dep) { case BD_REQUIRED: - FATAL("can't bind: destination not found: %s", dst_full); + FATAL(0, "can't bind: destination not found: %s", dst_full); break; case BD_OPTIONAL: return; @@ -400,7 +400,7 @@ enum img_type image_type(const char *ref, const char *storage_dir) return IMG_SQUASH; // Well now we’re stumped. - FATAL("unknown image type: %s", ref); + FATAL(0, "unknown image type: %s", ref); } char *img_name2path(const char *name, const char *storage_dir) @@ -546,9 +546,7 @@ void run_user_command(char *argv[], const char *initial_dir) if (verbose < LL_STDERR) T_ (freopen("/dev/null", "w", stderr)); execvp(argv[0], argv); // only returns if error - //Tf (0, "can't execve(2): %s", argv[0]); - //Terror (0, "can't execve(2): %s", argv[0]); - ERROR("can't execve(2): %s", argv[0]) + ERROR(errno, "can't execve(2): %s", argv[0]); exit(ERR_CMD); } diff --git a/bin/ch_fuse.c b/bin/ch_fuse.c index 2a8a56c4c..b5ee928a0 100644 --- a/bin/ch_fuse.c +++ b/bin/ch_fuse.c @@ -249,7 +249,7 @@ void sq_mount(const char *img_path, char *mountpt) &OPS, sizeof(OPS), sq.ll)) { break; // success } else if (i <= 0) { - FATAL("too many FUSE errors; giving up"); + FATAL(0, "too many FUSE errors; giving up"); } else { WARNING("FUSE error mounting SquashFS; will retry"); sleep(1); diff --git a/bin/ch_misc.c b/bin/ch_misc.c index 040004f9b..674fdb2df 100644 --- a/bin/ch_misc.c +++ b/bin/ch_misc.c @@ -449,7 +449,7 @@ void test_logging(bool fail) { INFO("info"); WARNING("warning"); if (fail) - FATAL("the program failed inexplicably (\"log-fail\" specified)"); + FATAL(0, "the program failed inexplicably (\"log-fail\" specified)"); exit(0); } @@ -587,7 +587,7 @@ void msg(enum log_level level, const char *file, int line, int errno_, } void msg_error(const char *file, int line, int errno_, - const char *fmt, ...) + const char *fmt, ...) { va_list ap; diff --git a/bin/ch_misc.h b/bin/ch_misc.h index c88103679..c86755236 100644 --- a/bin/ch_misc.h +++ b/bin/ch_misc.h @@ -72,13 +72,13 @@ #define Zf(x, ...) if (x) msg_fatal(__FILE__, __LINE__, errno, __VA_ARGS__) #define Ze(x, ...) if (x) msg_fatal(__FILE__, __LINE__, 0, __VA_ARGS__) -#define FATAL(...) msg_fatal( __FILE__, __LINE__, 0, __VA_ARGS__); -#define ERROR(...) msg_error( __FILE__, __LINE__, 0, __VA_ARGS__); -#define WARNING(...) msg(LL_WARNING, __FILE__, __LINE__, 0, __VA_ARGS__); -#define INFO(...) msg(LL_INFO, __FILE__, __LINE__, 0, __VA_ARGS__); -#define VERBOSE(...) msg(LL_VERBOSE, __FILE__, __LINE__, 0, __VA_ARGS__); -#define DEBUG(...) msg(LL_DEBUG, __FILE__, __LINE__, 0, __VA_ARGS__); -#define TRACE(...) msg(LL_TRACE, __FILE__, __LINE__, 0, __VA_ARGS__); +#define FATAL(e, ...) msg_fatal( __FILE__, __LINE__, e, __VA_ARGS__); +#define ERROR(e, ...) msg_error( __FILE__, __LINE__, e, __VA_ARGS__); +#define WARNING(...) msg(LL_WARNING, __FILE__, __LINE__, 0, __VA_ARGS__); +#define INFO(...) msg(LL_INFO, __FILE__, __LINE__, 0, __VA_ARGS__); +#define VERBOSE(...) msg(LL_VERBOSE, __FILE__, __LINE__, 0, __VA_ARGS__); +#define DEBUG(...) msg(LL_DEBUG, __FILE__, __LINE__, 0, __VA_ARGS__); +#define TRACE(...) msg(LL_TRACE, __FILE__, __LINE__, 0, __VA_ARGS__); /** Types **/ diff --git a/lib/build.py b/lib/build.py index a8be3a38a..dc3b5389d 100644 --- a/lib/build.py +++ b/lib/build.py @@ -322,18 +322,22 @@ def modify(cli_): fake_sid = uuid.uuid4() out_image.unpack_clear() out_image.copy_unpacked(src_image) - bu.cache.worktree_adopt(out_image, "root") + bu.cache.worktree_adopt(out_image, src_image.ref.for_path) bu.cache.ready(out_image) bu.cache.branch_nocheckout(src_image.ref, out_image.ref) foo = subprocess.run([ch.CH_BIN + "/ch-run", "--unsafe", "-w", str(out_image.ref), "--", shell]) - if (foo.returncode == 57): + if (foo.returncode == 58): # FIXME: Write a better error message? ch.FATAL("Unable to run shell: %s" % shell) ch.ILLERI("retcode: %s" % foo.returncode) ch.VERBOSE("using SID %s" % fake_sid) - bu.cache.commit(out_image.unpack_path, fake_sid, "MODIFY interactive", []) # FIXME: metadata history stuff? See misc.import_. + if (out_image.metadata["history"] == []): + out_image.metadata["history"].append({ "empty_layer": False, + "command": "ch-image import"}) + out_image.metadata_save() + bu.cache.commit(out_image.unpack_path, fake_sid, "MODIFY interactive", []) def modify_tree_make(src_img, cmds): """Function that manually constructs a parse tree corresponding to a set of diff --git a/test/build/50_ch-image.bats b/test/build/50_ch-image.bats index e6e61ddc9..f594e606c 100644 --- a/test/build/50_ch-image.bats +++ b/test/build/50_ch-image.bats @@ -869,12 +869,12 @@ EOF run ch-run -v "$CH_IMAGE_STORAGE"/img/alpine+3.17 -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *"error: can't run directory images from storage (hint: run by name)"* ]] run ch-run -v -s /doesnotexist alpine:3.17 -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *'warning: storage directory not found: /doesnotexist'* ]] [[ $output = *"error: can't stat: alpine:3.17: No such file or directory"* ]] } diff --git a/test/run/ch-run_escalated.bats b/test/run/ch-run_escalated.bats index 9bac753f6..e90492ed8 100644 --- a/test/run/ch-run_escalated.bats +++ b/test/run/ch-run_escalated.bats @@ -15,7 +15,7 @@ load ../common [[ -g $ch_run_tmp ]] run "$ch_run_tmp" --version echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *': please report this bug ('* ]] rm "$ch_run_tmp" } @@ -32,7 +32,7 @@ load ../common [[ -u $ch_run_tmp ]] run "$ch_run_tmp" --version echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *': please report this bug ('* ]] sudo rm "$ch_run_tmp" } @@ -71,7 +71,7 @@ load ../common fi run sudo -u root -g "$(id -gn)" "$ch_runfile" -v --version echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *'please report this bug ('* ]] } diff --git a/test/run/ch-run_join.bats b/test/run/ch-run_join.bats index 07afb2fcc..3a7555686 100644 --- a/test/run/ch-run_join.bats +++ b/test/run/ch-run_join.bats @@ -267,36 +267,36 @@ unset_vars () { # --join but no join count run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'join: no valid peer group size found' ]] ipc_clean_p # join count no digits run ch-run --join-ct=a "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'join-ct: no digits found' ]] SLURM_CPUS_ON_NODE=a run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'SLURM_CPUS_ON_NODE: no digits found' ]] ipc_clean_p # join count empty string run ch-run --join-ct='' "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ '--join-ct: no digits found' ]] SLURM_CPUS_ON_NODE=-1 run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'join: no valid peer group size found' ]] ipc_clean_p # --join-ct digits followed by extra goo (OK from environment variable) run ch-run --join-ct=1a "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ '--join-ct: extra characters after digits' ]] ipc_clean_p @@ -306,48 +306,48 @@ unset_vars () { # join count above INT_MAX run ch-run --join-ct=2147483648 "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] SLURM_CPUS_ON_NODE=2147483648 \ run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] ipc_clean_p # join count below INT_MIN run ch-run --join-ct=-2147483649 "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] SLURM_CPUS_ON_NODE=-2147483649 \ run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] ipc_clean_p # join count above LONG_MAX run ch-run --join-ct=9223372036854775808 "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] SLURM_CPUS_ON_NODE=9223372036854775808 \ run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] ipc_clean_p # join count below LONG_MIN run ch-run --join-ct=-9223372036854775809 "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] SLURM_CPUS_ON_NODE=-9223372036854775809 \ run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ $range_re ]] ipc_clean_p } @@ -361,11 +361,11 @@ unset_vars () { # join tag empty string run ch-run --join-tag='' "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'join: peer group tag cannot be empty string' ]] SLURM_STEP_ID='' run ch-run --join "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output =~ 'join: peer group tag cannot be empty string' ]] ipc_clean_p } @@ -473,7 +473,7 @@ unset_vars () { pid=2147483647 run ch-run -v --join-pid="$pid" "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *"join: no PID ${pid}: /proc/${pid}/ns/user not found"* ]] } diff --git a/test/run/ch-run_misc.bats b/test/run/ch-run_misc.bats index dbe4e8c12..3f88bbef0 100644 --- a/test/run/ch-run_misc.bats +++ b/test/run/ch-run_misc.bats @@ -121,7 +121,7 @@ EOF run ch-run --home "$ch_timg" -- /bin/sh -c 'echo $HOME' export HOME="$home_tmp" echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] # shellcheck disable=SC2016 [[ $output = *'--home failed: $HOME not set'* ]] @@ -132,7 +132,7 @@ EOF run ch-run --home "$ch_timg" -- /bin/sh -c 'echo $HOME' export USER=$user_tmp echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] # shellcheck disable=SC2016 [[ $output = *'$USER not set'* ]] } @@ -291,10 +291,10 @@ EOF [[ $status -eq 0 ]] # --home - run ch-run --home "$img" -- ls -lah /home + run ch-run --home "$img" -- ls -lAh /home echo "$output" [[ $status -eq 0 ]] - [[ $(echo "$output" | wc -l) -eq 3 ]] + [[ $(echo "$output" | wc -l) -eq 5 ]] [[ $output = *directory-in-home* ]] [[ $output = *file-in-home* ]] [[ $output = *"$USER"* ]] @@ -625,7 +625,7 @@ EOF # /ch/environment missing run ch-run --set-env "$ch_timg" -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *"can't open: /ch/environment: No such file or directory"* ]] # Note: I’m not sure how to test an error during reading, i.e., getline(3) @@ -635,14 +635,14 @@ EOF echo 'FOO bar' > "$f_in" run ch-run --set-env="$f_in" "$ch_timg" -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *"can't parse variable: no delimiter: ${f_in}:1"* ]] # invalid line: no name echo '=bar' > "$f_in" run ch-run --set-env="$f_in" "$ch_timg" -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output = *"can't parse variable: empty name: ${f_in}:1"* ]] } @@ -947,7 +947,7 @@ EOF # This should start up the container OK but fail to find the user command. run ch-run "$img" -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output = *"can't execve(2): /bin/true: No such file or directory"* ]] # For each required file, we want a correct error if it’s missing. @@ -958,7 +958,7 @@ EOF run ch-run "$img" -- /bin/true touch "${img}/${f}" # restore before test fails for idempotency echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] r="can't bind: destination not found: .+/${f}" echo "expected: ${r}" [[ $output =~ $r ]] @@ -971,7 +971,7 @@ EOF run ch-run "$img" -- /bin/true touch "${img}/${f}" # restore before test fails for idempotency echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output = *"can't execve(2): /bin/true: No such file or directory"* ]] done @@ -984,7 +984,7 @@ EOF rmdir "${img}/${f}" # restore before test fails for idempotency touch "${img}/${f}" echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] r="can't bind .+ to /.+/${f}: Not a directory" echo "expected: ${r}" [[ $output =~ $r ]] @@ -997,7 +997,7 @@ EOF run ch-run "$img" -- /bin/true mkdir "${img}/${d}" # restore before test fails for idempotency echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] r="can't bind: destination not found: .+/${d}" echo "expected: ${r}" [[ $output =~ $r ]] @@ -1012,7 +1012,7 @@ EOF rm "${img}/${d}" # restore before test fails for idempotency mkdir "${img}/${d}" echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] r="can't bind .+ to /.+/${d}: Not a directory" echo "expected: ${r}" [[ $output =~ $r ]] @@ -1023,7 +1023,7 @@ EOF run ch-run --private-tmp "$img" -- /bin/true mkdir "${img}/tmp" # restore before test fails for idempotency echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] r="can't mount tmpfs at /.+/tmp: No such file or directory" echo "expected: ${r}" [[ $output =~ $r ]] @@ -1033,13 +1033,13 @@ EOF run ch-run "$img" -- /bin/true mkdir "${img}/home" # restore before test fails for idempotency echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output = *"can't execve(2): /bin/true: No such file or directory"* ]] # Everything should be restored and back to the original error. run ch-run "$img" -- /bin/true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output = *"can't execve(2): /bin/true: No such file or directory"* ]] # At this point, there should be exactly two each of passwd and group @@ -1143,7 +1143,7 @@ EOF # subprocess failure at quiet level 2 run ch-run -qq "$ch_timg" -- doesnotexist echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output = *"error: can't execve(2): doesnotexist: No such file or directory"* ]] # quiet level 3 @@ -1156,13 +1156,12 @@ EOF # subprocess failure at quiet level 3 run ch-run -qqq "$ch_timg" -- doesnotexist echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 58 ]] [[ $output != *"error: can't execve(2): doesnotexist: No such file or directory"* ]] # failure at quiet level 3 run ch-run -qqq --test=log-fail - echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output != *'info'* ]] [[ $output != *'warning: warning'* ]] [[ $output = *'error: the program failed inexplicably'* ]] @@ -1174,6 +1173,6 @@ EOF # bad tmpfs size run ch-run --write-fake=foo "$ch_timg" -- true echo "$output" - [[ $status -eq 1 ]] + [[ $status -eq 57 ]] [[ $output == *'cannot mount tmpfs for overlay: Invalid argument'* ]] }