diff --git a/seed/script-generator.c b/seed/script-generator.c index e54cd539..9150daf3 100644 --- a/seed/script-generator.c +++ b/seed/script-generator.c @@ -541,6 +541,36 @@ void output_resume_network_init(FILE *out) { fputs("fi\n", out); } +void output_init_failure_shell(FILE *out) { + fputs("status=$?\n", out); + fputs("echo \"bootstrap script failed with status ${status}; dropping to rescue shell\" >&2\n", out); + fputs("PATH=/bin:/usr/bin:/sbin:/usr/sbin:${PREFIX}/bin:${PATH}\n", out); + fputs("while true; do\n", out); + fputs("if command -v bash >/dev/null 2>&1; then\n", out); + fputs("env PS1=\"[FAIL ${status}] \\\\w # \" bash -i\n", out); + fputs("elif command -v sh >/dev/null 2>&1; then\n", out); + fputs("env PS1=\"[FAIL ${status}] \\\\w # \" sh -i\n", out); + fputs("else\n", out); + fputs("echo \"No interactive shell available; sleeping.\" >&2\n", out); + fputs("sleep 60\n", out); + fputs("fi\n", out); + fputs("done\n", out); +} + +void output_init_call_script(FILE *out, char *name, int bash_build) { + if (bash_build) { + fputs("if ! bash ", out); + write_steps_prefix(out); + fputs(name, out); + fputs(".sh\n", out); + fputs("then\n", out); + output_init_failure_shell(out); + fputs("fi\n", out); + } else { + output_call_script(out, "", name, bash_build, 0); + } +} + void output_build(FILE *out, Directive *directive, int pass_no, int bash_build) { if (bash_build) { fputs("build ", out); @@ -670,7 +700,7 @@ void generate(Directive *directives) { } fputs("set -ex\n", out); } - output_call_script(out, "", int2str(counter, 10, 0), bash_build, 0); + output_init_call_script(out, int2str(counter, 10, 0), bash_build); fclose(out); out = start_script(counter, bash_build); counter += 1;