2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * Neither the name of the DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Workflow logic for installer.
37 * $Id: flow.c,v 1.67 2005/04/08 08:09:23 cpressey Exp $
49 #include "libdfui/lang.h"
50 #define _(String) gettext (String)
51 extern int _nl_msg_cat_cntr;
53 #define _(String) (String)
56 #include "libaura/mem.h"
57 #include "libaura/dict.h"
58 #include "libaura/fspred.h"
60 #include "libdfui/dfui.h"
62 #include "libdfui/dump.h"
64 #include "libdfui/system.h"
66 #include "libinstaller/commands.h"
67 #include "libinstaller/confed.h"
68 #include "libinstaller/diskutil.h"
69 #include "libinstaller/functions.h"
70 #include "libinstaller/package.h"
71 #include "libinstaller/uiutil.h"
75 #include "pathnames.h"
79 void (*state)(struct i_fn_args *) = NULL;
81 int use_hammer; /* 0=UFS 1=HAMMER 2=HAMMER2 */
88 * The installer works like a big state machine. Each major form is
89 * a state. When the user has filled out the form satisfactorily,
90 * and selects "OK", there is a transition to the next state, in a
91 * mostly-linear order towards the final, "successfully installed"
92 * state. The user may also "Cancel", which generally causes a
93 * transition to the previous state (but may also take them back to
94 * the very first state in some cases.)
97 * - Select localization optional
98 * - Welcome to DragonFly required
99 * - Begin Installation required
100 * - Select Disk required
101 * - Format Disk optional dd, fdisk
102 * - Select Partition required dd, disklabel
103 * - Create Subpartitions required disklabel, newfs
104 * - Install DragonFly required swapon, mkdir, mount, cpdup
105 * - Install Bootstrap optional boot0cfg
106 * - Reboot optional reboot
111 state_lang_menu(struct i_fn_args *a)
114 struct dfui_response *r;
120 f = dfui_form_create(
122 _("Select Language"),
123 _("Please select the language you wish you use."),
128 "a", "default", "English",
129 "English Standard Default", "",
130 "a", "ru", "Russian",
131 "Russian KOI8-R", "",
135 if (!dfui_be_present(a->c, f, &r))
138 id = aura_strdup(dfui_response_get_action_id(r));
140 if (strcmp(id, "default") == 0) {
141 state = state_welcome;
144 state = state_welcome;
149 dfui_response_free(r);
152 /* set keymap, scrnmap, fonts */
153 if (!set_lang_syscons(id))
157 if (!set_lang_envars(id))
160 dfui_be_set_global_setting(a->c, "lang", id, &cancelled);
162 /* XXX if (!cancelled) ... ? */
164 /* let gettext know about changes */
170 * state_welcome_livecd: the start state of the installer state machine,
171 * when run from the Live CD. Briefly describe DragonFly to the user,
172 * and present them with a set of reasonable options of how to proceed.
175 state_welcome(struct i_fn_args *a)
178 struct dfui_response *r;
179 char msg_buf[2][1024];
181 snprintf(msg_buf[0], sizeof(msg_buf[0]),
182 _("Welcome to %s"), OPERATING_SYSTEM_NAME);
184 snprintf(msg_buf[1], sizeof(msg_buf[1]),
185 _("Welcome to the %s Live CD."
187 "%s is an efficient and elegant BSD "
188 "Unix-derived operating system. For more information, see %s"
190 "From this CD, you can boot into %s ``live'' "
191 "(without installing it) to evaluate it, to install it "
192 "manually, or to troubleshoot problems with an "
193 "existing installation, using either a command prompt "
194 "or menu-driven utilities."
196 "Also, you can use this automated application to assist "
197 "you in installing %s on this computer and "
198 "configuring it once it is installed."
200 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_URL,
201 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
203 if ((a->flags & I_BOOTED_LIVECD) == 0) {
204 state = state_welcome_system;
208 f = dfui_form_create(
216 "p", "special", "dfinstaller_welcome",
221 if (a->flags & I_UPGRADE_TOOGLE) {
222 snprintf(msg_buf[0], sizeof(msg_buf[0]),
223 _("Upgrade a FreeBSD 4.X system to %s"),
224 OPERATING_SYSTEM_NAME);
225 dfui_form_action_add(f, "upgrade",
226 dfui_info_new(_("Upgrade"),
229 snprintf(msg_buf[0], sizeof(msg_buf[0]),
230 _("Install %s"), OPERATING_SYSTEM_NAME);
231 snprintf(msg_buf[1], sizeof(msg_buf[1]),
232 _("Install %s on a HDD or HDD partition on this computer"),
233 OPERATING_SYSTEM_NAME);
234 dfui_form_action_add(f, "install",
235 dfui_info_new(msg_buf[0],
239 snprintf(msg_buf[0], sizeof(msg_buf[0]),
240 _("Configure a %s system once it has been installed on HDD"),
241 OPERATING_SYSTEM_NAME);
242 dfui_form_action_add(f, "configure",
243 dfui_info_new(_("Configure an Installed System"),
246 dfui_form_action_add(f, "utilities",
247 dfui_info_new(_("Live CD Utilities"),
248 _("Utilities to work with disks, diagnostics, and the LiveCD Environment"), ""));
250 dfui_form_action_add(f, "exit",
251 dfui_info_new(_("Exit to Live CD"),
252 _("Exit this program to a login prompt with access to the LiveCD"), ""));
254 dfui_form_action_add(f, "reboot",
255 dfui_info_new(_("Reboot this Computer"),
256 _("Reboot this computer (e.g. to boot into a newly installed system)"), ""));
258 dfui_form_action_add(f, "configure_netboot",
259 dfui_info_new(_("Setup NetBoot Install Services"),
260 _("Setup machine as remote installation server"), ""));
262 if (!dfui_be_present(a->c, f, &r))
265 if (strcmp(dfui_response_get_action_id(r), "install") == 0) {
266 state = state_begin_install;
267 } else if (strcmp(dfui_response_get_action_id(r), "upgrade") == 0) {
268 state = state_begin_upgrade;
269 } else if (strcmp(dfui_response_get_action_id(r), "configure") == 0) {
270 storage_set_selected_disk(a->s, NULL);
271 storage_set_selected_slice(a->s, NULL);
272 state = state_configure_menu;
273 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) {
274 state = state_utilities_menu;
275 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) {
277 } else if (strcmp(dfui_response_get_action_id(r), "configure_netboot") == 0) {
278 state = state_setup_remote_installation_server;
279 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) {
280 state = state_reboot;
284 dfui_response_free(r);
288 * state_welcome_system: the start state of the installer state machine,
289 * when run from the installed system. Allow the user to configure the
293 state_welcome_system(struct i_fn_args *a)
296 struct dfui_response *r;
297 char msg_buf[2][1024];
299 snprintf(msg_buf[0], sizeof(msg_buf[0]),
300 _("Configure this %s System"), OPERATING_SYSTEM_NAME);
302 snprintf(msg_buf[1], sizeof(msg_buf[1]),
303 _("Thank you for choosing %s."
305 "For up-to-date news and information on %s, "
306 "make sure to check out"
310 "You can use this automated application to assist "
311 "you in setting up this %s system."
313 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
314 OPERATING_SYSTEM_URL, OPERATING_SYSTEM_NAME);
317 f = dfui_form_create(
325 "p", "special", "dfinstaller_welcome",
330 snprintf(msg_buf[0], sizeof(msg_buf[0]),
331 _("Configure this %s system"), OPERATING_SYSTEM_NAME);
333 dfui_form_action_add(f, "environment",
334 dfui_info_new(_("Configure this System"),
337 dfui_form_action_add(f, "utilities",
338 dfui_info_new(_("Utilities"),
339 _("Utilities to work with and diagnose disks and other subsystems"), ""));
341 dfui_form_action_add(f, "exit",
342 dfui_info_new(_("Exit Installer"),
343 _("Exit this program and return to the system"), ""));
345 if (!dfui_be_present(a->c, f, &r))
348 if (strcmp(dfui_response_get_action_id(r), "environment") == 0) {
349 state = state_environment_menu;
350 } else if (strcmp(dfui_response_get_action_id(r), "utilities") == 0) {
351 state = state_utilities_menu;
352 } else if (strcmp(dfui_response_get_action_id(r), "exit") == 0) {
354 } else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0) {
355 state = state_reboot;
359 dfui_response_free(r);
363 state_configure_menu(struct i_fn_args *a)
365 struct dfui_form *f = NULL;
366 struct dfui_response *r = NULL;
367 struct commands *cmds;
369 char msg_buf[2][1024];
371 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) {
372 if (!survey_storage(a)) {
373 inform(a->c, _("Errors occurred while probing "
374 "the system for its storage capabilities."));
377 a->short_desc = _("Select the disk containing the installation.");
378 a->cancel_desc = _("Return to Welcome Menu");
380 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
381 state = state_welcome;
385 a->short_desc = _("Select the primary partition containing the installation.");
386 a->cancel_desc = _("Return to Welcome Menu");
389 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
390 state = state_welcome;
397 if (during_install == 0) {
398 switch (dfui_be_present_dialog(a->c, _("Select file system"),
399 _("HAMMER2|HAMMER1|UFS|Return to Welcome Menu"),
400 _("Please select the file system installed on the disk.\n\n")))
403 /* HAMMER2 (first menu item is the default) */
415 state = state_welcome;
425 if (!mount_target_system(a)) {
426 inform(a->c, _("Target system could not be mounted."));
427 state = state_welcome;
431 snprintf(msg_buf[0], sizeof(msg_buf[0]),
432 _("The options on this menu allow you to configure a "
433 "%s system after it has already been "
434 "installed."), OPERATING_SYSTEM_NAME);
437 f = dfui_form_create(
439 _("Configure an Installed System"),
445 _("Select timezone"),
446 _("Set the Time Zone of your physical location"), "",
448 _("Set date and time"),
449 _("Set the Time and Date of your machine"), "",
452 _("Set keyboard map"),
453 _("Set what kind of keyboard layout you have"), "",
454 "a", "root_passwd", _("Set root password"),
455 _("Set the password that the root (superuser) account will use"), "",
456 "a", "add_user", _("Add a user"),
457 _("Add a user to the system"), "",
458 "a", "assign_ip", _("Configure network interfaces"),
459 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
460 "a", "assign_hostname_domain",
461 _("Configure hostname and domain"),
462 _("Configure the hostname and domain for this system"), "",
464 "a", "select_services", "Select Services",
465 "Enable/Disable system services (servers, daemons, etc.)", "",
468 _("Set console font"),
469 _("Set how the characters on your video console look"), "",
472 _("Set how characters are translated before console display"), "",
474 "a", "install_pkgs", _("Install extra software packages"),
475 _("Install third-party software packages from the LiveCD"), "",
477 "a", "remove_pkgs", _("Remove software packages"),
478 _("Remove third-party software packages from the installed system"), "",
480 "a", "cancel", _("Return to Welcome Menu"), "", "",
481 "p", "accelerator", "ESC",
486 if (!dfui_be_present(a->c, f, &r))
490 a->cfg_root = "mnt/";
491 if (strcmp(dfui_response_get_action_id(r), "root_passwd") == 0) {
493 } else if (strcmp(dfui_response_get_action_id(r), "add_user") == 0) {
495 } else if (strcmp(dfui_response_get_action_id(r), "install_pkgs") == 0) {
496 fn_install_packages(a);
497 } else if (strcmp(dfui_response_get_action_id(r), "remove_pkgs") == 0) {
498 fn_remove_packages(a);
499 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) {
501 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) {
502 fn_assign_hostname_domain(a);
503 } else if (strcmp(dfui_response_get_action_id(r), "select_services") == 0) {
504 fn_select_services(a);
505 } else if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) {
507 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
509 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
511 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
513 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) {
514 fn_assign_datetime(a);
515 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
516 state = state_welcome;
521 dfui_response_free(r);
525 * Before unmounting the system, write out any changes to rc.conf.
527 config_vars_write(rc_conf, CONFIG_TYPE_SH,
528 "%s%setc/rc.conf", a->os_root, a->cfg_root);
531 * Clear out configuration variable table in memory.
533 config_vars_free(rc_conf);
534 rc_conf = config_vars_new();
537 * Finally, unmount the system we mounted on /mnt and remove mappings.
539 cmds = commands_new();
540 unmount_all_under(a, cmds, "%smnt", a->os_root);
541 commands_execute(a, cmds);
544 if (remove_all_mappings(a) == NULL)
545 inform(a->c, _("Warning: mappings could not be removed."));
549 state_utilities_menu(struct i_fn_args *a)
552 struct dfui_response *r;
554 if (!survey_storage(a)) {
555 inform(a->c, _("Errors occurred while probing "
556 "the system for its storage capabilities."));
559 f = dfui_form_create(
561 _("Live CD Utilities Menu"),
562 _("On these submenus you will find utilities to help "
563 "you set up your Live CD environment, diagnose "
564 "and analyse this system, and work with "
565 "the devices attached to this computer."),
568 "a", "environment", _("LiveCD Environment"),
569 _("Configure the LiveCD Environment"), "",
570 "a", "diagnostics", _("System Diagnostics"),
571 _("Probe and display detailed information about this system"), "",
572 "a", "diskutil", _("Disk Utilities"),
573 _("Format and check hard drives and floppy disks"), "",
574 "a", "livecd", _("Exit to Live CD"),
575 _("Exit this program to a login prompt with access to the LiveCD"), "",
577 _("Reboot this Computer"), "", "",
579 _("Return to Welcome Menu"), "", "",
580 "p", "accelerator", "ESC",
584 if (!dfui_be_present(a->c, f, &r))
587 if (strcmp(dfui_response_get_action_id(r), "environment") == 0)
588 state = state_environment_menu;
589 else if (strcmp(dfui_response_get_action_id(r), "diagnostics") == 0)
590 state = state_diagnostics_menu;
591 else if (strcmp(dfui_response_get_action_id(r), "diskutil") == 0)
592 state = state_diskutil_menu;
593 else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0)
595 else if (strcmp(dfui_response_get_action_id(r), "reboot") == 0)
596 state = state_reboot;
597 else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0)
598 state = state_welcome;
601 dfui_response_free(r);
605 state_environment_menu(struct i_fn_args *a)
608 struct dfui_response *r;
610 char msg_buf[2][1024];
612 snprintf(msg_buf[0], sizeof(msg_buf[0]),
613 _("On this menu you will find utilities to help you "
614 "set up your Live CD environment.\n\nNote "
615 "that these functions affect only the LiveCD "
616 "environment you are currently using, and they will "
617 "not affect any system that may be installed on "
618 "this computer UNLESS you subsequently choose to "
619 "install %s from this environment, in which "
620 "case they will be copied to the newly installed "
621 "system."), OPERATING_SYSTEM_NAME);
624 f = dfui_form_create(
626 _("Live CD Environment Menu"),
632 _("Select timezone"),
633 _("Set the Time Zone of your physical location"), "",
635 _("Set date and time"),
636 _("Set the Time and Date of your machine"), "",
639 _("Set keyboard map"),
640 _("Set what kind of keyboard layout you have"), "",
642 _("Set console font"),
643 _("Set how the characters on your video console look"), "",
646 _("Set how characters are translated before console display"), "",
648 "a", "assign_hostname_domain",
649 _("Configure hostname and domain"),
650 _("Configure the hostname and domain for this system"), "",
652 _("Configure network interfaces"),
653 _("Set up network interfaces (NICs, ethernet, TCP/IP, etc)"), "",
656 _("Return to Utilities Menu"), "", "",
657 "p", "accelerator", "ESC",
662 if (!dfui_be_present(a->c, f, &r))
667 if (strcmp(dfui_response_get_action_id(r), "set_kbdmap") == 0) {
669 } else if (strcmp(dfui_response_get_action_id(r), "set_vidfont") == 0) {
671 } else if (strcmp(dfui_response_get_action_id(r), "set_scrnmap") == 0) {
673 } else if (strcmp(dfui_response_get_action_id(r), "assign_hostname_domain") == 0) {
674 fn_assign_hostname_domain(a);
675 } else if (strcmp(dfui_response_get_action_id(r), "assign_ip") == 0) {
677 } else if (strcmp(dfui_response_get_action_id(r), "set_timezone") == 0) {
679 } else if (strcmp(dfui_response_get_action_id(r), "set_datetime") == 0) {
680 fn_assign_datetime(a);
681 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
682 state = state_utilities_menu;
687 dfui_response_free(r);
692 state_diagnostics_menu(struct i_fn_args *a)
695 struct dfui_action *k;
696 struct dfui_response *r;
700 f = dfui_form_create(
702 _("Live CD Diagnostics Menu"),
703 _("These functions can help you diagnose this system."),
708 _("Display system startup messages"),
709 _("Display system startup messages (dmesg)"), "",
711 _("Display PCI devices"),
712 _("Display PCI devices (pciconf)"), "",
714 _("Display ATA devices"),
715 _("Display ATA devices (natacontrol)"), "",
719 k = dfui_form_action_add(f, "cancel",
720 dfui_info_new(_("Return to Utilities Menu"), "", ""));
721 dfui_action_property_set(k, "accelerator", "ESC");
723 if (!dfui_be_present(a->c, f, &r))
727 if (strcmp(dfui_response_get_action_id(r), "show_dmesg") == 0) {
729 } else if (strcmp(dfui_response_get_action_id(r), "pciconf") == 0) {
731 } else if (strcmp(dfui_response_get_action_id(r), "natacontrol") == 0) {
732 fn_show_natacontrol(a);
733 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
734 state = state_utilities_menu;
739 dfui_response_free(r);
744 state_diskutil_menu(struct i_fn_args *a)
747 struct dfui_action *k;
748 struct dfui_response *r;
752 f = dfui_form_create(
754 _("Disk Utilities Menu"),
755 _("These functions let you manipulate the storage devices "
756 "attached to this computer."),
762 _("Format a hard disk drive"), "", "",
763 "a", "wipe_start_of_disk",
764 _("Wipe out the start of a disk"), "", "",
765 "a", "wipe_start_of_slice",
766 _("Wipe out the start of a primary partition"), "", "",
767 "a", "install_bootblocks",
768 _("Install bootblocks on disks"), "", "",
769 "a", "format_msdos_floppy",
770 _("Format an MSDOS floppy"), "", "",
774 if (is_file("%sboot/cdboot.flp.bz2", a->os_root)) {
775 dfui_form_action_add(f, "create_cdboot_floppy",
776 dfui_info_new(_("Create a CDBoot floppy"),
781 k = dfui_form_action_add(f, "cancel",
782 dfui_info_new(_("Return to Utilities Menu"), "", ""));
783 dfui_action_property_set(k, "accelerator", "ESC");
785 if (!dfui_be_present(a->c, f, &r))
789 if (strcmp(dfui_response_get_action_id(r), "format_hdd") == 0) {
790 storage_set_selected_disk(a->s, NULL);
791 storage_set_selected_slice(a->s, NULL);
793 fn_format_disk_uefi(a);
795 fn_format_disk_mbr(a);
796 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_disk") == 0) {
797 fn_wipe_start_of_disk(a);
798 } else if (strcmp(dfui_response_get_action_id(r), "wipe_start_of_slice") == 0) {
799 fn_wipe_start_of_slice(a);
800 } else if (strcmp(dfui_response_get_action_id(r), "install_bootblocks") == 0) {
801 a->short_desc = _("Select the disks on which "
802 "you wish to install bootblocks.");
803 a->cancel_desc = _("Return to Utilities Menu");
804 fn_install_bootblocks(a, NULL);
805 } else if (strcmp(dfui_response_get_action_id(r), "format_msdos_floppy") == 0) {
806 fn_format_msdos_floppy(a);
807 } else if (strcmp(dfui_response_get_action_id(r), "create_cdboot_floppy") == 0) {
808 fn_create_cdboot_floppy(a);
809 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
810 state = state_utilities_menu;
815 dfui_response_free(r);
819 /** INSTALLER STATES **/
822 * state_begin_upgrade: Ask the user where the freebsd
823 * 4.X install is and make sure its safe to proceed.
827 state_begin_upgrade(struct i_fn_args *a)
829 //struct dfui_form *f = NULL;
830 //struct dfui_response *r = NULL;
833 if (storage_get_selected_disk(a->s) == NULL || storage_get_selected_slice(a->s) == NULL) {
834 if (!survey_storage(a)) {
835 inform(a->c, _("Errors occurred while probing "
836 "the system for its storage capabilities."));
839 a->short_desc = _("Select the disk containing the installation that you would like to upgrade.");
840 a->cancel_desc = _("Return to Welcome Menu");
842 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
843 state = state_welcome;
847 a->short_desc = _("Select the primary partition containing the installation you would like to upgrade.");
848 a->cancel_desc = _("Return to Welcome Menu");
851 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
852 state = state_welcome;
858 if (!mount_target_system(a)) {
859 inform(a->c, _("Target system could not be mounted."));
860 state = state_welcome;
866 * state_begin_install: Briefly describe the install process
867 * to the user, and let them proceed (or not.)
870 state_begin_install(struct i_fn_args *a)
873 struct dfui_response *r;
874 char msg_buf[3][1024];
876 snprintf(msg_buf[0], sizeof(msg_buf[0]),
877 _("This application will install %s"
878 " on one of the hard disk drives attached to this computer. "
879 "It has been designed to make it easy to install "
880 "%s in the typical case. "
881 "If you have special requirements that are not addressed "
882 "by this installer, or if you have problems using it, you "
883 "are welcome to install %s manually. "
884 "To do so select Exit to Live CD, login as root, and follow "
885 "the instructions given in the file /README ."
887 "NOTE! As with any installation process, YOU ARE "
888 "STRONGLY ENCOURAGED TO BACK UP ANY IMPORTANT DATA ON THIS "
889 "COMPUTER BEFORE PROCEEDING!"
891 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME,
892 OPERATING_SYSTEM_NAME);
894 snprintf(msg_buf[1], sizeof(msg_buf[1]),
895 _("Some situations in which you might not wish to use this "
897 "- you want to install %s onto a "
898 "logical/extended partition;\n"
899 "- you want to install %s "
900 "onto a ``dangerously dedicated'' disk; or\n"
901 "- you want full and utter control over the install process."
903 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
905 snprintf(msg_buf[2], sizeof(msg_buf[2]),
906 _("Install %s"), OPERATING_SYSTEM_NAME);
908 f = dfui_form_create(
910 _("Begin Installation"),
914 "p", "special", "dfinstaller_begin_install",
915 "p", "minimum_width", "76",
917 "a", "proceed", msg_buf[2],
919 "a", "cancel", _("Return to Welcome Menu"),
921 "p", "accelerator", "ESC",
922 "a", "livecd", _("Exit to Live CD"),
927 if (!dfui_be_present(a->c, f, &r))
930 if (strcmp(dfui_response_get_action_id(r), "proceed") == 0) {
931 if (!survey_storage(a)) {
932 inform(a->c, _("Errors occurred while probing "
933 "the system for its storage capabilities."));
935 state = state_ask_uefi;
936 } else if (strcmp(dfui_response_get_action_id(r), "livecd") == 0) {
938 } else if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
939 state = state_welcome;
943 dfui_response_free(r);
947 * state_ask_uefi: ask the user if they want a UEFI installation
950 state_ask_uefi(struct i_fn_args *a)
954 switch (dfui_be_present_dialog(a->c, _("UEFI or legacy BIOS?"),
955 _("UEFI|Legacy BIOS|Return to Begin Installation"),
956 _("Do you wish to set up %s for a UEFI or legacy BIOS system?"),
957 OPERATING_SYSTEM_NAME))
967 state = state_begin_install;
975 state = state_select_disk;
979 * state_select_disk: ask the user on which physical disk they wish
980 * to install DragonFly.
983 state_select_disk(struct i_fn_args *a)
987 char msg_buf[1][1024];
989 for (d = storage_disk_first(a->s); d != NULL; d = disk_next(d))
992 if (num_disks == 0) {
993 inform(a->c, _("The installer could not find any disks suitable "
994 "for installation (IDE or SCSI) attached to this "
995 "computer. If you wish to install %s"
996 " on an unorthodox storage device, you will have to "
997 "exit to a LiveCD command prompt and install it "
998 "manually, using the file /README as a guide."),
999 OPERATING_SYSTEM_NAME);
1000 state = state_welcome;
1004 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1005 _("Select a disk on which to install %s"),
1006 OPERATING_SYSTEM_NAME);
1007 a->short_desc = msg_buf[0];
1008 a->cancel_desc = _("Return to Begin Installation");
1010 if (!a->result || storage_get_selected_disk(a->s) == NULL) {
1011 state = state_begin_install;
1014 if (disk_get_capacity(storage_get_selected_disk(a->s)) < DISK_MIN) {
1015 inform(a->c, _("WARNING: you should have a disk "
1016 "at least %dM in size, or "
1017 "you may encounter problems trying to "
1018 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME);
1021 state = state_format_disk;
1026 state_ask_fs(struct i_fn_args *a)
1030 switch (dfui_be_present_dialog(a->c, _("Select file system"),
1031 _("Use HAMMER2|Use HAMMER1|Use UFS|Return to Select Disk"),
1032 _("Please select the file system you want to use with %s.\n\n"
1033 "HAMMER2 is the recommended %s file system. "
1034 "HAMMER1 is the previous %s file system. "
1035 "UFS is the traditional BSD file system."),
1036 OPERATING_SYSTEM_NAME,
1037 OPERATING_SYSTEM_NAME,
1038 OPERATING_SYSTEM_NAME))
1041 /* HAMMER2 (first menu item is the default) */
1052 state = state_select_disk;
1060 state = state_create_subpartitions;
1064 * state_format_disk: ask the user if they wish to format the disk they
1068 state_format_disk(struct i_fn_args *a)
1072 fn_format_disk_uefi(a);
1074 state = state_ask_fs;
1076 state = state_select_disk;
1080 /* XXX Using part of the disk is only supported for MBR installs */
1081 switch (dfui_be_present_dialog(a->c, _("How Much Disk?"),
1082 _("Use Entire Disk|Use Part of Disk|Return to Select Disk"),
1083 _("Select how much of this disk you want to use for %s.\n\n%s"),
1084 OPERATING_SYSTEM_NAME,
1085 disk_get_desc(storage_get_selected_disk(a->s)))) {
1088 if (measure_activated_swap_from_disk(a, storage_get_selected_disk(a->s)) > 0) {
1089 if (swapoff_all(a) == NULL) {
1090 inform(a->c, _("Warning: swap could not be turned off."));
1091 state = state_select_disk;
1096 fn_format_disk_mbr(a);
1098 state = state_ask_fs;
1100 state = state_format_disk;
1104 state = state_select_slice;
1108 state = state_select_disk;
1117 * state_select_slice: ask the user which slice they wish to install
1118 * DragonFly on. In order to avoid confusing them, refer to it as
1119 * a primary partition, but tell them what BSD has traditionally called
1123 state_select_slice(struct i_fn_args *a)
1125 char msg_buf[1][1024];
1127 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1128 _("Select the existing primary partition (also "
1129 "known as a `slice' in the BSD tradition) on "
1130 "which to install %s.\n\n"
1131 "Note that if you do not have any existing "
1132 "primary partitions on this disk, you must "
1133 "first create some. This installer does not "
1134 "currently have the ability to do this, so "
1135 "you will have to exit and run fdisk (in "
1136 "DOS or *BSD) or parted (in Linux) to do so."),
1137 OPERATING_SYSTEM_NAME);
1139 a->short_desc = msg_buf[0];
1140 a->cancel_desc = _("Return to Select Disk");
1142 if (!a->result || storage_get_selected_slice(a->s) == NULL) {
1143 state = state_select_disk;
1145 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1146 storage_get_selected_slice(a->s)) > 0) {
1147 if (swapoff_all(a) == NULL) {
1148 inform(a->c, _("Warning: swap could not be turned off."));
1149 state = state_select_slice;
1154 if (slice_get_capacity(storage_get_selected_slice(a->s)) < DISK_MIN) {
1155 inform(a->c, _("WARNING: you should have a primary "
1156 "partition at least %dM in size, or "
1157 "you may encounter problems trying to "
1158 "install %s."), DISK_MIN, OPERATING_SYSTEM_NAME);
1161 if (confirm_dangerous_action(a->c,
1162 _("WARNING! ALL data in primary partition #%d,\n\n%s\n\non the "
1163 "disk\n\n%s\n\n will be IRREVOCABLY ERASED!\n\nAre you "
1164 "ABSOLUTELY SURE you wish to take this action? This is "
1165 "your LAST CHANCE to cancel!"),
1166 slice_get_number(storage_get_selected_slice(a->s)),
1167 slice_get_desc(storage_get_selected_slice(a->s)),
1168 disk_get_desc(storage_get_selected_disk(a->s)))) {
1169 if (!format_slice(a)) {
1170 inform(a->c, _("Primary partition #%d was "
1171 "not correctly formatted, and may "
1172 "now be in an inconsistent state. "
1173 "We recommend re-formatting it "
1174 "before proceeding."),
1175 slice_get_number(storage_get_selected_slice(a->s)));
1177 inform(a->c, _("Primary partition #%d was formatted."),
1178 slice_get_number(storage_get_selected_slice(a->s)));
1179 state = state_ask_fs;
1182 inform(a->c, _("Action cancelled - no primary partitions were formatted."));
1183 state = state_select_slice;
1189 * state_create_subpartitions: let the user specify what subpartitions they
1190 * want on the disk, how large each should be, and where it should be mounted.
1193 state_create_subpartitions(struct i_fn_args *a)
1195 struct commands *cmds;
1197 if (measure_activated_swap_from_slice(a, storage_get_selected_disk(a->s),
1198 storage_get_selected_slice(a->s)) > 0) {
1199 if (swapoff_all(a) == NULL) {
1200 inform(a->c, _("Warning: swap could not be turned off."));
1201 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1202 state_select_disk : state_select_slice;
1207 cmds = commands_new();
1210 * Auto-disklabel the slice.
1211 * NB: one cannot use "/dev/adXsY" here -
1212 * it must be in the form "adXsY".
1214 command_add(cmds, "%s%s -W %s",
1215 a->os_root, cmd_name(a, "DISKLABEL64"),
1216 slice_get_device_name(storage_get_selected_slice(a->s)));
1217 command_add(cmds, "%s%s if=/dev/zero of=/dev/%s bs=32k count=16",
1218 a->os_root, cmd_name(a, "DD"),
1219 slice_get_device_name(storage_get_selected_slice(a->s)));
1220 command_add(cmds, "%s%s -B -r -w %s",
1221 a->os_root, cmd_name(a, "DISKLABEL64"),
1222 slice_get_device_name(storage_get_selected_slice(a->s)));
1223 commands_execute(a, cmds);
1224 commands_free(cmds);
1227 * Create subpartitions and filesystems
1229 switch(use_hammer) {
1231 fn_create_subpartitions_hammer(FS_HAMMER, a);
1234 fn_create_subpartitions_hammer(FS_HAMMER2, a);
1237 fn_create_subpartitions_ufs(a);
1242 state = state_install_os;
1244 state = disk_get_formatted(storage_get_selected_disk(a->s)) ?
1245 state_select_disk : state_select_slice;
1250 * state_install_os: actually put DragonFly on the disk.
1253 state_install_os(struct i_fn_args *a)
1255 struct dfui_form *f;
1256 struct dfui_response *r;
1257 char msg_buf[1][1024];
1259 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1260 _("Everything is now ready to install the actual files which "
1261 "comprise the %s operating system "
1262 "on the selected partition of the selected disk.\n\n"
1263 "Note that this process will take quite a while to finish. "
1264 "You may wish to take a break now and come back to the "
1265 "computer in a short while."),
1266 OPERATING_SYSTEM_NAME);
1268 f = dfui_form_create(
1275 "p", "role", "confirm",
1276 "p", "special", "dfinstaller_install_os",
1278 "a", "ok", _("Begin Installing Files"), "", "",
1279 "a", "cancel", _("Return to Create Subpartitions"), "", "",
1280 "p", "accelerator", "ESC",
1285 if (!dfui_be_present(a->c, f, &r))
1288 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1289 state = state_create_subpartitions;
1294 state = state_finish_install;
1296 state = state_install_bootstrap;
1301 dfui_response_free(r);
1305 * state_install_bootstrap: put boot0 bootblocks on selected disks.
1308 state_install_bootstrap(struct i_fn_args *a)
1310 char msg_buf[1][1024];
1312 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1313 _("You may now wish to install bootblocks on one or more disks. "
1314 "If you already have a boot manager installed, you can skip "
1315 "this step (but you may have to configure your boot manager "
1316 "separately.) If you installed %s on a disk other "
1317 "than your first disk, you will need to put the bootblock "
1318 "on at least your first disk and the %s disk."),
1319 OPERATING_SYSTEM_NAME, OPERATING_SYSTEM_NAME);
1321 a->short_desc = msg_buf[0];
1322 a->cancel_desc = _("Skip this Step");
1323 fn_install_bootblocks(a,
1324 disk_get_device_name(storage_get_selected_disk(a->s)));
1325 state = state_finish_install;
1329 * Finish up the install.
1332 state_finish_install(struct i_fn_args *a)
1334 char msg_buf[1][1024];
1337 snprintf(msg_buf[0], sizeof(msg_buf[0]),
1339 OPERATING_SYSTEM_NAME);
1341 switch (dfui_be_present_dialog(a->c, msg_buf[0],
1342 _("Configure this System|Reboot|Return to Welcome Menu"),
1343 _("Congratulations!\n\n"
1344 "%s has successfully been installed on "
1345 "this computer. You may now proceed to configure "
1346 "the installation. Alternately, you may wish to "
1347 "reboot the computer and boot into the installed "
1348 "system to confirm that it works."),
1349 OPERATING_SYSTEM_NAME)) {
1351 state = state_configure_menu;
1354 state = state_reboot;
1357 state = state_welcome;
1365 * state_reboot: reboot the machine.
1368 state_reboot(struct i_fn_args *a)
1370 struct dfui_form *f;
1371 struct dfui_response *r;
1373 f = dfui_form_create(
1376 _("This machine is about to be shut down. "
1377 "After the machine has reached its shutdown state, "
1378 "you may remove the CD from the CD-ROM drive tray "
1379 "and press Enter to reboot from the HDD."),
1383 "p", "role", "confirm",
1385 "a", "ok", _("Reboot"), "", "",
1386 "a", "cancel", _("Return to Welcome Menu"), "", "",
1387 "p", "accelerator", "ESC",
1391 if (!dfui_be_present(a->c, f, &r))
1394 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1395 state = state_welcome;
1402 dfui_response_free(r);
1407 * state_setup_remote_installation_server:
1408 * Setup a remote boot installation environment where a machine
1409 * can boot via DHCP/TFTP/NFS and have a running environment
1410 * where the installer can setup the machine.
1414 state_setup_remote_installation_server(struct i_fn_args *a)
1417 struct commands *cmds;
1418 struct dfui_form *f;
1419 struct dfui_action *k;
1420 struct dfui_response *r;
1422 char interface[256];
1425 switch (dfui_be_present_dialog(a->c, _("Enable Netboot Installation Services?"),
1426 _("Enable NetBoot Installation Services|No thanks"),
1427 _("NetBoot Installation Services allows this machine to become "
1428 "a Installation Server that will allow the clients to boot over the network "
1429 "via PXE and start the Installation Environment."
1430 "\n\n*NOTE!* This will assign the IP Address of 10.1.0.1/24 to the selected interface."
1431 "\n\nWould you like to provision this machine to serve up the LiveCD/Installer?"))) {
1434 * Get interface list.
1436 p = popen("/sbin/ifconfig -l", "r");
1437 /* XXX it's possible (though extremely unlikely) this will fail. */
1438 while (fgets(line, 255, p) != NULL)
1439 line[strlen(line) - 1] = '\0';
1442 f = dfui_form_create(
1444 _("Setup NetBoot Installation Environment"),
1445 _("Please select which interface you would like to configure:"),
1447 "p", "role", "menu",
1451 /* Loop through array. */
1452 word = strtok(line, " \t");
1453 while (word != NULL) {
1454 dfui_form_action_add(f, word,
1455 dfui_info_new(word, "", ""));
1456 word = strtok(NULL, " ");
1459 k = dfui_form_action_add(f, "cancel",
1460 dfui_info_new("Cancel", "", ""));
1461 dfui_action_property_set(k, "accelerator", "ESC");
1463 if (!dfui_be_present(a->c, f, &r))
1466 strlcpy(interface, dfui_response_get_action_id(r), 256);
1468 if (strcmp(dfui_response_get_action_id(r), "cancel") == 0) {
1470 dfui_response_free(r);
1476 * Issues the necessary commands to setup the remote boot environment
1479 cmds = commands_new();
1480 command_add(cmds, "%s%s %s 10.1.0.1 netmask 255.255.255.0",
1481 a->os_root, cmd_name(a, "IFCONFIG"), interface);
1482 command_add(cmds, "%s%s -p %stftpdroot",
1483 a->os_root, cmd_name(a, "MKDIR"), a->tmp);
1484 command_add(cmds, "%s%s %sboot/pxeboot %stftpdroot",
1485 a->os_root, cmd_name(a, "CP"), a->os_root, a->tmp);
1486 command_add(cmds, "%s%s %s -ro -alldirs -maproot=root: -network 10.1.0.0 -mask 255.255.255.0 >> %setc/exports",
1487 a->os_root, cmd_name(a, "ECHO"), a->os_root, a->os_root);
1488 command_add(cmds, "%s%s tftp dgram udp wait root %s%s tftpd -l -s %stftpdroot >> %setc/inetd.conf",
1489 a->os_root, cmd_name(a, "ECHO"),
1490 a->os_root, cmd_name(a, "TFTPD"),
1491 a->tmp, a->os_root);
1492 command_add(cmds, "%s%s",
1493 a->os_root, cmd_name(a, "INETD"));
1494 command_add(cmds, "%s%s %svar/db/dhcpd.leases",
1495 a->os_root, cmd_name(a, "TOUCH"), a->os_root);
1496 command_add(cmds, "%s%s -cf /etc/dhcpd.conf >/dev/null 2>&1",
1497 a->os_root, cmd_name(a, "DHCPD"));
1498 command_add(cmds, "%s%s >/dev/null 2>&1",
1499 a->os_root, cmd_name(a, "RPCBIND"));
1500 command_add(cmds, "%s%s -ln >/dev/null 2>&1",
1501 a->os_root, cmd_name(a, "MOUNTD"));
1502 command_add(cmds, "%s%s -u -t -n 6 >/dev/null 2>&1",
1503 a->os_root, cmd_name(a, "NFSD"));
1505 if (commands_execute(a, cmds)) {
1506 inform(a->c, _("NetBoot installation services are now started."));
1508 inform(a->c, _("A failure occurred while provisioning the NetBoot environment. Please check the logs."));
1511 commands_free(cmds);
1513 dfui_response_free(r);
1522 state = state_welcome;
1529 flow(int transport, char *rendezvous, char *os_root,
1532 struct i_fn_args *a;
1534 rc_conf = config_vars_new();
1536 if ((a = i_fn_args_new(os_root, DEFAULT_INSTALLER_TEMP,
1537 DEFAULT_CMDNAMES_FILE, transport,
1538 rendezvous)) == NULL) {
1543 * XXX We can't handle this yet.
1545 a->flags |= I_BOOTED_LIVECD;
1546 a->flags |= I_UPGRADE_TOOGLE;
1548 a->flags |= I_BOOTED_LIVECD;
1551 * Execute the state machine here. The global function pointer
1552 * variable `state' points to the next state_* function to execute.
1553 * Before it exits, this function should set `state' to the next
1554 * state to make a transition to, or NULL to indicate that the
1555 * state machine is finished.
1558 state = state_lang_menu;
1560 state = state_welcome;
1562 for (; state != NULL; )
1565 config_vars_free(rc_conf);