1#!/bin/bash
2#\
3exec expect "$0" -- ${1+"$@"}
4
5# This file contains utilities for working with Serial over Lan (SOL).
6
7# Example use case:
8# sol_utils.tcl --os_host=ip --os_password=password --os_username=username
9# --openbmc_host=ip --openbmc_password=password --openbmc_username=username
10# --proc_name=boot_to_petitboot
11
12source [exec bash -c "which source.tcl"]
13my_source \
14[list print.tcl opt.tcl valid.tcl call_stack.tcl tools.exp cmd.tcl host.tcl]
15
16longoptions openbmc_host: openbmc_username:=root openbmc_password:=0penBmc\
17  os_host: os_username:=root os_password: proc_name: ftp_username: \
18  ftp_password: os_repo_url: autoboot_setting: test_mode:=0 quiet:=0 debug:=0
19pos_parms
20
21set valid_proc_name [list os_login boot_to_petitboot go_to_petitboot_shell \
22  install_os time_settings software_selection root_password set_autoboot]
23
24# Create help dictionary for call to gen_print_help.
25set help_dict [dict create\
26  ${program_name} [list "${program_name} is an SOL utilities program that\
27    will run the user's choice of utilities.  See the \"proc_name\" parm below\
28    for details."]\
29  openbmc_host [list "The OpenBMC host name or IP address." "host"]\
30  openbmc_username [list "The OpenBMC username." "username"]\
31  openbmc_password [list "The OpenBMC password." "password"]\
32  os_host [list "The OS host name or IP address." "host"]\
33  os_username [list "The OS username." "username"]\
34  os_password [list "The OS password." "password"]\
35  proc_name [list "The proc_name you'd like to run.  Valid values are as\
36    follows: [regsub -all {\s+} $valid_proc_name {, }]."]\
37  autoboot_setting [list "The desired state of autoboot." "true/flase"]\
38]
39
40
41# Setup state dictionary.
42set state [dict create\
43  ssh_logged_in 0\
44  os_login_prompt 0\
45  os_logged_in 0\
46  petitboot_screen 0\
47  petitboot_shell_prompt 0\
48]
49
50
51proc help {} {
52
53  gen_print_help
54
55}
56
57
58proc exit_proc { {ret_code 0} } {
59
60  # Execute whenever the program ends normally or with the signals that we
61  # catch (i.e. TERM, INT).
62
63  dprintn ; dprint_executing
64  dprint_var ret_code
65
66  set cmd_buf os_logoff
67  qprintn ; qprint_issuing
68  eval ${cmd_buf}
69
70  set cmd_buf sol_logoff
71  qprintn ; qprint_issuing
72  eval ${cmd_buf}
73
74  qprint_pgm_footer
75
76  exit $ret_code
77
78}
79
80
81proc validate_parms {} {
82
83  trap { exit_proc } [list SIGTERM SIGINT]
84
85  valid_value openbmc_host
86  valid_value openbmc_username
87  valid_value openbmc_password
88  valid_value os_host
89  valid_value os_username
90  valid_password os_password
91  global valid_proc_name
92  global proc_name proc_names
93  set proc_names [split $proc_name " "]
94
95  if { [lsearch -exact $proc_names "install_os"] != -1 } {
96    valid_value ftp_username
97    valid_password ftp_password
98    valid_value os_repo_url
99  }
100
101  if { [lsearch -exact $proc_names "set_autoboot"] != -1 } {
102    valid_value autoboot_setting {} [list "true" "false"]
103  }
104
105}
106
107
108proc sol_login {} {
109
110  # Login to the SOL console.
111
112  dprintn ; dprint_executing
113
114  global spawn_id
115  global expect_out
116  global state
117  global openbmc_host openbmc_username openbmc_password
118  global cr_lf_regex
119  global ssh_password_prompt
120
121  set cmd_buf "spawn -nottycopy ssh -p 2200 $openbmc_username@$openbmc_host"
122  qprint_issuing
123  eval $cmd_buf
124
125  append bad_host_regex "ssh: Could not resolve hostname ${openbmc_host}:"
126  append bad_host_regex " Name or service not known"
127  set expect_result [expect_wrap\
128    [list $bad_host_regex $ssh_password_prompt]\
129    "an SOL password prompt" 5]
130
131  if { $expect_result == 0 } {
132    puts stderr ""
133    print_error "Invalid openbmc_host value.\n"
134    exit_proc 1
135  }
136
137  send_wrap "${openbmc_password}"
138
139  append bad_user_pw_regex "Permission denied, please try again\."
140  append bad_user_pw_regex "${cr_lf_regex}${ssh_password_prompt}"
141  set expect_result [expect_wrap\
142    [list $bad_user_pw_regex "sh: xauth: command not found"]\
143    "an SOL prompt" 10]
144
145  switch $expect_result {
146    0 {
147      puts stderr "" ; print_error "Invalid OpenBmc username or password.\n"
148      exit_proc 1
149    }
150    1 {
151      # Currently, this string always appears but that is not necessarily
152      # guaranteed.
153      dict set state ssh_logged_in 1
154    }
155  }
156
157  if { [dict get $state ssh_logged_in] } {
158    qprintn ; qprint_timen "Logged into SOL."
159    dprintn ; dprint_dict state
160    return
161  }
162
163  # If we didn't get a hit on the "sh: xauth: command not found", then we just
164  # need to see a linefeed.
165  set expect_result [expect_wrap [list ${cr_lf_regex}] "an SOL prompt" 5]
166
167  dict set state ssh_logged_in 1
168  qprintn ; qprint_timen "Logged into SOL."
169  dprintn ; dprint_dict state
170
171}
172
173
174proc sol_logoff {} {
175
176  # Logoff from the SOL console.
177
178  dprintn ; dprint_executing
179
180  global spawn_id
181  global expect_out
182  global state
183  global openbmc_host
184
185  if { ! [dict get $state ssh_logged_in] } {
186    qprintn ; qprint_timen "No SOL logoff required."
187    return
188  }
189
190  send_wrap "~."
191
192  set expect_result [expect_wrap\
193    [list "Connection to $openbmc_host closed"]\
194    "a connection closed message" 5]
195
196  dict set state ssh_logged_in 0
197  qprintn ; qprint_timen "Logged off SOL."
198  dprintn ; dprint_dict state
199
200}
201
202
203proc get_post_ssh_login_state {} {
204
205  # Get the initial state following sol_login.
206
207  # The following state global dictionary variable is set by this procedure.
208
209  dprintn ; dprint_executing
210
211  global spawn_id
212  global expect_out
213  global state
214  global os_login_prompt_regex
215  global os_prompt_regex
216  global petitboot_screen_regex
217  global petitboot_shell_prompt_regex
218  global installer_screen_regex
219
220  if { ! [dict get $state ssh_logged_in] } {
221    puts stderr ""
222    append message "Programmer error - [get_stack_proc_name] must only be"
223    append message " called after sol_login has been called."
224    print_error_report $message
225    exit_proc 1
226  }
227
228  # The first thing one must do after signing into ssh -p 2200 is hit enter to
229  # see where things stand.
230  send_wrap ""
231  set expect_result [expect_wrap\
232  [list $os_login_prompt_regex $os_prompt_regex $petitboot_screen_regex \
233  $petitboot_shell_prompt_regex $installer_screen_regex] \
234  "any indication of status" 5 0]
235
236  switch $expect_result {
237    0 {
238      dict set state os_login_prompt 1
239    }
240    1 {
241      dict set state os_logged_in 1
242    }
243    2 {
244      dict set state petitboot_screen 1
245    }
246    3 {
247      dict set state petitboot_shell_prompt 1
248    }
249  }
250
251  dprintn ; dprint_dict state
252
253}
254
255
256proc os_login {} {
257
258  # Login to the OS.
259
260  dprintn ; dprint_executing
261
262  global spawn_id
263  global expect_out
264  global state
265  global openbmc_host os_username os_password
266  global os_password_prompt
267  global os_prompt_regex
268
269  if { [dict get $state os_logged_in] } {
270    printn ; print_timen "We are already logged in to the OS."
271    return
272  }
273
274  send_wrap "${os_username}"
275
276  append bad_host_regex "ssh: Could not resolve hostname ${openbmc_host}:"
277  append bad_host_regex " Name or service not known"
278  set expect_result [expect_wrap\
279    [list $os_password_prompt]\
280    "an OS password prompt" 5]
281
282  send_wrap "${os_password}"
283  set expect_result [expect_wrap\
284    [list "Login incorrect" "$os_prompt_regex"]\
285    "an OS prompt" 10]
286  switch $expect_result {
287    0 {
288      puts stderr "" ; print_error "Invalid OS username or password.\n"
289      exit_proc 1
290    }
291  }
292
293  dict set state os_logged_in 1
294  dict set state os_login_prompt 0
295  qprintn ; qprint_timen "Logged into OS."
296  dprintn ; dprint_dict state
297
298}
299
300
301proc os_logoff {} {
302
303  # Logoff from the SOL console.
304
305  dprintn ; dprint_executing
306
307  global spawn_id
308  global expect_out
309  global state
310  global os_login_prompt_regex
311
312  if { ! [dict get $state os_logged_in] } {
313    qprintn ; qprint_timen "No OS logoff required."
314    return
315  }
316
317  send_wrap "exit"
318  set expect_result [expect_wrap\
319    [list $os_login_prompt_regex]\
320    "an OS prompt" 5]
321
322  dict set state os_logged_in 0
323  qprintn ; qprint_timen "Logged off OS."
324  dprintn ; dprint_dict state
325
326}
327
328
329proc shell_command {command_string {prompt_regex} { quiet {} } \
330  { test_mode {} } { show_err {} } { ignore_err {} } {trim_cr_lf 1}} {
331
332  # Execute the command_string on the shell command line and return a list
333  # consisting of 1) the return code of the command 2) the stdout/
334  # stderr.
335
336  # It is the caller's responsibility to make sure we are logged into the OS.
337
338  # Description of argument(s):
339  # command_string  The command string which is to be run on the shell (e.g.
340  #                 "hostname" or "grep this that").
341  # prompt_regex    The regular expression of the shell the command string is
342  #                 to run on. (e.g "os_prompt_regex").
343  # quiet           Indicates whether this procedure should run the
344  #                 print_issuing() procedure which prints "Issuing:
345  #                 <cmd string>" to stdout. The default value is 0.
346  # test_mode       If test_mode is set, this procedure will not actually run
347  #                 the command.  If print_output is set, it will print
348  #                 "(test_mode) Issuing: <cmd string>" to stdout.  The default
349  #                 value is 0.
350  # show_err        If show_err is set, this procedure will print a
351  #                 standardized error report if the shell command returns non-
352  #                 zero.  The default value is 1.
353  # ignore_err      If ignore_err is set, this procedure will not fail if the
354  #                 shell command fails.  However, if ignore_err is not set,
355  #                 this procedure will exit 1 if the shell command fails.  The
356  #                 default value is 1.
357  # trim_cr_lf      Trim any trailing carriage return or line feed from the
358  #                 result.
359
360  # Set defaults (this section allows users to pass blank values for certain
361  # args)
362  set_var_default quiet [get_stack_var quiet 0 2]
363  set_var_default test_mode 0
364  set_var_default show_err 1
365  set_var_default ignore_err 0
366  set_var_default acceptable_shell_rcs 0
367
368  global spawn_id
369  global expect_out
370
371  qprintn ; qprint_issuing ${command_string} ${test_mode}
372
373  if { $test_mode } {
374    return [list 0 ""]
375  }
376
377  send_wrap "${command_string}"
378
379  set expect_result [expect_wrap\
380    [list "-ex $command_string"]\
381    "the echoed command" 5]
382  set expect_result [expect_wrap\
383    [list {[\n\r]{1,2}}]\
384    "one or two line feeds" 5]
385  # Note the non-greedy specification in the regex below (the "?").
386  set expect_result [expect_wrap\
387    [list "(.*?)$prompt_regex"]\
388    "command output plus prompt" -1]
389  # The command's stdout/stderr should be captured as match #1.
390  set out_buf $expect_out(1,string)
391
392  if { $trim_cr_lf } {
393    set out_buf [ string trimright $out_buf "\r\n" ]
394  }
395
396  # Get rc via recursive call to this function.
397  set rc 0
398  set proc_name [get_stack_proc_name]
399  set calling_proc_name [get_stack_proc_name -2]
400  if { $calling_proc_name != $proc_name } {
401    set sub_result [shell_command {echo ${?}} $prompt_regex 1]
402    dprintn ; dprint_list sub_result
403    set rc [lindex $sub_result 1]
404  }
405
406  if { $rc != 0 } {
407    if { $show_err } {
408      puts stderr "" ; print_error_report "The prior shell command failed.\n"
409    }
410    if { ! $ignore_err } {
411      if { [info procs "exit_proc"] != "" } {
412        exit_proc 1
413      }
414    }
415  }
416
417  return [list $rc $out_buf]
418
419}
420
421
422proc boot_to_petitboot {} {
423
424  # Boot the machine until the petitboot screen is reached.
425
426  dprintn ; dprint_executing
427
428  global spawn_id
429  global expect_out
430  global state
431  global os_prompt_regex
432  global petitboot_screen_regex
433  global autoboot_setting
434
435  if { [dict get $state petitboot_screen] } {
436    qprintn ; qprint_timen "Already at petiboot."
437    return
438  }
439
440  if { [dict get $state petitboot_shell_prompt] } {
441    qprintn ; qprint_timen "Now at the shell prompt. Going to petitboot."
442    send_wrap "exit"
443    set expect_result [expect_wrap [list $petitboot_screen_regex]\
444    "the petitboot screen" 900]
445    dict set state petitboot_shell_prompt 0
446    dict set state petitboot_screen 1
447    return
448  }
449
450  if { [dict get $state os_login_prompt] } {
451    set cmd_buf os_login
452    qprintn ; qprint_issuing
453    eval ${cmd_buf}
454  }
455
456  # Turn off autoboot.
457  set_autoboot "false"
458
459  # Reboot and wait for petitboot.
460  send_wrap "reboot"
461
462  # Once we've started a reboot, we are no longer logged into OS.
463  dict set state os_logged_in 0
464  dict set state os_login_prompt 0
465
466  set expect_result [expect_wrap\
467    [list $petitboot_screen_regex]\
468    "the petitboot screen" 900]
469  set expect_result [expect_wrap\
470    [list "Exit to shell"]\
471    "the 'Exit to shell' screen" 10]
472  dict set state petitboot_screen 1
473
474  qprintn ; qprint_timen "Arrived at petitboot screen."
475  dprintn ; dprint_dict state
476
477}
478
479
480proc go_to_petitboot_shell {} {
481
482  # Go to petitboot shell.
483  global spawn_id
484  global state
485  global expect_out
486  global petitboot_shell_prompt_regex
487
488  if { [dict get $state petitboot_shell_prompt] } {
489    qprintn ; qprint_timen "Already at the shell prompt."
490    return
491  }
492
493  eval boot_to_petitboot
494  send_wrap "x"
495  set expect_result [expect_wrap [list $petitboot_shell_prompt_regex]\
496    "the shell prompt" 10]
497  dict set state petitboot_screen 0
498  dict set state petitboot_shell_prompt 1
499  qprintn ; qprint_timen "Arrived at the shell prompt."
500  qprintn ; qprint_timen state
501
502}
503
504
505proc set_autoboot { { autoboot_setting {}} } {
506
507  # Set the state of autoboot.
508  # Defaults to the value of the global autoboot_setting.
509
510  # This will work regardless of whether the OS is logged in or at petitboot.
511
512  # Description of argument(s):
513  # autoboot_setting  The desired state of autoboot (true/flase).
514
515  dprintn ; dprint_executing
516  global spawn_id
517  global expect_out
518  global state
519  global os_prompt_regex
520  global petitboot_shell_prompt_regex
521
522  set_var_default autoboot_setting [get_stack_var autoboot_setting 0 2]
523  set prompt_regex $petitboot_shell_prompt_regex
524
525  if { [dict get $state os_login_prompt] } {
526    set cmd_buf os_login
527    qprintn ; qprint_issuing
528    eval ${cmd_buf}
529    set prompt_regex $os_prompt_regex
530  }
531
532  if { [dict get $state petitboot_screen ] } {
533    set cmd_buf go_to_petitboot_shell
534    qprintn ; qprint_issuing
535    eval ${cmd_buf}
536  }
537
538  if { [dict get $state os_logged_in ] } {
539    set prompt_regex $os_prompt_regex
540  }
541
542
543  set cmd_result [shell_command\
544    "nvram --update-config auto-boot?=$autoboot_setting" $prompt_regex]
545  set cmd_result [shell_command "nvram --print-config" $prompt_regex]
546
547}
548
549
550proc installation_destination {} {
551
552  # Set the software installation destination.
553
554  # Expectation is that we are starting at the "Installation" options screen.
555
556  dprintn ; dprint_executing
557
558  global spawn_id
559  global expect_out
560  global state
561  global installer_screen_regex
562
563  qprintn ; qprint_timen "Presumed to be at \"Installation\" screen."
564
565  qprintn ; qprint_timen "Setting Installation Destination."
566  # Option 5). Installation Destination
567  qprintn ; qprint_timen "Selecting \"Installation Destination\" option."
568  send_wrap "5"
569  expect_wrap [list "Installation Destination"] "installation destination\
570  menu" 30
571
572  qprintn ; qprint_timen "Selecting \"Select all\" option."
573  send_wrap "3"
574  expect_wrap [list "Select all"] "selected all disks" 10
575
576  qprintn ; qprint_timen "Selecting \"continue\" option."
577  send_wrap "c"
578  expect_wrap [list "Autopartitioning"] "autopartitioning options" 10
579
580  qprintn ; qprint_timen "\
581  Selecting \"Replace Existing Linux system(s)\" option."
582  send_wrap "1"
583  expect_wrap [list "Replace"] "selected stanard partition" 10
584
585  qprintn ; qprint_timen "Selecting \"continue\" option."
586  send_wrap "c"
587  expect_wrap [list "Partition Scheme"] "partition scheme options" 10
588
589  qprintn ; qprint_timen "Selecting \"LVM\" option."
590  send_wrap "3"
591  expect_wrap [list "LVM"] "lvm option" 10
592
593  qprintn ; qprint_timen "Selecting \"continue\" option."
594  send_wrap "c"
595  expect_wrap [list $installer_screen_regex] "installation options screen" 10
596
597}
598
599
600proc time_settings {} {
601
602  # Set the time/zone via the petitboot shell prompt "Time settings" menu.
603
604  # Expectation is that we are starting at the "Installation" options screen.
605
606  dprintn ; dprint_executing
607
608  global spawn_id
609  global expect_out
610  global state
611  global installer_screen_regex
612
613  # Option 2). Timezone.
614
615  qprintn ; qprint_timen "Presumed to be at \"Installation\" screen."
616  qprintn ; qprint_timen "Setting time."
617
618  qprintn ; qprint_timen "Selecting \"Time settings\"."
619  send_wrap "2"
620  expect_wrap [list "Set timezone" "Time settings"] "Time settings menu" 30
621
622  qprintn ; qprint_timen "Selecting \"Change timezone\"."
623  send_wrap "1"
624  expect_wrap [list "Available regions"] "available regions menu" 10
625
626  qprintn ; qprint_timen "Selecting \"US\"."
627  send_wrap "11"
628  expect_wrap [list "region US"] "select region in US menu" 10
629
630  qprintn ; qprint_timen "Selecting \"Central\"."
631  send_wrap "3"
632  expect_wrap [list $installer_screen_regex] "installation options screen" 10
633
634}
635
636
637proc software_selection {} {
638
639  # Set the base environment via the petitboot shell prompt
640  # "Software Selection" menu.
641
642  # Expectation is that we are starting at the "Installation" options
643  # screen.
644
645  dprintn ; dprint_executing
646
647  global spawn_id
648  global expect_out
649  global state
650  global installer_screen_regex
651
652  qprintn ; qprint_timen "Presumed to be at \"Installation\" screen."
653  qprintn ; qprint_timen "Software selection."
654  # Option 4). Software selection.
655  set expect_result 0
656  while { $expect_result != 1 } {
657    qprintn ; qprint_timen "Selecting \"Software selection\"."
658    send_wrap "4"
659    set expect_result [expect_wrap\
660      [list "Installation source needs to be set up first." \
661      "Base environment"] "base environment menu" 10 0]
662
663    switch $expect_result {
664      0 {
665        qprintn ; qprint_timen "Selecting \"continue\"."
666        send_wrap "c"
667        expect_wrap [list $installer_screen_regex] \
668        "installation options screen" 15
669      }
670      1 {
671        break
672      }
673    }
674  }
675
676  qprintn ; qprint_timen "Selecting \"Infrastructure Server\"."
677  send_wrap "2"
678  expect_wrap [list "Infrastructure"] "selected infrastructure" 15
679
680  qprintn ; qprint_timen "Selecting \"continue\"."
681  send_wrap "c"
682  expect_wrap [list $installer_screen_regex] "installation options screen" 15
683
684}
685
686
687proc root_password {} {
688
689  # Set the os root password via the petitboot shell prompt "Root password"
690  # option.
691
692  # Expectation is that we are starting at the "Installation" options screen.
693
694  dprintn ; dprint_executing
695
696  global spawn_id
697  global expect_out
698  global state
699  global os_password
700  global installer_screen_regex
701
702  qprintn ; qprint_timen "Presumed to be at \"Installation\" screen."
703  qprintn ; qprint_timen "Setting root password."
704
705  # Option 8). Root password.
706  qprintn ; qprint_timen "Selecting \"Root password\"."
707  send_wrap "8"
708  expect_wrap [list "Password:"] "root password prompt" 30
709
710  qprintn ; qprint_timen "Entering root password."
711  send_wrap "$os_password"
712  expect_wrap [list "confirm"] "comfirm root password prompt" 15
713
714  qprintn ; qprint_timen "Re-entering root password."
715  send_wrap "$os_password"
716  set expect_result [expect_wrap\
717    [list $installer_screen_regex "The password you have provided is weak"] \
718    "root password accepted" 10 0]
719  switch $expect_result {
720    0 {
721      break
722    }
723    1 {
724    qprintn ; qprint_timen "Confirming weak password."
725      send_wrap "yes"
726    }
727  }
728  expect_wrap [list $installer_screen_regex] "installation options screen" 10
729
730}
731
732
733proc install_os {} {
734
735  # Install an os on the machine.
736  global spawn_id
737  global expect_out
738  global petitboot_shell_prompt_regex
739  global installer_screen_regex
740  global ftp_username ftp_password os_repo_url
741  global os_host os_username os_password
742
743  lassign [get_host_name_ip $os_host 0] os_hostname short_host_name ip_address
744  set netmask [get_host_netmask $os_host $os_username $os_password {} 0]
745  set gateway [get_host_gateway $os_host $os_username $os_password 0]
746  set mac_address \
747    [get_host_mac_address $os_host $os_username $os_password {} 0]
748  set name_servers [get_host_name_servers $os_host $os_username $os_password 0]
749  set dns [lindex $name_servers 0]
750  set domain [get_host_domain $os_host $os_username $os_password 0]
751
752  # Go to shell and download files for installation
753  eval go_to_petitboot_shell
754  after 10000
755  set vmlinuz_url \
756    "ftp://$ftp_username:$ftp_password@$os_repo_url/ppc/ppc64/vmlinuz"
757  set initrd_url \
758    "ftp://$ftp_username:$ftp_password@$os_repo_url/ppc/ppc64/initrd.img"
759  send_wrap "wget -c $vmlinuz_url"
760  expect_wrap [list "vmlinuz *100%"] "wget vmlinuz file success" 30
761  send_wrap "wget -c $initrd_url"
762  expect_wrap [list "initrd.img *100%"] "wget initrd file success" 30
763
764  # Setup parms and run kexec.
765  set colon "::"
766  set squashfs_url \
767    "ftp://$ftp_username:$ftp_password@$os_repo_url/LiveOS/squashfs.img"
768  set kexec_args "kexec -l vmlinuz --initrd initrd.img\
769    --append='root=live:$squashfs_url \
770    repo=ftp://$ftp_username:$ftp_password@$os_repo_url rd.dm=0 rd.md=0\
771    nodmraid console=hvc0 ifname=net0:$mac_address\
772    ip=$os_host$colon$gateway:$netmask:$os_hostname:net0:none nameserver=$dns\
773    inst.text'"
774  send_wrap "$kexec_args"
775  dprintn ; dprint_vars expect_out
776  set expect_result [expect_wrap [list $petitboot_shell_prompt_regex]\
777    "the shell prompt" 10]
778
779  # Turn on autoboot.
780  set_autoboot "true"
781
782  send_wrap "kexec -e"
783
784  # Begin installation process, go to settings screen.
785  set expect_result [expect_wrap [list "Starting installer"]\
786    "starting installer log" 900]
787  set expect_result [expect_wrap [list "Use text mode"]\
788    "install mode selection prompt" 120]
789  send_wrap "2"
790  expect_wrap [list $installer_screen_regex] "installation options screen" 15
791
792  installation_destination
793  time_settings
794  software_selection
795  root_password
796
797  # Now begin installation process.
798  set expect_result [expect_wrap\
799    [list $os_repo_url "Processing..."] \
800    "installation source processing" 10 0]
801
802  switch $expect_result {
803    0 {
804      break
805    }
806    1 {
807      expect_wrap [list $os_repo_url] "source processing complete" 240
808    }
809  }
810  send_wrap "b"
811  set expect_result [expect_wrap \
812    [list "Installation complete* Press return to quit"] \
813    "os installation complete message" 2000]
814  send_wrap ""; # Reboots to petitboot.
815  return
816
817}
818
819
820# Main
821
822  gen_get_options $argv
823
824  validate_parms
825
826  qprint_pgm_header
827
828  # Global variables for current prompts of the SOL console.
829  set ssh_password_prompt ".* password: "
830  set os_login_prompt_regex "login: "
831  set os_password_prompt "Password: "
832  set petitboot_screen_regex "Petitboot"
833  set cr_lf_regex "\[\n\r\]"
834  set os_prompt_regex "(\\\[${os_username}@\[^ \]+ ~\\\]# )"
835  set petitboot_shell_prompt_regex "/ #"
836  set installer_screen_regex \
837  {Installation[\r\n].*Please make your choice from above.* to refresh\]: }
838
839  dprintn ; dprint_dict state
840
841  set cmd_buf sol_login
842  qprint_issuing
843  eval ${cmd_buf}
844
845  set cmd_buf get_post_ssh_login_state
846  qprintn ; qprint_issuing
847  eval ${cmd_buf}
848
849  foreach proc_name $proc_names {
850    set cmd_buf ${proc_name}
851    qprintn ; qprint_issuing
852    eval ${cmd_buf}
853  }
854
855  exit_proc