Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 May 2015 13:01:00 -0400
From:      "Ellis H. Wilson III" <ellisw@panasas.com>
To:        Allan Jude <allanjude@freebsd.org>, <freebsd-sysinstall@freebsd.org>, <kczekirda@FreeBSD.org>
Subject:   Re: RFC: Patches to achieve bsdinstall script without dialogs
Message-ID:  <5556264C.7080708@panasas.com>
In-Reply-To: <55117618.8020308@freebsd.org>
References:  <54EF7B40.2030706@panasas.com> <551172FC.1010508@panasas.com> <55117618.8020308@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
--------------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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 
 /* 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 <sys/queue.h>
 #include <inttypes.h>
 #include <fstab.h>
+#include <stdio.h>
 
 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 <libgeom.h>
 #include <dialog.h>
 #include <dlg_keys.h>
+#include <stdarg.h>
+#include <time.h>
 
 #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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5556264C.7080708>