From owner-freebsd-sysinstall@FreeBSD.ORG Fri May 15 17:01:19 2015 Return-Path: Delivered-To: freebsd-sysinstall@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C61B94EF; Fri, 15 May 2015 17:01:19 +0000 (UTC) Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1on0082.outbound.protection.outlook.com [157.56.110.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (Client CN "mail.protection.outlook.com", Issuer "MSIT Machine Auth CA 2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 15C3B167D; Fri, 15 May 2015 17:01:15 +0000 (UTC) Authentication-Results: FreeBSD.org; dkim=none (message not signed) header.d=none; Received: from [172.17.3.251] (63.252.212.99) by CO2PR0801MB662.namprd08.prod.outlook.com (10.141.247.25) with Microsoft SMTP Server (TLS) id 15.1.154.19; Fri, 15 May 2015 17:01:07 +0000 Message-ID: <5556264C.7080708@panasas.com> Date: Fri, 15 May 2015 13:01:00 -0400 From: "Ellis H. Wilson III" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: Allan Jude , , Subject: Re: RFC: Patches to achieve bsdinstall script without dialogs References: <54EF7B40.2030706@panasas.com> <551172FC.1010508@panasas.com> <55117618.8020308@freebsd.org> In-Reply-To: <55117618.8020308@freebsd.org> Content-Type: multipart/mixed; boundary="------------010905000303080601070703" X-Originating-IP: [63.252.212.99] X-ClientProxiedBy: CY1PR13CA0007.namprd13.prod.outlook.com (25.162.30.145) To CO2PR0801MB662.namprd08.prod.outlook.com (10.141.247.25) X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CO2PR0801MB662; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:CO2PR0801MB662; BCL:0; PCL:0; RULEID:; SRVR:CO2PR0801MB662; X-Forefront-PRVS: 0577AD41D6 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6049001)(6009001)(24454002)(377454003)(51704005)(479174004)(77096005)(5001770100001)(59896002)(189998001)(5001960100002)(107886002)(83506001)(50986999)(54356999)(87266999)(76176999)(80316001)(65816999)(19580395003)(84326002)(46102003)(4610100001)(4810100001)(5890100001)(65956001)(66066001)(86362001)(99136001)(42186005)(87976001)(33656002)(2201001)(77156002)(62966003)(36756003)(92566002)(40100003)(450100001)(512944002)(2950100001)(568964001)(122386002)(4001350100001); DIR:OUT; SFP:1101; SCL:1; SRVR:CO2PR0801MB662; H:[172.17.3.251]; FPR:; SPF:None; MLV:sfv; LANG:en; X-OriginatorOrg: panasas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2015 17:01:07.1407 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO2PR0801MB662 X-BeenThere: freebsd-sysinstall@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Sysinstall Work List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 May 2015 17:01:20 -0000 --------------010905000303080601070703 Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit On 03/24/2015 10:35 AM, Allan Jude wrote: > These changes look ok to me. > > 2 main things: These would need to be based on HEAD not 10.1 in order to > be committed Nathan, Allan, et. al.: Please see attached for a new set of patches based off of HEAD. Sorry this took some time for me to get back to. Notes follow: The following experienced no real changes between 10.1 (which my last patches were based on) and HEAD, and therefore can be deemed completely safe: usr.sbin/bsdconfig/share/common.subr usr.sbin/bsdinstall/scripts/checksum usr.sbin/bsdinstall/scripts/script The following experienced changes, but the existing patch went through without any problems. I visually inspected it afterwards and it looked perfectly fine: usr.sbin/bsdinstall/partedit/scripted.c The following experienced minor changes such that the patch failed, but only needed minor modifications to achieve the same intent: usr.sbin/bsdinstall/partedit/partedit.h usr.sbin/bsdinstall/partedit/partedit.c The following was significantly changed from the 10.1 version. Since the new version used dpv, which makes ASCII output difficult, the cleanest solution I could identify was to forward port some of the old logic. There may be a better way to do this, but this is my attempt. I defer to the original author's best judgement. usr.sbin/bsdinstall/distextract/distextract.c All of our machines are running 10.1 or older, so I wasn't able to compile and test the changes above since they lack dpv. I therefore fired up a VM and made sure they at least compile. Particularly in the last case (distextract), the patch should be tested before being committed. I apologize I don't have the resources to do this myself currently. Best, ellis --------------010905000303080601070703 Content-Type: text/x-patch; name="checksum.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="checksum.patch" Index: usr.sbin/bsdinstall/scripts/checksum =================================================================== --- usr.sbin/bsdinstall/scripts/checksum (revision 282864) +++ usr.sbin/bsdinstall/scripts/checksum (working copy) @@ -28,6 +28,10 @@ test -f $BSDINSTALL_DISTDIR/MANIFEST || exit 0 +if [ "$BSDINSTALL_SCRIPTED" -eq 1 ]; then + printf "$0: Verifying checksums of selected distributions:\n" +fi + percentage=0 for dist in $DISTRIBUTIONS; do distname=$(basename $dist .txz) @@ -37,10 +41,15 @@ for i in $DISTRIBUTIONS; do items="$items $i `eval echo \\\${status_$(basename $i .txz):-Pending}`" done - dialog --backtitle "FreeBSD Installer" --title "Checksum Verification" \ - --mixedgauge "Verifying checksums of selected distributions." \ - 0 0 $percentage $items + if [ -z "$BSDINSTALL_SCRIPTED" || "$BSDINSTALL_SCRIPTED" -ne 1 ]; then + dialog --backtitle "FreeBSD Installer" --title "Checksum Verification" \ + --mixedgauge "Verifying checksums of selected distributions." \ + 0 0 $percentage $items + else + printf "$0:\tVerifying $distname...\n" + fi + CK=`sha256 -q $BSDINSTALL_DISTDIR/$dist` awk -v checksum=$CK -v dist=$dist -v found=0 '{ if (dist == $1) { @@ -62,8 +71,12 @@ percentage=$(echo $percentage + 100/`echo $DISTRIBUTIONS | wc -w` | bc) else eval "status_$distname=1" - dialog --backtitle "FreeBSD Installer" --title "Error" \ - --msgbox "The checksum for $dist does not match. It may have become corrupted, and should be redownloaded." 0 0 + if [ -z "$BSDINSTALL_SCRIPTED" || "$BSDINSTALL_SCRIPTED" -ne 1 ]; then + dialog --backtitle "FreeBSD Installer" --title "Error" \ + --msgbox "The checksum for $dist does not match. It may have become corrupted, and should be redownloaded." 0 0 + else + printf "$0: Error: The checksum for $dist does not match. It may have become corrupted, and should be redownloaded.\n" + fi exit 1 fi done --------------010905000303080601070703 Content-Type: text/x-patch; name="common.subr.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="common.subr.patch" Index: usr.sbin/bsdconfig/share/common.subr =================================================================== --- usr.sbin/bsdconfig/share/common.subr (revision 282864) +++ usr.sbin/bsdconfig/share/common.subr (working copy) @@ -129,11 +129,12 @@ { [ "$debug" ] || return $SUCCESS local fmt="$1"; shift + local iso8601=$(date -u +"%Y-%m-%dT%H:%M:%SZ"); case "$debugFile" in ""|+*) - printf "DEBUG: $fmt${fmt:+\n}" "$@" >&${TERMINAL_STDOUT_PASSTHRU:-1} + printf "$iso8601: DEBUG: $fmt${fmt:+\n}" "$@" >&${TERMINAL_STDOUT_PASSTHRU:-1} esac [ "${debugFile#+}" ] && - printf "DEBUG: $fmt${fmt:+\n}" "$@" >> "${debugFile#+}" + printf "$iso8601: DEBUG: $fmt${fmt:+\n}" "$@" >> "${debugFile#+}" return $SUCCESS } --------------010905000303080601070703 Content-Type: text/x-patch; name="distextract.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="distextract.c.patch" Index: usr.sbin/bsdinstall/distextract/distextract.c =================================================================== --- usr.sbin/bsdinstall/distextract/distextract.c (revision 282864) +++ usr.sbin/bsdinstall/distextract/distextract.c (working copy) @@ -39,6 +39,7 @@ #include #include #include +#include #include /* Data to process */ @@ -50,7 +51,11 @@ static void sig_int(int sig); static int count_files(const char *file); static int extract_files(struct dpv_file_node *file, int out); +static int extract_files_scripted(int nfiles, const char **files); +static void scripted_printf(const char *fmt, ...); +static int do_scripted = 0; + #if __FreeBSD_version <= 1000008 /* r232154: bump for libarchive update */ #define archive_read_support_filter_all(x) \ archive_read_support_compression_all(x) @@ -63,7 +68,8 @@ { char *chrootdir; char *distributions; - int retval; + const char **script_dists; + int i, retval, ndists = 0; size_t config_size = sizeof(struct dpv_config); size_t file_node_size = sizeof(struct dpv_file_node); size_t span; @@ -81,55 +87,73 @@ if ((distdir = getenv("BSDINSTALL_DISTDIR")) == NULL) distdir = __DECONST(char *, ""); - /* Initialize dialog(3) */ - init_dialog(stdin, stdout); - dialog_vars.backtitle = backtitle; - dlg_put_backtitle(); + if (getenv("BSDINSTALL_SCRIPTED") && strcmp(getenv("BSDINSTALL_SCRIPTED"), "1") == 0) + do_scripted = 1; - dialog_msgbox("", - "Checking distribution archives.\nPlease wait...", 4, 35, FALSE); + if (!do_scripted) { + /* Initialize dialog(3) */ + init_dialog(stdin, stdout); + dialog_vars.backtitle = backtitle; + dlg_put_backtitle(); + dialog_msgbox("", + "Checking distribution archives.\nPlease wait...", 4, 35, FALSE); - /* - * Parse $DISTRIBUTIONS into dpv(3) linked-list - */ - while (*distributions != '\0') { - span = strcspn(distributions, "\t\n\v\f\r "); - if (span < 1) { /* currently on whitespace */ - distributions++; - continue; - } + /* + * Parse $DISTRIBUTIONS into dpv(3) linked-list + */ + while (*distributions != '\0') { + span = strcspn(distributions, "\t\n\v\f\r "); + if (span < 1) { /* currently on whitespace */ + distributions++; + continue; + } - /* Allocate a new struct for the distribution */ - if (dist == NULL) { - if ((dist = calloc(1, file_node_size)) == NULL) + /* Allocate a new struct for the distribution */ + if (dist == NULL) { + if ((dist = calloc(1, file_node_size)) == NULL) + _errx(EXIT_FAILURE, "Out of memory!"); + dists = dist; + } else { + dist->next = calloc(1, file_node_size); + if (dist->next == NULL) + _errx(EXIT_FAILURE, "Out of memory!"); + dist = dist->next; + } + + /* Set path */ + if ((dist->path = malloc(span + 1)) == NULL) _errx(EXIT_FAILURE, "Out of memory!"); - dists = dist; - } else { - dist->next = calloc(1, file_node_size); - if (dist->next == NULL) - _errx(EXIT_FAILURE, "Out of memory!"); - dist = dist->next; - } + snprintf(dist->path, span + 1, "%s", distributions); + dist->path[span] = '\0'; - /* Set path */ - if ((dist->path = malloc(span + 1)) == NULL) - _errx(EXIT_FAILURE, "Out of memory!"); - snprintf(dist->path, span + 1, "%s", distributions); - dist->path[span] = '\0'; + /* Set display name */ + dist->name = strrchr(dist->path, '/'); + if (dist->name == NULL) + dist->name = dist->path; - /* Set display name */ - dist->name = strrchr(dist->path, '/'); - if (dist->name == NULL) - dist->name = dist->path; + /* Set initial length in files (-1 == error) */ + dist->length = count_files(dist->path); + if (dist->length < 0) { + end_dialog(); + return (EXIT_FAILURE); + } - /* Set initial length in files (-1 == error) */ - dist->length = count_files(dist->path); - if (dist->length < 0) { - end_dialog(); - return (EXIT_FAILURE); + distributions += span; } + } else { + scripted_printf("Checking distribution archives. Please wait...\n"); - distributions += span; + for (i = 0; distributions[i] != 0; i++) + if (isspace(distributions[i]) && !isspace(distributions[i+1])) + ndists++; + ndists++; /* Last one */ + + script_dists = calloc(ndists, sizeof(const char *)); + if (script_dists == NULL) + errx(EXIT_FAILURE, "Out of memory!"); + + for (i = 0; i < ndists; i++) + script_dists[i] = strsep(&distributions, " \t"); } /* Optionally chdir(2) into $BSDINSTALL_CHROOT */ @@ -138,40 +162,48 @@ snprintf(error, sizeof(error), "Could not change to directory %s: %s\n", chrootdir, strerror(errno)); - dialog_msgbox("Error", error, 0, 0, TRUE); - end_dialog(); + if (!do_scripted) { + dialog_msgbox("Error", error, 0, 0, TRUE); + end_dialog(); + } else + scripted_printf("Error: %s\n", error); return (EXIT_FAILURE); } - /* Set cleanup routine for Ctrl-C action */ - act.sa_handler = sig_int; - sigaction(SIGINT, &act, 0); + if (!do_scripted) { + /* Set cleanup routine for Ctrl-C action */ + act.sa_handler = sig_int; + sigaction(SIGINT, &act, 0); + + /* + * Hand off to dpv(3) + */ + if ((config = calloc(1, config_size)) == NULL) + _errx(EXIT_FAILURE, "Out of memory!"); + config->backtitle = backtitle; + config->title = title; + config->pprompt = pprompt; + config->aprompt = aprompt; + config->options |= DPV_WIDE_MODE; + config->label_size = -1; + config->action = extract_files; + config->status_solo = + "%10lli files read @ %'9.1f files/sec."; + config->status_many = + "%10lli files read @ %'9.1f files/sec. [%i/%i busy/wait]"; + end_dialog(); + retval = dpv(config, dists); - /* - * Hand off to dpv(3) - */ - if ((config = calloc(1, config_size)) == NULL) - _errx(EXIT_FAILURE, "Out of memory!"); - config->backtitle = backtitle; - config->title = title; - config->pprompt = pprompt; - config->aprompt = aprompt; - config->options |= DPV_WIDE_MODE; - config->label_size = -1; - config->action = extract_files; - config->status_solo = - "%10lli files read @ %'9.1f files/sec."; - config->status_many = - "%10lli files read @ %'9.1f files/sec. [%i/%i busy/wait]"; - end_dialog(); - retval = dpv(config, dists); - - dpv_free(); - while ((dist = dists) != NULL) { - dists = dist->next; - if (dist->path != NULL) - free(dist->path); - free(dist); + dpv_free(); + while ((dist = dists) != NULL) { + dists = dist->next; + if (dist->path != NULL) + free(dist->path); + free(dist); + } + } else { + retval = extract_files_scripted(ndists, script_dists); + free(script_dists); } return (retval); @@ -235,7 +267,10 @@ if ((archive = archive_read_new()) == NULL) { snprintf(errormsg, sizeof(errormsg), "Error: %s\n", archive_error_string(NULL)); - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + if (!do_scripted) + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + else + scripted_printf("Extract Error: %s\n", errormsg); return (-1); } archive_read_support_format_all(archive); @@ -246,7 +281,10 @@ snprintf(errormsg, sizeof(errormsg), "Error while extracting %s: %s\n", file, archive_error_string(archive)); - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + if (!do_scripted) + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + else + scripted_printf("Extract Error: %s\n", errormsg); archive = NULL; return (-1); } @@ -273,7 +311,10 @@ if ((archive = archive_read_new()) == NULL) { snprintf(errormsg, sizeof(errormsg), "Error: %s\n", archive_error_string(NULL)); - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + if (!do_scripted) + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + else + scripted_printf("Extract Error: %s\n", errormsg); dpv_abort = 1; return (-1); } @@ -285,7 +326,10 @@ snprintf(errormsg, sizeof(errormsg), "Error opening %s: %s\n", file->name, archive_error_string(archive)); - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + if (!do_scripted) + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + else + scripted_printf("Extract Error: %s\n", errormsg); file->status = DPV_STATUS_FAILED; dpv_abort = 1; return (-1); @@ -310,9 +354,12 @@ return (100); } else if (retval != ARCHIVE_OK) { snprintf(errormsg, sizeof(errormsg), - "Error while extracting %s: %s\n", file->name, - archive_error_string(archive)); - dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + "Error while extracting %s: %s\n", file->name, + archive_error_string(archive)); + if (!do_scripted) + dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE); + else + scripted_printf("Extract Error: %s\n", errormsg); file->status = DPV_STATUS_FAILED; dpv_abort = 1; return (-1); @@ -327,3 +374,113 @@ else return (-1); } + +static int +extract_files_scripted(int nfiles, const char **files) +{ + const char *items[nfiles]; + char path[PATH_MAX]; + int archive_files[nfiles]; + int total_files, current_files, archive_file; + struct archive_entry *entry; + char errormsg[512]; + int i, err, progress, last_progress, last_progress_step; + + err = 0; + progress = 0; + + for (i = 0; i < nfiles; i++) { + items[i] = strrchr(files[i], '/'); + if (items[i] != NULL) + items[i]++; + else + items[i] = files[i]; + } + + scripted_printf("Checking distribution archives. Please wait...\n"); + + /* Count all the files */ + total_files = 0; + for (i = 0; i < nfiles; i++) { + archive_files[i] = count_files(files[i]); + if (archive_files[i] < 0) + return (-1); + total_files += archive_files[i]; + } + + current_files = 0; + last_progress_step = 0; + + scripted_printf("Extracting distribution files (0%%)"); + for (i = 0; i < nfiles; i++) { + archive = archive_read_new(); + archive_read_support_format_all(archive); + archive_read_support_filter_all(archive); + sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), files[i]); + err = archive_read_open_filename(archive, path, 4096); + + archive_file = 0; + + while ((err = archive_read_next_header(archive, &entry)) == + ARCHIVE_OK) { + last_progress = progress; + progress = (current_files*100)/total_files; + + if (progress > last_progress) { + if (progress >= last_progress_step + 10) { + printf("\n"); + scripted_printf("Extracting distribution files (%d%%)", progress); + last_progress_step = progress; + } else { + printf("."); + fflush(stdout); + } + } + + err = archive_read_extract(archive, entry, + ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | + ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS); + + if (err != ARCHIVE_OK) + break; + + archive_file++; + current_files++; + } + + if (err != ARCHIVE_EOF) { + snprintf(errormsg, sizeof(errormsg), + "Error while extracting %s: %s\n", items[i], + archive_error_string(archive)); + scripted_printf("Extract Error: %s\n", errormsg); + return (err); + } + + archive_read_free(archive); + } + + printf("\n"); + scripted_printf("Extracting distribution files (100%%)\n"); + + return (0); +} + +static void +scripted_printf(const char *fmt, ...) +{ + static const char fmtstr[] = "%Y-%m-%dT%H:%M:%SZ"; + char timestr[32]; + time_t tmval; + struct tm tm; + va_list ap; + + time(&tmval); + gmtime_r(&tmval, &tm); + strftime(timestr, sizeof(timestr), fmtstr, &tm); + printf("%s: ", timestr); + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); +} --------------010905000303080601070703 Content-Type: text/x-patch; name="partedit.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="partedit.c.patch" Index: usr.sbin/bsdinstall/partedit/partedit.c =================================================================== --- usr.sbin/bsdinstall/partedit/partedit.c (revision 282864) +++ usr.sbin/bsdinstall/partedit/partedit.c (working copy) @@ -42,6 +42,7 @@ struct pmetadata_head part_metadata; static int sade_mode = 0; +static int scriptedpart_mode = 0; static int apply_changes(struct gmesh *mesh); static struct partedit_item *read_geom_mesh(struct gmesh *mesh, int *nitems); @@ -61,7 +62,8 @@ gpart_revert_all(&mesh); geom_deletetree(&mesh); - end_dialog(); + if (!scriptedpart_mode) + end_dialog(); exit(1); } @@ -75,45 +77,55 @@ struct gmesh mesh; int i, op, nitems, nscroll; int error; + int autopart_mode = 0; if (strcmp(basename(argv[0]), "sade") == 0) sade_mode = 1; + if (strcmp(basename(argv[0]), "autopart") == 0) + autopart_mode = 1; + + if (strcmp(basename(argv[0]), "scriptedpart") == 0) + scriptedpart_mode = 1; + TAILQ_INIT(&part_metadata); init_fstab_metadata(); - init_dialog(stdin, stdout); - if (!sade_mode) - dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); - dialog_vars.item_help = TRUE; - nscroll = i = 0; - /* Revert changes on SIGINT */ signal(SIGINT, sigint_handler); - if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */ + if (autopart_mode) /* Guided */ prompt = "Please review the disk setup. When complete, press " "the Finish button."; + else if (scriptedpart_mode) + prompt = NULL; + else + prompt = "Create partitions for FreeBSD. No changes will be " + "made until you select Finish."; + + if (scriptedpart_mode) { + error = scripted_editor(argc, argv); + if (error != 0) + return (error); + } else { + init_dialog(stdin, stdout); + if (!sade_mode) + dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); + dialog_vars.item_help = TRUE; + } + + if (autopart_mode) { /* Experimental ZFS autopartition support */ if (argc > 1 && strcmp(argv[1], "zfs") == 0) { part_wizard("zfs"); } else { part_wizard("ufs"); } - } else if (strcmp(basename(argv[0]), "scriptedpart") == 0) { - error = scripted_editor(argc, argv); - prompt = NULL; - if (error != 0) { - end_dialog(); - return (error); - } - } else { - prompt = "Create partitions for FreeBSD. No changes will be " - "made until you select Finish."; } /* Show the part editor either immediately, or to confirm wizard */ + nscroll = i = 0; while (prompt != NULL) { dlg_clear(); dlg_put_backtitle(); @@ -213,7 +225,8 @@ geom_deletetree(&mesh); free(items); - end_dialog(); + if (!scriptedpart_mode) + end_dialog(); return (error); } @@ -276,9 +289,13 @@ } if (root == NULL) { - dialog_msgbox("Error", "No root partition was found. " - "The root FreeBSD partition must have a mountpoint of '/'.", - 0, 0, TRUE); + if (!scriptedpart_mode) + dialog_msgbox("Error", "No root partition was found. " + "The root FreeBSD partition must have a mountpoint of '/'.", + 0, 0, TRUE); + else + scripted_fprintf(stderr, "Error: No root partition was found. " + "The root FreeBSD partition must have a mountpoint of '/'.\n"); return (FALSE); } @@ -286,7 +303,7 @@ * Check for root partitions that we aren't formatting, which is * usually a mistake */ - if (root->newfs == NULL && !sade_mode) { + if (root->newfs == NULL && !sade_mode && !scriptedpart_mode) { dialog_vars.defaultno = TRUE; cancel = dialog_yesno("Warning", "The chosen root partition " "has a preexisting filesystem. If it contains an existing " @@ -334,9 +351,12 @@ } i = 0; - dialog_mixedgauge("Initializing", - "Initializing file systems. Please wait.", 0, 0, i*100/nitems, - nitems, __DECONST(char **, items)); + if (!scriptedpart_mode) + dialog_mixedgauge("Initializing", + "Initializing file systems. Please wait.", 0, 0, i*100/nitems, + nitems, __DECONST(char **, items)); + else + scripted_fprintf(stdout, "Initializing file systems:\n"); gpart_commit(mesh); items[i*2 + 1] = "3"; i++; @@ -347,9 +367,12 @@ TAILQ_FOREACH(md, &part_metadata, metadata) { if (md->newfs != NULL) { items[i*2 + 1] = "7"; /* In progress */ - dialog_mixedgauge("Initializing", - "Initializing file systems. Please wait.", 0, 0, - i*100/nitems, nitems, __DECONST(char **, items)); + if (!scriptedpart_mode) + dialog_mixedgauge("Initializing", + "Initializing file systems. Please wait.", 0, 0, + i*100/nitems, nitems, __DECONST(char **, items)); + else + scripted_fprintf(stdout, "\t%s...\n", items[i*2]); sprintf(message, "(echo %s; %s) >>%s 2>>%s", md->newfs, md->newfs, getenv("BSDINSTALL_LOG"), getenv("BSDINSTALL_LOG")); @@ -358,9 +381,12 @@ i++; } } - dialog_mixedgauge("Initializing", - "Initializing file systems. Please wait.", 0, 0, - i*100/nitems, nitems, __DECONST(char **, items)); + if (!scriptedpart_mode) + dialog_mixedgauge("Initializing", + "Initializing file systems. Please wait.", 0, 0, + i*100/nitems, nitems, __DECONST(char **, items)); + else + scripted_fprintf(stdout, "Completed initializing file systems!\n"); for (i = 1; i < nitems; i++) free(__DECONST(char *, items[i*2])); @@ -374,7 +400,10 @@ if (fstab == NULL) { sprintf(message, "Cannot open fstab file %s for writing (%s)\n", getenv("PATH_FSTAB"), strerror(errno)); - dialog_msgbox("Error", message, 0, 0, TRUE); + if (!scriptedpart_mode) + dialog_msgbox("Error", message, 0, 0, TRUE); + else + scripted_fprintf(stderr, "Error: %s\n", message); return (-1); } fprintf(fstab, "# Device\tMountpoint\tFStype\tOptions\tDump\tPass#\n"); --------------010905000303080601070703 Content-Type: text/x-patch; name="partedit.h.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="partedit.h.patch" Index: usr.sbin/bsdinstall/partedit/partedit.h =================================================================== --- usr.sbin/bsdinstall/partedit/partedit.h (revision 282864) +++ usr.sbin/bsdinstall/partedit/partedit.h (working copy) @@ -32,6 +32,7 @@ #include #include #include +#include struct gprovider; struct gmesh; @@ -56,6 +57,7 @@ int part_wizard(const char *fstype); int scripted_editor(int argc, const char **argv); +void scripted_fprintf(FILE *fp, const char *fmt, ...); int wizard_makeparts(struct gmesh *mesh, const char *disk, const char *fstype, int interactive); --------------010905000303080601070703 Content-Type: text/x-patch; name="script.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="script.patch" Index: usr.sbin/bsdinstall/scripts/script =================================================================== --- usr.sbin/bsdinstall/scripts/script (revision 282864) +++ usr.sbin/bsdinstall/scripts/script (working copy) @@ -38,6 +38,7 @@ ############################################################ CONFIGURATION # VARIABLES: +export BSDINSTALL_SCRIPTED=1 # PARTITIONS # DISTRIBUTIONS # BSDINSTALL_DISTDIR @@ -47,7 +48,7 @@ # # Strings that should be moved to an i18n file and loaded with f_include_lang() # -msg_installation_error="Installation Error!" +msg_installation_error="Installation Error! See" ############################################################ FUNCTIONS @@ -58,9 +59,7 @@ local file f_getvar "$VAR_DEBUG_FILE#+" file if [ "$file" ]; then - f_dialog_title "$msg_installation_error" - f_dialog_textbox "$file" - # No need to restore title, pining for the fjords + printf "$0: $msg_installation_error $file" fi exit 1 @@ -74,7 +73,7 @@ SCRIPT="$1" shift -f_dprintf "Began Installation at %s" "$( date )" +f_dprintf "$0: Began Installation at %s" "$( date )" rm -rf $BSDINSTALL_TMPETC mkdir $BSDINSTALL_TMPETC @@ -89,7 +88,7 @@ export debugFile="$BSDINSTALL_LOG" f_quietly f_debug_init # NB: Being scripted, let debug go to terminal for invalid debugFile - f_dprintf "Began Instalation at %s" "$( date )" + f_dprintf "$0: Began Installation at %s" "$( date )" fi # Make partitions @@ -127,7 +126,7 @@ bsdinstall entropy bsdinstall umount -f_dprintf "Installation Completed at %s" "$( date )" +f_dprintf "$0: Installation Completed at %s" "$( date )" trap true EXIT --------------010905000303080601070703 Content-Type: text/x-patch; name="scripted.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="scripted.c.patch" Index: usr.sbin/bsdinstall/partedit/scripted.c =================================================================== --- usr.sbin/bsdinstall/partedit/scripted.c (revision 282864) +++ usr.sbin/bsdinstall/partedit/scripted.c (working copy) @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include "partedit.h" @@ -76,7 +78,7 @@ error = geom_gettree(&mesh); if (provider_for_name(&mesh, disk) == NULL) { - fprintf(stderr, "GEOM provider %s not found\n", disk); + scripted_fprintf(stderr, "GEOM provider %s not found\n", disk); geom_deletetree(&mesh); return (-1); } @@ -159,7 +161,7 @@ input++; partconfig = strchr(input, '}'); if (partconfig == NULL) { - fprintf(stderr, "Malformed partition setup " + scripted_fprintf(stderr, "Malformed partition setup " "string: %s\n", input); return (1); } @@ -174,7 +176,7 @@ else if (scheme == NULL) scheme = strsep(&input, " \t\n"); else { - fprintf(stderr, "Unknown directive: %s\n", + scripted_fprintf(stderr, "Unknown directive: %s\n", strsep(&input, " \t\n")); return (1); } @@ -211,3 +213,21 @@ return (0); } +void +scripted_fprintf(FILE *fp, const char *fmt, ...) +{ + static const char fmtstr[] = "%Y-%m-%dT%H:%M:%SZ"; + char timestr[32]; + time_t tmval; + struct tm tm; + va_list ap; + + time(&tmval); + gmtime_r(&tmval, &tm); + strftime(timestr, sizeof(timestr), fmtstr, &tm); + printf("%s: ", timestr); + + va_start(ap, fmt); + vfprintf(fp, fmt, ap); + va_end(ap); +} --------------010905000303080601070703--