home *** CD-ROM | disk | FTP | other *** search
/ Chip: Linux Special / CorelLinux_CHIP.iso / VMware / bin / vmware-wizard / wiz.tcl < prev   
Encoding:
Tcl/Tk script  |  1999-11-08  |  50.7 KB  |  1,704 lines

  1. #!/usr/bin/wishx
  2.  
  3. #load {} Tclx
  4. #signal default *
  5.  
  6. option add *Font -*-helvetica-medium-r-*-*-12-120-*-*-*-*-iso8859-*
  7. option add *Button.Font -*-helvetica-medium-r-*-*-10-100-*-*-*-*-iso8859-*
  8. option add *selectBorderWidth 0
  9. option add *Radiobutton.selectColor grey
  10. option add *Radiobutton.highlightBackground [. cget -background]
  11. option add *Canvas.highlightBackground [. cget -background]
  12.  
  13. set bold -*-helvetica-bold-r-*-*-12-120-*-*-*-*-iso8859-*
  14.  
  15. set tk_strictMotif 1
  16.  
  17. source "lib/util.tcl"
  18. source "lib/shell.tcl"
  19. source "lib/dialog.tcl"
  20. source "lib/help.tcl"
  21. source "helpText.tcl"
  22. source "helpURLs.tcl"
  23. source "rawdisk.tcl"
  24.  
  25. # In case we run as root,
  26. # Force the path to reduce the risk of using "modified" external helpers
  27. # If the user has a special system setup, he will be prompted for the
  28. # proper location anyway
  29. proc restrict_path {} {
  30.     global env
  31.  
  32.     if {[GetEuid] == 0} {
  33.     set env(PATH) "/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11/bin"
  34.     }
  35. }
  36.  
  37. # Set up the location of external helpers
  38. proc initialize_external_helpers {} {
  39.     global db
  40.  
  41.     set db(helper.netscape) [Shell_DoesBinaryExist_Prompt {netscape}]
  42.     if {$db(helper.netscape) == ""} {
  43.         DialogWin .error "Configuration Wizard Error" "The wizard can work without netscape, however the help system will not be available." {} 0 OK
  44.     # We can live without netscape (at least I hope so), so don't exit
  45.     }
  46.  
  47.     set db(helper.grep) [Shell_DoesBinaryExist_Prompt {grep}]
  48.     if {$db(helper.grep) == ""} {
  49.         DialogWin .error "Configuration Wizard Error" "Unable to continue without grep. Configuration cancelled." {} 0 OK
  50.         exit 1
  51.     }
  52.  
  53.     set db(helper.df) [Shell_DoesBinaryExist_Prompt {df}]
  54.     if {$db(helper.df) == ""} {
  55.         DialogWin .error "Configuration Wizard Error" "Unable to continue without df. Configuration cancelled." {} 0 OK
  56.         exit 1
  57.     }
  58.  
  59.     set db(helper.chmod) [Shell_DoesBinaryExist_Prompt {chmod}]
  60.     if {$db(helper.chmod) == ""} {
  61.         DialogWin .error "Configuration Wizard Error" "Unable to continue without chmod. Configuration cancelled." {} 0 OK
  62.         exit 1
  63.     }
  64. }
  65.  
  66. # Hide the main window until we are done with initialization
  67. wm withdraw .
  68.  
  69. restrict_path
  70.  
  71. initialize_external_helpers
  72.  
  73. set option(outputFileName) 0
  74.  
  75. set len [llength $argv]
  76.  
  77. for {set i 0} {$i < $len} {incr i} {
  78.     set arg [lindex $argv $i]
  79.     switch -exact -- $arg {
  80.         "-x" {
  81.             set option(outputFileName) 1
  82.         }
  83.  
  84.         "-rawdisk" {
  85.             # obsolete
  86.         }
  87.         
  88.         "-safedisk" {
  89.             incr i
  90.             if {$i >= $len} {
  91.                 puts "usage: $argv0 \[-x\] \[-safedisk <device>\]"
  92.                 exit                
  93.             }
  94.             set option(safedisk) [lindex $argv $i]
  95.         }
  96.  
  97.         default {
  98.             puts "usage: $argv0 \[-x\] \[-safedisk <device>\]"
  99.             exit
  100.         }
  101.     }
  102. }
  103.  
  104.  
  105. ############################################################
  106. ###
  107. ### machine config databse
  108. ###
  109. ###  Set defaults here. Probe host configuration here if
  110. ###  necessary to help determine reasonable defaults.
  111. ###
  112. ############################################################
  113.  
  114.  
  115. ##
  116. ## db(OS)       { dos, win31, win95, win98, nt4, win2000, linux, other }
  117. ## db(OS.name)
  118. ## 
  119.  
  120. set db(OS) <null>
  121. set db(OS.name) <null>
  122.  
  123.  
  124. ##
  125. ## db(directory)
  126. ## db(directory.userSet)
  127. ## db(directory.mountPoint.name)
  128. ## db(directory.mountPoint.type)
  129. ## db(directory.mountPoint.available)
  130. ##
  131.  
  132. set db(directory) $env(HOME)/vmware/$db(OS.name)/
  133. set db(directory.userSet) 0
  134. set db(directory.mountPoint.name) <null>
  135. set db(directory.mountPoint.type) <null>
  136. set db(directory.mountPoint.available) <null>
  137.  
  138.  
  139. ##
  140. ## db(diskType)
  141. ##
  142. ## legal values:
  143. ##
  144. ##   file - create a virtual disk in a file
  145. ##   part - create a safe raw disk file
  146. ##
  147.  
  148. set db(diskType) file
  149.  
  150.  
  151. ##
  152. ## db(diskSize)  (in MB)
  153. ## db(diskSize.userSet)
  154. ##
  155.  
  156. set db(diskSize) 500
  157. set db(diskSize.userSet) 0
  158.  
  159.  
  160. ##
  161. ## db(hostRawDisk.validDrives) : List of allowed drive names
  162. ## db(hostRawDisk.drives) : List of detected ro or rw drives
  163. ## db(hostRawDisk.<drive>.userAccess)    { np none ro rw }
  164. ## db(hostRawDisk.<drive>.partitions)
  165. ## db(hostRawDisk.<drive>.<partition>.start)
  166. ## db(hostRawDisk.<drive>.<partition>.end)
  167. ## db(hostRawDisk.<drive>.<partition>.id)
  168. ## db(hostRawDisk.<drive>.<partition>.type)
  169. ##
  170. ## db(rawDisk.<drive>.used)
  171. ## db(rawDisk.<drive>.<partition>.access)     { none ro rw }
  172. ##
  173.  
  174. set db(hostRawDisk.validDrives) {hda hdb hdc hdd hde hdf hdg hdh hdi hdj hdk hdl}
  175. set db(hostRawDisk.drives) {}
  176.  
  177. foreach drive $db(hostRawDisk.validDrives) {
  178.     GetRawDiskInfo $drive
  179. }
  180.  
  181.  
  182. ##
  183. ## db(cdrom.present)
  184. ## db(cdrom.fileName)
  185. ## db(cdrom.wanted)
  186. ##
  187.  
  188. set db(cdrom.present) 1
  189. set db(cdrom.fileName) /dev/cdrom
  190. set db(cdrom.wanted) 1
  191.  
  192.  
  193. ##
  194. ## db(floppy.present)
  195. ## db(floppy.fileName)
  196. ## db(floppy.wanted)
  197. ##
  198.  
  199. set db(floppy.present) 1
  200. set db(floppy.fileName) /dev/fd0
  201. set db(floppy.wanted) 1
  202.  
  203.  
  204. ##
  205. ## db(networking)   { none bridged hostOnly }
  206. ##
  207.  
  208. set db(networking) none
  209.  
  210.  
  211. ##
  212. ## db(memorySize)
  213. ## db(hostMemorySize)
  214. ##
  215.  
  216. set db(memorySize) 32
  217.  
  218. if {[file readable /proc/meminfo]} {
  219.     if {[catch {exec $db(helper.grep) MemTotal /proc/meminfo} memLine]} {
  220.         DialogWin .error "Configuration Wizard Error" \
  221.             "Error opening /proc/meminfo:\n$memLine" {} 0 OK
  222.         exit
  223.     }
  224.     
  225.     regexp {MemTotal:[ ]*([0-9]*)[ ]*kB} $memLine dummy kbmem
  226.     set db(hostMemorySize) [expr {$kbmem / 1024}]
  227.     
  228. } else {
  229.     set db(hostMemorySize) 32
  230.  
  231.  
  232. ############################################################
  233. ###
  234. ### parse locations file
  235. ###
  236. ############################################################
  237.  
  238. if {[catch {set fd [open /etc/vmware/config]} err]} {
  239.     set ret [DialogWin .error "Configuration Wizard Error" \
  240.                  "There is no VMware distribution installed on this system." \
  241.                  {} 0 Exit Continue]
  242.     if {$ret == 0} {
  243.         exit
  244.     }
  245.     set fd ""
  246. }
  247.  
  248. if {$fd != ""} {
  249.     while {[gets $fd line] != -1} {
  250.         if {[regexp {([A-Za-z0-9\.\-\_]*)[ ]*=[ ]*\"?([^\"]*)\"?} $line dummy opt value]} {
  251.             set install($opt) $value
  252.             if {[string match {*.HostOnly*} $opt]} {
  253.                 set install(HostOnly) 1
  254.             }
  255.         }
  256.     }
  257.     
  258.     close $fd
  259. }
  260.  
  261.  
  262. ############################################################
  263. ###
  264. ### panels
  265. ###
  266. ############################################################
  267.  
  268. set panel(width)   5i
  269. set panel(height)  5i
  270.  
  271. set panel(current) welcome
  272. set panel(stack) {}
  273.  
  274. proc NewPanel {name} {
  275.     global panel bold
  276.     frame .$name -width $panel(width) -height $panel(height) -relief flat
  277.     message .$name.title -justify left -text $panel(${name}.title) \
  278.         -width $panel(width) -pady 3m -font $bold
  279.     message .$name.msg -justify left -text $panel(${name}.text) \
  280.         -width $panel(width)
  281.     pack .$name.title .$name.msg -in .$name -anchor w
  282.     $panel(${name}.init) $name
  283. }
  284.  
  285. image create photo redximage -file images/redx.gif
  286. image create photo yellowximage -file images/yellowx.gif
  287.  
  288. proc MakeWarning {name priority text} {
  289.     global panel
  290.  
  291.     frame $name -width $panel(width) -relief flat
  292.     canvas $name.canvas -width 32p -height 40p
  293.  
  294.     switch $priority {
  295.         1 { set imageName "redximage" }
  296.         2 { set imageName "yellowximage" }
  297.     }
  298.     
  299.     $name.canvas create image 0p 8p -anchor nw -image $imageName
  300.     message $name.msg -text $text -width 4i
  301.     pack $name.canvas $name.msg -side left -anchor nw
  302. }
  303.  
  304.  
  305. ##
  306. ## Welcome panel
  307. ##
  308.  
  309. set panel(welcome.title) {Welcome}
  310. set panel(welcome.init) Welcome_Init
  311. set panel(welcome.activate) Welcome_Activate
  312. set panel(welcome.deactivate) Welcome_Deactivate
  313. set panel(welcome.next) os
  314. set panel(welcome.text) "Welcome to the VMware for Linux Configuration Wizard."
  315. set panel(welcome.text2) {This wizard automates the most common tasks in order to properly create and configure a VMware Virtual Machine. It will ask a few simple questions, and at the end it will create all the files you need to run the VM.
  316.  
  317. The configuration settings which you will be selecting for the new virtual machine can be viewed and changed at a later time by using the Configuration Editor.
  318.     
  319. Click the "Next" button to proceed.
  320.  
  321. At any point you may return to the previous panel by clicking on the "Prev" button, or abort the wizard by clicking on the "Cancel" button.  You may also select default parameters and skip to the last panel by using the "Finish" button.
  322.  
  323. The "Help" button provides context sensitive help and links to relevant online documentation.}
  324.  
  325. proc Welcome_Init {name} {
  326.     global panel
  327.     
  328.     message .welcome.msg2 -text $panel(welcome.text2) -width $panel(width)
  329.     pack .welcome.msg2 -in .welcome -anchor w
  330. }
  331.  
  332. proc Welcome_Activate {} {
  333.     .nav.prev configure -state disabled
  334.     .nav.finish configure -state disabled
  335.     bind . <Alt-KeyPress-p> {}
  336.     bind . <Alt-KeyPress-f> {}
  337. }
  338.  
  339. proc Welcome_Deactivate {} {
  340.     .nav.prev configure -state normal
  341.     .nav.finish configure -state normal
  342.     bind . <Alt-KeyPress-p> Prev
  343.     bind . <Alt-KeyPress-f> Finish
  344. }
  345.  
  346.  
  347. ##
  348. ## Guest OS panel
  349. ##
  350.  
  351. set panel(os.title) {Guest Operating System}
  352. set panel(os.init) OS_Init
  353. set panel(os.activate) OS_Activate
  354. set panel(os.deactivate) OS_Deactivate
  355. set panel(os.next) dir
  356. set panel(os.text) {Please select the operating system you plan on installing in the virtual machine (your guest OS). This information is used to determine optimal default values for the guest OS, and it does not limit your machine's ability to run other OSes.}
  357.  
  358. set panel(os.entry) Other
  359.  
  360. proc OS_Init {name} {
  361.     set osNames { \
  362.                   {"dos" "MS DOS"} \
  363.                   {"win31" "Windows 3.1"} \
  364.                   {"win95" "Windows 95"} \
  365.                   {"win98" "Windows 98"} \
  366.                   {"nt4" "Windows NT (Workstation or Server) 4.0"} \
  367.                   {"win2000" "Windows 2000"} \
  368.                   {"linux" "Linux"} \
  369.                   {"other" "Other"} \
  370.               }
  371.  
  372.     foreach osInfo $osNames {
  373.         set os [lindex $osInfo 0]
  374.         set text [lindex $osInfo 1]
  375.         radiobutton .os.$os -text $text -variable db(OS) -value $os -anchor w -command OS_Set
  376.         pack .os.$os -in .os -anchor w -padx 5m
  377.     }
  378.  
  379.     bind .os.win98 billg {WindowShake 1}
  380.     bind .os.linux linus {WindowShake 0}
  381.     
  382.     entry .os.entry -relief sunken -bd 2 -textvariable panel(os.entry) -width 20
  383.     OS_Set
  384. }
  385.  
  386. proc WindowShake {arg} {
  387.     global lastOne onOff
  388.  
  389.     switch $arg {
  390.         0 {
  391.             set onOff 0
  392.         }
  393.         1 {
  394.             set onOff 1
  395.         }
  396.     }
  397.  
  398.     if {$onOff} {
  399.         set geo [split [wm geometry .] "+"]
  400.         
  401.         if {![info exists lastOne] || $lastOne} {
  402.             set newX [expr {[lindex $geo 1] + 10}]
  403.             set lastOne 0
  404.         } else {
  405.             set newX [expr {[lindex $geo 1] - 10}]
  406.             set lastOne 1
  407.         }
  408.         
  409.         wm geometry . "+${newX}+[lindex $geo 2]"
  410.         
  411.         after 100 WindowShake 2
  412.     }
  413. }
  414.  
  415. proc OS_Activate {} {
  416.     global db panel
  417.     if {$db(OS) == "<null>"} {
  418.         .nav.next configure -state disabled
  419.         .nav.finish configure -state disabled
  420.         bind . <Alt-KeyPress-n> {}
  421.         bind . <Alt-KeyPress-f> {}
  422.     }
  423. }
  424.  
  425. proc OS_Deactivate {} {
  426.     global db panel env
  427.  
  428.     if {$db(OS) == "<null>"} {
  429.         # must be prev
  430.         .nav.next configure -state normal
  431.         .nav.finish configure -state normal
  432.         bind . <Alt-KeyPress-n> Prev
  433.         bind . <Alt-KeyPress-f> Finish
  434.         return
  435.     }
  436.     
  437.     switch $db(OS) {
  438.         dos -
  439.         win31 {
  440.             set db(memorySize) 16
  441.         }
  442.         linux -
  443.         win95 -
  444.         win98 {
  445.             if {$db(hostMemorySize) > 100} {
  446.                 set db(memorySize) 48
  447.             } else {
  448.                 set db(memorySize) 32
  449.             }            
  450.         }
  451.         other {
  452.             set db(memorySize) 32
  453.         }
  454.         nt4 -
  455.         win2000 {
  456.             if {$db(hostMemorySize) > 100} {
  457.                 set db(memorySize) 64
  458.             } else {
  459.                 set db(memorySize) 32
  460.             }
  461.         }
  462.     }
  463.  
  464.     set db(diskSize) 2000
  465.  
  466.     if {$db(OS) == "other"} {
  467.         set db(OS.name) $panel(os.entry)
  468.     } else {
  469.         set db(OS.name) $db(OS)
  470.     }
  471.     
  472.     if {!$db(directory.userSet)} {
  473.         set db(directory) "$env(HOME)/vmware/$db(OS.name)/"
  474.         UpdateMountPoint
  475.     }
  476. }
  477.  
  478. proc OS_Set {} {
  479.     global db
  480.     
  481.     if {$db(OS) == "other"} {
  482.         pack .os.entry -in .os -padx 15m -pady 1m -anchor w
  483.         focus .os.entry
  484.         .os.entry icursor end
  485.     } else {
  486.         pack forget .os.entry
  487.     }
  488.  
  489.     .nav.next configure -state normal
  490.     .nav.finish configure -state normal
  491.     bind . <Alt-KeyPress-n> Prev
  492.     bind . <Alt-KeyPress-f> Finish
  493. }
  494.  
  495.  
  496.  
  497. ##
  498. ## Directory panel
  499. ##
  500.  
  501. set panel(dir.title) {Virtual Machine Directory}
  502. set panel(dir.init) Dir_Init
  503. set panel(dir.activate) Dir_Activate
  504. set panel(dir.deactivate) Dir_Deactivate
  505. set panel(dir.next) diskType
  506.  
  507. set panel(dir.text) {Please select a directory for the virtual machine. It is suggested that each virtual machine have its own directory.}
  508.  
  509. proc Dir_Init {name} {
  510.     label .dir.label -text "Full path of the virtual machine directory:"
  511.     frame .dir.frame -relief flat
  512.     entry .dir.frame.entry -width 40 -relief sunken -bd 2 -textvariable panel(dir.entry)
  513.     button .dir.frame.browse -text "Browse..." -command Dir_Browse
  514.     pack .dir.frame.entry -in .dir.frame -side left -pady 1m
  515.     # pack .dir.frame.browse -in .dir.frame -side left -padx 2m
  516.     pack .dir.label .dir.frame -in .dir -anchor w -padx 5m
  517. }
  518.  
  519. proc Dir_Activate {} {
  520.     global panel db
  521.     set panel(dir.entry) $db(directory)
  522.     focus .dir.frame.entry
  523.     .dir.frame.entry icursor end
  524. }
  525.  
  526. proc Dir_Deactivate {} {
  527.     global panel db
  528.     if {$panel(dir.entry) != $db(directory)} {
  529.         if {$panel(dir.entry) == ""} {
  530.             set panel(dir.entry) "."
  531.         }
  532.         set db(directory) $panel(dir.entry)
  533.         set db(directory.userSet) 1
  534.         if {[string index $db(directory) [expr {[string length $db(directory)] - 1}]] != "/"} {
  535.             set db(directory) "$db(directory)/"
  536.         }
  537.     }
  538.     UpdateMountPoint
  539. }
  540.  
  541. proc Dir_Browse {} {
  542.     global panel
  543.     set ret [tk_getSaveFile]
  544.     if {$ret != ""} {
  545.         set panel(dir.entry) $ret
  546.     }
  547. }
  548.  
  549. proc UpdateMountPoint {} {
  550.     global db
  551.  
  552.     set path [file nativename $db(directory)]
  553.  
  554.     while {1} {
  555.         if {![catch {exec $db(helper.df) -P -T -k $path} dfOut]} {
  556.             break
  557.         }
  558.  
  559.         if {$path == "/"} {
  560.             DialogWin .error "Configuration Wizard Error" \
  561.                 "Error execing $db(helper.df):\n$dfOut" {} 0 OK
  562.             exit
  563.         }
  564.         
  565.         set path [file dirname $path]
  566.     }
  567.     
  568.     regsub -all {[ ]+} $dfOut " " dfOut
  569.     set lines [split $dfOut "\n"]
  570.  
  571.     if {[llength $lines] != 2} {
  572.         DialogWin .error "Configuration Wizard Error" \
  573.             "Bad df output:\n$dfOut" {} 0 OK
  574.         exit
  575.     }
  576.  
  577.     set fields [split [lindex $lines 0]]
  578.     if {![regexp -nocase {(1024|1k)-blocks} [lindex $fields 2]]} {
  579.         DialogWin .error "Configuration Wizard Error" \
  580.             "Bad df output:\n$dfOut--[lindex fields 2]" {} 0 OK
  581.         exit
  582.     }
  583.  
  584.     set fields [split [lindex $lines 1]]
  585.     set db(directory.mountPoint.name) [lindex $fields 6]
  586.     set db(directory.mountPoint.type) [lindex $fields 1]
  587.     set db(directory.mountPoint.available) [expr {int(ceil([lindex $fields 4]/1024))}]
  588. }
  589.  
  590.  
  591. ##
  592. ## Disk selection panel
  593. ##
  594.  
  595. set panel(diskType.title) {Virtual Disk Type Setting}
  596. set panel(diskType.init) DiskType_Init
  597. set panel(diskType.activate) DiskType_Activate
  598. set panel(diskType.deactivate) DiskType_Deactivate
  599. set panel(diskType.next) <null>
  600. set panel(diskType.text) {Please choose what type of disk the virtual machine will use.}
  601.  
  602. set panel(diskType.fileTextIn) {Virtual disks appear as files on the host operating system's file system.}
  603. set panel(diskType.partText) {Existing physical disks are the disks seen by the host operating system.  They can be used as disks for this virtual machine. This option is recommended for advanced users only.
  604.  
  605. If a physical disk is empty, you can install an operating system in it.
  606.  
  607. If a physical disk already has an operating system installed (you have a multi-boot system), you can bring that disk up within the virtual machine.
  608.  
  609. You have the following access rights for IDE drives on this system:}
  610. set panel(diskType.nfsWarnText) {The directory you have chosen is on an NFS mounted file system ($mount). Disk performance to NFS file systems can be slow. It is advised that you change the virtual machine's directory to a local file system.}
  611. set panel(diskType.fileText) $panel(diskType.fileTextIn)
  612.  
  613. proc DiskType_Init {name} {
  614.     global panel db
  615.  
  616.     radiobutton .diskType.file -text "New Virtual Disk" -variable db(diskType) \
  617.         -value file -anchor w -command DiskType_Set -padx 5m
  618.     
  619.     radiobutton .diskType.partition -text "Existing Physical Disk" -variable db(diskType) \
  620.         -value part -anchor w -command DiskType_Set -padx 5m
  621.  
  622.     message .diskType.msg2 -justify left -text $panel(diskType.fileText) -width $panel(width) -pady 5m
  623.     
  624.     MakeWarning .diskType.warn 2 $panel(diskType.nfsWarnText)
  625.  
  626.     pack .diskType.file .diskType.partition .diskType.msg2 -in .diskType -anchor w
  627. }
  628.  
  629. proc DiskType_Set {} {
  630.     global db panel
  631.     switch $db(diskType) {
  632.         file {
  633.             .diskType.msg2 configure -text $panel(diskType.fileText)
  634.             if {$db(directory.mountPoint.type) == "nfs"} {
  635.                 regsub {\$mount} "$panel(diskType.nfsWarnText)" \
  636.                     $db(directory.mountPoint.name) text
  637.                 .diskType.warn.msg configure -text $text
  638.                 pack .diskType.warn -in .diskType -anchor w -padx 2m
  639.             } else {
  640.                 pack forget .diskType.warn
  641.             }
  642.         }
  643.         part {
  644.             pack forget .diskType.warn
  645.  
  646.             set text ""
  647.             foreach drive $db(hostRawDisk.validDrives) {
  648.                 set text "${text}\n     /dev/$drive"
  649.                 switch $db(hostRawDisk.$drive.userAccess) {
  650.                     "np"   {set text "$text - not present"}
  651.                     "none" {set text "$text - no access"}
  652.                     "ro"   {set text "$text - read only access"}
  653.                     "rw"   {set text "$text - read/write access"}
  654.                 }
  655.             }
  656.  
  657.             if {[llength $db(hostRawDisk.drives)] != 0} {
  658.                 set text "$panel(diskType.partText)\n$text"
  659.                 .diskType.msg2 configure -text $text
  660.             } else {
  661.                 set text1 {Either you don't have access to the IDE drives on this system or no IDE drives were detected. You will only be able to configure a virtual disk on the host file system.
  662.  
  663. You have the following access rights for IDE drives on this system:}
  664.  
  665.                 DialogWin .error "Configuration Wizard Help" "$text1\n$text" {} 0 OK
  666.                 set db(diskType) file
  667.                 DiskType_Set
  668.             }
  669.         }
  670.     }
  671. }
  672.  
  673. proc DiskType_Deactivate {} {
  674.     global db panel
  675.     switch $db(diskType) {
  676.         file { set panel(diskType.next) diskSize }
  677.         part { set panel(diskType.next) rawDisk_[lindex $db(hostRawDisk.drives) 0] }
  678.     }       
  679. }
  680.  
  681. proc DiskType_Activate {} {
  682.     DiskType_Set
  683. }
  684.  
  685.  
  686. ##
  687. ## Disk size panel
  688. ##
  689.  
  690. set panel(diskSize.title) {Virtual Disk Size Setting}
  691. set panel(diskSize.init) DiskSize_Init
  692. set panel(diskSize.activate) DiskSize_Activate
  693. set panel(diskSize.deactivate) DiskSize_Deactivate
  694. set panel(diskSize.next) cdrom
  695. set panel(diskSize.text) {The wizard will create a persistent virtual disk on the host file system. Please enter the size of the virtual disk. After the disk is created, this parameter may not be changed.}
  696.  
  697. set panel(diskSize.hostDiskSpace) {The disk size you have selected ($diskSize MB) is greater than the free space on the file system ($mountPoint has $available MB available). The disk can be created now but your virtual machine may run out of host disk space later.}
  698. set panel(diskSize.sizeZeroText) {The virtual disk size must be at least 1 megabyte.}
  699. set panel(diskSize.sizeLimitationText) {Because of limitations of the host file system the maximum allowable virtual hard disk size is 2047 megabytes.}
  700.  
  701. proc DiskSize_Init {name} {
  702.     global panel option
  703.     
  704.     frame .diskSize.frame -relief flat
  705.     label .diskSize.frame.label -text "Virtual disk size (in megabytes):"
  706.     entry .diskSize.frame.entry -width 7 -relief sunken -bd 2 \
  707.         -textvariable panel(diskSize.entry)
  708.     pack .diskSize.frame.label .diskSize.frame.entry -in .diskSize.frame \
  709.         -anchor w -side left -padx 1m
  710.     pack .diskSize.frame -in .diskSize -padx 5m -pady 4m -anchor w
  711.  
  712.     MakeWarning .diskSize.warn 2 $panel(diskSize.hostDiskSpace)
  713.     MakeWarning .diskSize.warn2 1 $panel(diskSize.sizeLimitationText)
  714.     MakeWarning .diskSize.warn3 2 $panel(diskType.nfsWarnText)
  715.     
  716.     trace variable panel(diskSize.entry) w DiskSize_Set
  717. }
  718.  
  719. proc DiskSize_Set {name element op} {
  720.     global db panel
  721.  
  722.     regsub -all {[^0-9]} $panel(diskSize.entry) "" panel(diskSize.entry)
  723.  
  724.     set indx [.diskSize.frame.entry index insert]
  725.     
  726.     while {[string length $panel(diskSize.entry)] > 6} {
  727.         set panel(diskSize.entry) [string_delete $panel(diskSize.entry) $indx $indx]
  728.         incr indx -1
  729.     }
  730.  
  731.     if {$panel(diskSize.entry) == ""} {
  732.     } elseif {$panel(diskSize.entry) > 2047} {
  733.         pack forget .diskSize.warn
  734.         pack .diskSize.warn2 -in .diskSize -anchor w -pady 5m -padx 2m
  735.     } elseif {$panel(diskSize.entry) > $db(directory.mountPoint.available)} {
  736.         pack forget .diskSize.warn2
  737.         set text $panel(diskSize.hostDiskSpace)
  738.         regsub -all {\$diskSize} $text $panel(diskSize.entry) text
  739.         regsub -all {\$mountPoint} $text $db(directory.mountPoint.name) text
  740.         regsub -all {\$available} $text $db(directory.mountPoint.available) text
  741.         .diskSize.warn.msg configure -text $text
  742.         pack .diskSize.warn -in .diskSize -anchor w -pady 5m -padx 2m
  743.     } else {
  744.         pack forget .diskSize.warn2
  745.         pack forget .diskSize.warn
  746.     }
  747. }
  748.  
  749. proc DiskSize_Activate {} {
  750.     global panel db option
  751.  
  752.     if {0} {
  753.         # used to be here with rawdisk option
  754.         # obsolete now - this warning is in disk type panel
  755.         if {$db(directory.mountPoint.type) == "nfs"} {
  756.             regsub {\$mount} "$panel(diskType.nfsWarnText)" \
  757.                 $db(directory.mountPoint.name) text
  758.             .diskSize.warn3.msg configure -text $text
  759.             pack .diskSize.warn3 -in .diskSize -anchor w -pady 5m -padx 2m
  760.         } else {
  761.             pack forget .diskSize.warn3
  762.         }
  763.     }
  764.     
  765.     set panel(diskSize.entry) $db(diskSize)
  766.     focus .diskSize.frame.entry
  767.     .diskSize.frame.entry icursor end
  768. }
  769.  
  770. proc DiskSize_Deactivate {} {
  771.     global panel db
  772.     if {($panel(diskSize.entry) == "") || ($panel(diskSize.entry) == 0)} {
  773.         DialogWin .error "Wizard Error" $panel(diskSize.sizeZeroText) {} 0 OK
  774.         set panel(diskSize.entry) $db(diskSize)
  775.         .diskSize.frame.entry icursor 5
  776.         return retry
  777.     }
  778.     if {$panel(diskSize.entry) > 2047} {
  779.         DialogWin .error "Wizard Error" $panel(diskSize.sizeLimitationText) {} 0 OK
  780.         set panel(diskSize.entry) 2047
  781.         return retry
  782.     }
  783.     if {$panel(diskSize.entry) != $db(diskSize)} {
  784.         set db(diskSize) $panel(diskSize.entry)
  785.         set db(diskSize.userSet) 1
  786.     }
  787. }
  788.  
  789.  
  790. ##
  791. ## Safe rawdisk panel
  792. ##
  793.  
  794. set last ""
  795. foreach drive $db(hostRawDisk.drives) {
  796.     set panel(rawDisk_${drive}.title) {Rawdisk Permissions Setting}
  797.     set panel(rawDisk_${drive}.init) RawDisk_Init
  798.     set panel(rawDisk_${drive}.activate) RawDisk_Activate
  799.     set panel(rawDisk_${drive}.deactivate) RawDisk_Deactivate
  800.     if {$last != ""} {
  801.         set panel(${last}.next) rawDisk_${drive}
  802.     }
  803.     set last rawDisk_${drive}
  804.     set panel(rawDisk_${drive}.next) cdrom
  805.     set panel(rawDisk_${drive}.text) "The IDE drive /dev/$drive has been detected on your system. Please select which partition(s) you want the virtual machine to access. If you don't want the virtual machine to use this disk at all, select 'No Access' for all partitions."
  806.     set panel(rawDisk_${drive}.drive) $drive
  807. }
  808.  
  809. proc RawDisk_Init {name} {
  810.     global db panel
  811.  
  812.     set drive $panel(${name}.drive)
  813.     
  814.     frame .${name}.matrix -relief flat
  815.     
  816.     set column 0
  817.     
  818.     foreach header { "Partition" "No\nAccess" "Read\nOnly" "Read\nWrite" "Type" } {
  819.         label .${name}.matrix.h$header -text $header -anchor w -width 6
  820.         grid .${name}.matrix.h$header -in .${name}.matrix -column $column -row 0 \
  821.             -sticky w -pady 2m
  822.         incr column
  823.     }
  824.  
  825.     set row 1
  826.  
  827.     foreach part $db(hostRawDisk.${drive}.partitions) {
  828.         label .${name}.matrix.part${part}_label -text "/dev/${drive}${part}" -anchor w
  829.         grid .${name}.matrix.part${part}_label -in .${name}.matrix -column 0 -row $row \
  830.             -sticky w -padx 1m
  831.         
  832.         radiobutton .${name}.matrix.part${part}_none \
  833.             -variable db(rawDisk.${drive}.${part}.access) \
  834.             -value none
  835.         grid .${name}.matrix.part${part}_none -in .${name}.matrix -column 1 -row $row
  836.  
  837.         radiobutton .${name}.matrix.part${part}_ro \
  838.             -variable db(rawDisk.${drive}.${part}.access) \
  839.             -value ro
  840.         grid .${name}.matrix.part${part}_ro -in .${name}.matrix -column 2 -row $row
  841.  
  842.         radiobutton .${name}.matrix.part${part}_rw \
  843.             -variable db(rawDisk.${drive}.${part}.access) \
  844.             -value rw
  845.         grid .${name}.matrix.part${part}_rw -in .${name}.matrix -column 3 -row $row
  846.         
  847.         label .${name}.matrix.part${part}_type \
  848.             -text $db(hostRawDisk.${drive}.${part}.type)
  849.         grid .${name}.matrix.part${part}_type -in .${name}.matrix -column 4 -row $row \
  850.             -sticky w -padx 1m
  851.  
  852.         incr row
  853.     }
  854.  
  855.     pack .${name}.matrix -in .$name -anchor w -padx 5m
  856. }
  857.  
  858. proc RawDisk_Activate {} {
  859. }
  860.  
  861. # Check if ranges with different access rights overlap
  862. # Return 1 if everything is ok
  863. proc RawDisk_CheckOverlappingRanges {drive} {
  864.     global db
  865.  
  866.     set partitionList $db(hostRawDisk.${drive}.partitions)
  867.     for {set i 0} {$i < [llength $partitionList]} {incr i 1} {
  868.         set partition_i [lindex $partitionList $i]
  869.         for {set j [expr $i + 1]} {$j < [llength $partitionList]} {incr j 1} {
  870.             set partition_j [lindex $partitionList $j]
  871.             if {   ($db(rawDisk.${drive}.${partition_i}.access) != $db(rawDisk.${drive}.${partition_j}.access))
  872.         && [RawDisk_CheckOverlappingRange hostRawDisk.${drive}.${partition_i} hostRawDisk.${drive}.${partition_j}]} {
  873.                 DialogWin .warning "Overlapping partitions" "Partitions $i and $j overlap.\nConsequently, they should have the same access rights.\n\nClick on the OK button, then modify their access rights." {} 0 OK
  874.                 return 0
  875.         }
  876.         }
  877.     }
  878.  
  879.     return 1
  880. }
  881.  
  882. proc RawDisk_Deactivate {} {
  883.     global db panel
  884.     
  885.     set name $panel(current)
  886.     set drive $panel(${name}.drive)
  887.  
  888.     # The check for overlapping ranges has to handle complex dependancy
  889.     # situations like this:
  890.     #
  891.     # partition     access
  892.     # ------------  ------
  893.     # container       RO
  894.     #   contained1    RO
  895.     #   contained2    RO   <- The user sets this to RW
  896.     #
  897.     # In that case, container _and also contained1_ should be set to RW too.
  898.     # That's why I think here is the best place to handle such a case.
  899.  
  900.     # We must perform this check even when the user pressed the "Back" button
  901.     # because he could press on "Finish" just after
  902.     if {[RawDisk_CheckOverlappingRanges $drive] == 0} {
  903.        return retry
  904.     }
  905.  
  906.     set db(rawDisk.${drive}.used) 0
  907.     foreach part $db(hostRawDisk.${drive}.partitions) {
  908.         if {$db(rawDisk.${drive}.${part}.access) != "none"} {
  909.             set db(rawDisk.${drive}.used) 1
  910.             break
  911.         }
  912.     }
  913.  
  914.     return ""
  915. }
  916.  
  917.  
  918.  
  919. ##
  920. ## CDROM panel
  921. ##
  922.  
  923. set panel(cdrom.title) {CD-ROM Device Setting}
  924. set panel(cdrom.init) CDROM_Init
  925. set panel(cdrom.activate) CDROM_Activate
  926. set panel(cdrom.deactivate) CDROM_Deactive
  927. set panel(cdrom.next) floppy
  928.  
  929. if {$db(cdrom.present)} {
  930.     set panel(cdrom.text) {A CD-ROM drive was detected on your host system. Do you want the virtual machine to see and access the CD-ROM?}
  931. } else {
  932.     set panel(cdrom.text) {No CD-ROM was detected on the host. If you have a CD-ROM on the host and you want the virtual machine to use it please enter its location.}
  933. }
  934.  
  935. set panel(cdrom.fileWarnText) {The device you have selected is not present on the host machine. Do you want to continue?}
  936.  
  937. proc CDROM_Init {name} {
  938.     global db
  939.  
  940.     radiobutton .cdrom.disabled -text "CD-ROM Disabled" -variable db(cdrom.wanted) \
  941.         -value 0 -anchor w -padx 5m -command CDROM_Set
  942.     
  943.     radiobutton .cdrom.enabled -text "CD-ROM Enabled" -variable db(cdrom.wanted) \
  944.         -value 1 -anchor w -padx 5m -command CDROM_Set
  945.  
  946.     frame .cdrom.frame -relief flat
  947.     entry .cdrom.frame.fileName -width 20 -relief sunken -bd 2 -textvariable db(cdrom.fileName)
  948.     button .cdrom.frame.browse -text "Browse..." -command CDROM_Browse
  949.  
  950.     pack .cdrom.frame.fileName .cdrom.frame.browse -in .cdrom.frame -side left \
  951.         -pady 1m -padx 1m
  952.     pack .cdrom.disabled .cdrom.enabled .cdrom.frame -in .cdrom -anchor w
  953.  
  954.     CDROM_Set
  955. }
  956.  
  957. proc CDROM_Activate {} {
  958.     focus .cdrom.frame.fileName
  959.     .cdrom.frame.fileName icursor end
  960. }
  961.  
  962. proc CDROM_Deactive {} {
  963.     global db panel
  964.     if {$db(cdrom.wanted) && ![file exists $db(cdrom.fileName)]} {
  965.         set ret [DialogWin .error "Wizard Warning" $panel(cdrom.fileWarnText) \
  966.                      {} 0 No Yes]
  967.         if {$ret == 0} {
  968.             return retry
  969.         } 
  970.     }
  971. }
  972.  
  973. proc CDROM_Set {} {
  974.     global db
  975.     if {$db(cdrom.wanted)} {
  976.         pack .cdrom.frame -in .cdrom -anchor w -padx 15m
  977.     } else {
  978.         pack forget .cdrom.frame
  979.     }
  980. }
  981.  
  982. proc CDROM_Browse {} {
  983.     global db
  984.     set ret [tk_getOpenFile -initialdir /dev]
  985.     if {$ret != ""} {
  986.         set db(cdrom.fileName) $ret
  987.     }
  988. }
  989.  
  990.  
  991. ##
  992. ## Floppy panel
  993. ##
  994.  
  995. set panel(floppy.title) {Floppy Device Setting}
  996. set panel(floppy.init) Floppy_Init
  997. set panel(floppy.activate) Floppy_Activate
  998. set panel(floppy.deactivate) Floppy_Deactive
  999. set panel(floppy.next) networking
  1000.  
  1001. if {$db(floppy.present)} {
  1002.     set panel(floppy.text) {A floppy drive was detected on your host system. Do you want the virtual machine to see and access the floppy?}
  1003. } else {
  1004.     set panel(floppy.text) {No floppy was detected on the host. If you have a floppy on the host and you want the virtual machine to use it please enter its location.}
  1005. }
  1006.  
  1007. set panel(floppy.fileWarnText) {The device you have selected is not present on the host machine. Do you want to continue?}
  1008.  
  1009.  
  1010. proc Floppy_Init {name} {
  1011.     global db
  1012.  
  1013.     radiobutton .floppy.disabled -text "Floppy Disabled" -variable db(floppy.wanted) \
  1014.         -value 0 -anchor w -padx 5m -command Floppy_Set
  1015.     
  1016.     radiobutton .floppy.enabled -text "Floppy Enabled" -variable db(floppy.wanted) \
  1017.         -value 1 -anchor w -padx 5m -command Floppy_Set
  1018.  
  1019.     frame .floppy.frame -relief flat
  1020.     entry .floppy.frame.fileName -width 20 -relief sunken -bd 2 -textvariable db(floppy.fileName)
  1021.     button .floppy.frame.browse -text "Browse..." -command Floppy_Browse
  1022.  
  1023.     pack .floppy.frame.fileName .floppy.frame.browse -in .floppy.frame -side left \
  1024.         -pady 1m -padx 1m
  1025.     pack .floppy.disabled .floppy.enabled .floppy.frame -in .floppy -anchor w
  1026.  
  1027.     Floppy_Set
  1028. }
  1029.  
  1030. proc Floppy_Activate {} {
  1031.     focus .floppy.frame.fileName
  1032.     .floppy.frame.fileName icursor end
  1033. }
  1034.  
  1035. proc Floppy_Deactive {} {
  1036.     global db panel
  1037.     if {$db(floppy.wanted) && ![file exists $db(floppy.fileName)]} {
  1038.         set ret [DialogWin .error "Wizard Warning" $panel(floppy.fileWarnText) \
  1039.                      {} 0 No Yes]
  1040.         if {$ret == 0} {
  1041.             return retry
  1042.         } 
  1043.     }
  1044. }
  1045.  
  1046. proc Floppy_Set {} {
  1047.     global db
  1048.     if {$db(floppy.wanted)} {
  1049.         pack .floppy.frame -in .floppy -anchor w -padx 15m
  1050.     } else {
  1051.         pack forget .floppy.frame
  1052.     }
  1053. }
  1054.  
  1055. proc Floppy_Browse {} {
  1056.     global db
  1057.     set ret [tk_getOpenFile -initialdir /dev]
  1058.     if {$ret != ""} {
  1059.         set db(floppy.fileName) $ret
  1060.     }
  1061. }
  1062.  
  1063.  
  1064. ##
  1065. ## Networking panel
  1066. ##
  1067.  
  1068. set panel(networking.title) {Networking Setting}
  1069. set panel(networking.init) Networking_Init
  1070. set panel(networking.activate) <null>
  1071. set panel(networking.deactivate) <null>
  1072. set panel(networking.next) confirm
  1073.  
  1074. set panel(networking.text) {A virtual machine can be connected to other systems through standard networking protocols. Please select the networking option for your virtual machine.}
  1075.  
  1076. set panel(networking.noneText) {Your virtual machine will be a stand-alone system. It will not be networked and therefore not able to communicate with other systems.}
  1077. set panel(networking.bridgedText) {Your virtual machine will be bridged to the outside network. It will appear as a separate machine on the host machine's subnet. The operating system will require proper network configuration. Please contact your network administrator in order to get proper settings.}
  1078. set panel(networking.hostOnlyText) {Your virtual machine will only be able to talk to the host operating system through an internal virtual network.}
  1079.  
  1080. proc Networking_Init {name} {
  1081.     global install panel
  1082.  
  1083.     radiobutton .networking.none -text "No Networking" -variable db(networking) \
  1084.         -value none -anchor w -padx 5m -command Networking_Set
  1085.     
  1086.     radiobutton .networking.bridged -text "Bridged Networking" -variable db(networking) \
  1087.         -value bridged -anchor w -padx 5m -command Networking_Set
  1088.     
  1089.     pack .networking.none .networking.bridged -in .networking -anchor w
  1090.     
  1091.     if {[info exists install(HostOnly)]} {
  1092.         radiobutton .networking.hostOnly -text "Host-only Networking" \
  1093.             -variable db(networking) -command Networking_Set \
  1094.             -value hostOnly -anchor w -padx 5m 
  1095.         pack .networking.hostOnly -in .networking -anchor w
  1096.     }
  1097.     
  1098.     message .networking.msg2 -justify left -text $panel(networking.noneText) -width $panel(width) -pady 5m
  1099.     pack .networking.msg2 -in .networking -anchor w
  1100. }
  1101.  
  1102. proc Networking_Set {} {
  1103.     global db panel
  1104.     switch $db(networking) {
  1105.         none     { .networking.msg2 configure -text $panel(networking.noneText) }
  1106.         bridged  { .networking.msg2 configure -text $panel(networking.bridgedText) }
  1107.         hostOnly { .networking.msg2 configure -text $panel(networking.hostOnlyText) }
  1108.     }
  1109. }
  1110.  
  1111.  
  1112. ##
  1113. ## Confirmation panel
  1114. ##
  1115.  
  1116. set panel(confirm.title) {Confirmation}
  1117. set panel(confirm.init) Confirm_Init
  1118. set panel(confirm.activate) Confirm_Activate
  1119. set panel(confirm.deactivate) Confirm_Deactivate
  1120. set panel(confirm.next) <null>
  1121. set panel(confirm.text) {Congratulations! You have finished configuring your virtual machine. Please review the following information and make sure that all is correct. You can go back in order to change these settings.}
  1122.  
  1123. set panel(confirm.configText) {You have configured the following virtual machine:}
  1124. set panel(confirm.fileText) {You can fine tune these settings and configure more options (like the use of parallel and serial ports) at any time using the VMware Configuration Editor.
  1125.  
  1126. By clicking on the "Done" button, the following will be created:}
  1127.  
  1128. set panel(confirm.font) *-courier-bold-r-normal--12-120-*-*-*-*-*-*
  1129.  
  1130. proc Confirm_Init {name} {
  1131.     global panel
  1132.     
  1133.     message .confirm.configMsg  -justify left -width $panel(width) -pady 3m -text $panel(confirm.configText) 
  1134.     message .confirm.configInfo -justify left -width $panel(width) -padx 5m -font $panel(confirm.font)
  1135.     message .confirm.fileMsg    -justify left -width $panel(width) -pady 3m -text $panel(confirm.fileText)
  1136.     message .confirm.fileInfo   -justify left -width $panel(width) -padx 5m -font $panel(confirm.font)
  1137.     
  1138.     pack .confirm.configMsg .confirm.configInfo .confirm.fileMsg .confirm.fileInfo -in .confirm -anchor w
  1139. }
  1140.  
  1141. proc Confirm_Activate {} {
  1142.     global db
  1143.     
  1144.     .nav.next configure -state disabled -default normal
  1145.     .nav.finish configure -text Done -default active -underline 0
  1146.  
  1147.     bind . <KeyPress-Return> Save
  1148.     bind . <Alt-KeyPress-d> Save
  1149.     bind . <Alt-KeyPress-f> {}
  1150.     bind . <Alt-KeyPress-n> {}
  1151.  
  1152.     # .confirm.configMsg configure -text "You have configured the following virtual machine to run $db(OS.name)."
  1153.     
  1154.     set config "$db(memorySize) megabytes of RAM"
  1155.  
  1156.     if {$db(diskType) == "file"} {
  1157.         set config "${config}\n$db(diskSize) megabytes persistent hard disk"
  1158.     } else {
  1159.         foreach drive $db(hostRawDisk.drives) {
  1160.             if {$db(rawDisk.${drive}.used)} {
  1161.                 set config "${config}\nrawdisk /dev/$drive"
  1162.             }
  1163.         }
  1164.     }
  1165.  
  1166.     if {$db(cdrom.wanted)} {
  1167.         set config "${config}\n1 CD-ROM drive"
  1168.     }
  1169.  
  1170.     if {$db(floppy.wanted)} {
  1171.         set config "${config}\n1 floppy drive"
  1172.     }
  1173.  
  1174.     if {$db(networking) == "bridged"} {
  1175.         set config "${config}\nbridged networking"
  1176.     } elseif {$db(networking) == "hostOnly"} {
  1177.         set config "${config}\nhost only networking"
  1178.     }
  1179.     
  1180.     .confirm.configInfo configure -text $config
  1181.  
  1182.     set files "$db(directory)"
  1183.     set files "$files\n$db(directory)$db(OS.name).cfg"
  1184.     if {$db(diskType) == "file"} {
  1185.         set files "$files\n$db(directory)$db(OS.name).dsk"
  1186.     } else {
  1187.         foreach drive $db(hostRawDisk.drives) {
  1188.             if {$db(rawDisk.${drive}.used)} {
  1189.                 set files "$files\n$db(directory)$db(OS.name).${drive}"
  1190.             }
  1191.         }
  1192.     }
  1193.     set files "$files\n$db(directory)$db(OS.name).nvram"
  1194.     set files "$files\n$db(directory)$db(OS.name).log"
  1195.     
  1196.     .confirm.fileInfo configure -text $files
  1197. }
  1198.  
  1199. proc Confirm_Deactivate {} {
  1200.     .nav.next configure -state normal -default active
  1201.     .nav.finish configure -text Finish -default normal -underline 0
  1202.     bind . <KeyPress-Return> Next
  1203.     bind . <Alt-KeyPress-n> Next
  1204.     bind . <Alt-KeyPress-f> Finish
  1205.     bind . <Alt-KeyPress-d> {}
  1206. }
  1207.  
  1208.  
  1209. ############################################################
  1210. ###
  1211. ### navigation bar
  1212. ###
  1213. ############################################################
  1214.  
  1215. frame .nav -width $panel(width) -height 2i -relief flat
  1216.  
  1217. button .nav.help   -width 8 -text "Help"   -command Help   -underline 0
  1218. button .nav.cancel -width 8 -text "Cancel" -command Cancel -underline 0
  1219. button .nav.prev   -width 8 -text "< Prev" -command Prev   -underline 2
  1220. button .nav.next   -width 8 -text "Next >" -command Next   -underline 0 -default active
  1221. button .nav.finish -width 8 -text "Finish" -command Finish -underline 0 -default normal
  1222.  
  1223. focus .nav.next
  1224.  
  1225. bind . <KeyPress-Return> Next
  1226.  
  1227. bind . <Alt-KeyPress-h> Help
  1228. bind . <Alt-KeyPress-c> Cancel
  1229. bind . <Alt-KeyPress-p> Prev
  1230. bind . <Alt-KeyPress-n> Next
  1231. bind . <Alt-KeyPress-f> Finish
  1232.  
  1233. pack .nav.help .nav.cancel .nav.prev .nav.next .nav.finish -in .nav -side left -padx 1m -pady 2m
  1234.  
  1235.  
  1236. proc Help {} {
  1237.     global help panel
  1238.  
  1239.     if {[string match {rawDisk_hd[a-d]} $panel(current)]
  1240.         || ($panel(current) == "safeDisk")} {
  1241.         set p rawDisk
  1242.     } else {
  1243.         set p $panel(current)
  1244.     }
  1245.     
  1246.     helpWindow .help $panel($p.title) $help($p.text) $help($p.urls)
  1247. }
  1248.  
  1249. proc Cancel {} {
  1250.     global option
  1251.     if {$option(outputFileName)} {
  1252.         puts "file:"
  1253.     }
  1254.     exit
  1255. }
  1256.  
  1257. proc Activate {newPanel} {
  1258.     global panel
  1259.     set panel(current) $newPanel
  1260.     focus .nav.next
  1261.     if {$panel($panel(current).activate) != "<null>"} {
  1262.         $panel($panel(current).activate)
  1263.     }    
  1264.     pack .$panel(current) -anchor w -padx 5m
  1265.     if {[winfo exists .help]} {
  1266.         Help
  1267.     }
  1268. }
  1269.  
  1270. proc Deactivate {} {
  1271.     global panel started
  1272.     set started 0
  1273.     set ret ""
  1274.     if {$panel($panel(current).deactivate) != "<null>"} {
  1275.         if {[$panel($panel(current).deactivate)] == "retry"} {
  1276.             return retry
  1277.         }
  1278.     }
  1279.     pack forget .$panel(current)
  1280. }
  1281.  
  1282. proc Next {} {
  1283.     global panel
  1284.     if {[Deactivate] != "retry"} {
  1285.         set panel(stack) [linsert $panel(stack) 0 $panel(current)]
  1286.         Activate $panel($panel(current).next)
  1287.     }
  1288. }
  1289.  
  1290. proc Prev {} {
  1291.     global panel
  1292.     if {[Deactivate] != "retry"} {
  1293.         set next [lindex $panel(stack) 0]
  1294.         set panel(stack) [lreplace $panel(stack) 0 0]
  1295.         Activate $next
  1296.     }
  1297. }
  1298.  
  1299. proc Finish {} {
  1300.     global panel
  1301.     if {$panel(current) == "confirm"} {
  1302.         # The user clicked on the "Done" button
  1303.         Save
  1304.     } else {
  1305.         if {[Deactivate] != "retry"} {
  1306.             set panel(stack) [linsert $panel(stack) 0 $panel(current)]
  1307.             Activate confirm
  1308.         }
  1309.     }
  1310. }
  1311.  
  1312.  
  1313.  
  1314. ############################################################
  1315. ###
  1316. ### save configuration
  1317. ###
  1318. ### XXX We should ensure that the user will not use more
  1319. ### than 3 or 4 (depending on the CDROM choice) raw disks
  1320. ###
  1321. ############################################################
  1322.  
  1323. proc Save {} {
  1324.     global db install option
  1325.  
  1326.     # Create the list of used hard drives
  1327.     set usedDrives {}
  1328.     foreach drive $db(hostRawDisk.drives) {
  1329.     if {$db(rawDisk.${drive}.used)} {
  1330.         lappend usedDrives $drive
  1331.     }
  1332.     }
  1333.  
  1334.     ##
  1335.     ## sanity checks / make directory
  1336.     ##
  1337.     
  1338.     if {[file exists $db(directory)]} {
  1339.         if {![file isdirectory $db(directory)]} {
  1340.             DialogWin .error "Configuration Wizard Error" \
  1341.                 "$db(directory) already exists and it is not a directory." {} 0 OK
  1342.             return
  1343.         }
  1344.         
  1345.         if {$db(diskType) == "file"} {
  1346.             if {[file exists [file join $db(directory) $db(OS.name).dsk]]} {
  1347.                 if {[DialogWin .error "File Exists" \
  1348.                          "$db(directory)$db(OS.name).dsk exists, overwrite it?" {} 1 Yes No] == 1} {
  1349.                     return
  1350.                 }
  1351.                 file delete [file join $db(directory) $db(OS.name).dsk]
  1352.             }
  1353.         } else {
  1354.             foreach drive $usedDrives {
  1355.         if {[file exists [file join $db(directory) "$db(OS.name).$drive"]]} {
  1356.             if {[DialogWin .error "File Exists" \
  1357.                  "$db(directory)$db(OS.name).$drive exists, overwrite it?" \
  1358.                  {} 1 Yes No] == 1} {
  1359.             return
  1360.             }
  1361.         }
  1362.             }
  1363.         }
  1364.  
  1365.         if {[file exists [file join $db(directory) $db(OS.name).cfg]]} {
  1366.             if {[DialogWin .error "File Exists" \
  1367.                      "$db(directory)$db(OS.name).cfg exists, overwrite it?" {} 1 Yes No] == 1} {
  1368.                 return
  1369.             }
  1370.         }
  1371.     } else {        
  1372.     # The directory does not exist, create it
  1373.         if {[catch {file mkdir $db(directory)} err]} {
  1374.             DialogWin .error "Configuration Wizard Error" \
  1375.                 "Failed to make $db(directory): $err" {} 0 OK
  1376.             return
  1377.         }
  1378.     }
  1379.     
  1380.  
  1381.     ##
  1382.     ## make disk
  1383.     ##
  1384.  
  1385.     if {$db(diskType) == "file"} {
  1386.         set heads 15
  1387.         set secs 63
  1388.         set cyls [expr {($db(diskSize)*2048) / ($heads*$secs)}] 
  1389.         
  1390.         if {[CreateCOWDisk $db(directory)/$db(OS.name).dsk $cyls $heads $secs]} {
  1391.             return
  1392.         }
  1393.     } else {
  1394.         foreach drive $usedDrives {
  1395.         RawDisk_Save $drive $db(directory)$db(OS.name).$drive
  1396.         }
  1397.     }
  1398.     
  1399.     ##
  1400.     ## make config file
  1401.     ##
  1402.  
  1403.     if {[catch {set fd [open [file join $db(directory) $db(OS.name).cfg] w]} err]} {
  1404.         DialogWin .error "Configuration Wizard Error" \
  1405.             "Failed to open $db(directory)$db(OS.name).cfg: $err" {} 0 OK
  1406.         return
  1407.     }
  1408.  
  1409.     if {[info exists install(vmware.fullpath)]} {
  1410.         puts $fd "\#!$install(vmware.fullpath)"
  1411.     }
  1412.     
  1413.     set prefixes { "ide0:0" "ide0:1" "ide1:0" "ide1:1" }
  1414.  
  1415.     if {$db(diskType) == "file"} {
  1416.         # Get the next prefix
  1417.     set prefix [lindex $prefixes 0]
  1418.     set prefixes [lreplace $prefixes 0 0]
  1419.  
  1420.         puts $fd "\n\# Virtual hard disk on primary master"
  1421.         puts $fd "${prefix}.present = TRUE"
  1422.         puts $fd "${prefix}.fileName = $db(directory)$db(OS.name).dsk"
  1423.         puts $fd "${prefix}.deviceType = ata-hardDisk"
  1424.         puts $fd "${prefix}.mode = persistent"
  1425.     } else {
  1426.         # Compute the number of availbale IDE slots for hard drives
  1427.     if {$db(cdrom.wanted)} {
  1428.            set maxDisk 3
  1429.         } else {
  1430.            set maxDisk 4
  1431.         }
  1432.  
  1433.         # Restrict the number of hard drives to declare in the config file
  1434.         if {[llength $usedDrives] > $maxDisk} {
  1435.             DialogWin .error "Configuration Wizard Warning" "There are not enough IDE slots in the Virtual Machine to place all your hard drives.\n\nAlthough a safe raw disk file will be generated for all your hard drives, the Virtual Machine configuration file will only use the first $maxDisk of them." {} 0 OK
  1436.             set cfgDrives [lrange $usedDrives 0 [expr $maxDisk - 1]]
  1437.     } else {
  1438.             set cfgDrives $usedDrives
  1439.     }
  1440.  
  1441.         foreach drive $cfgDrives {
  1442.         # Get the next prefix
  1443.         set prefix [lindex $prefixes 0]
  1444.         set prefixes [lreplace $prefixes 0 0]
  1445.  
  1446.         puts $fd "\n\# Raw hard disk /dev/$drive"
  1447.         puts $fd "${prefix}.present = TRUE"
  1448.         puts $fd "${prefix}.fileName = $db(directory)$db(OS.name).$drive"
  1449.         puts $fd "${prefix}.deviceType = rawDisk"
  1450.         puts $fd "${prefix}.mode = persistent"
  1451.         }
  1452.     }
  1453.     
  1454.     if {$db(cdrom.wanted)} {
  1455.         if {$db(diskType) == "part"} { 
  1456.         # Get the next prefix
  1457.         set prefix [lindex $prefixes 0]
  1458.         set prefixes [lreplace $prefixes 0 0]
  1459.         } else {
  1460.         # Get the next prefix
  1461.         set prefix [lindex $prefixes 0]
  1462.         set prefixes [lreplace $prefixes 0 0]
  1463.         # Get the next prefix
  1464.         set prefix [lindex $prefixes 0]
  1465.         set prefixes [lreplace $prefixes 0 0]
  1466.         }
  1467.         
  1468.         puts $fd "\n\# CD-ROM"
  1469.         puts $fd "${prefix}.present = TRUE"
  1470.         puts $fd "${prefix}.fileName = $db(cdrom.fileName)"
  1471.         puts $fd "${prefix}.deviceType = atapi-cdrom"
  1472.     } else {
  1473.         puts $fd "\n\# No cdrom installed"
  1474.     }
  1475.     
  1476.     if {$db(floppy.wanted)} {
  1477.         puts $fd "\n\# Floppy"
  1478.         puts $fd "floppy0.present = TRUE"
  1479.         puts $fd "floppy0.fileName = $db(floppy.fileName)"
  1480.     } else {
  1481.         puts $fd "\n\# No floppy installed"
  1482.         puts $fd "floppy0.present = FALSE"
  1483.     }
  1484.  
  1485.     switch $db(networking) {
  1486.         "none" {
  1487.             puts $fd "\n\# No networking installed"            
  1488.         }
  1489.         "bridged" {
  1490.             puts $fd "\n\# Networking bridged to real ethernet"            
  1491.             puts $fd "ethernet0.present = TRUE"
  1492.             puts $fd "ethernet0.connectionType = bridged"
  1493.         }
  1494.         "hostOnly" {
  1495.             puts $fd "\n\# Networked to host only subnet "            
  1496.             puts $fd "ethernet0.present = TRUE"
  1497.             puts $fd "ethernet0.connectionType = hostOnly"
  1498.         }
  1499.     }
  1500.  
  1501.     puts $fd "\n\# Memory size"
  1502.     puts $fd "memsize = $db(memorySize)"
  1503.  
  1504.     puts $fd "\n\# Nvram"
  1505.     puts $fd "nvram = $db(directory)$db(OS.name).nvram"
  1506.  
  1507.     puts $fd "\n\# Log file"
  1508.     puts $fd "log.fileName = $db(directory)$db(OS.name).log"
  1509.  
  1510.     puts $fd "\n\# Hints"
  1511.     if {$db(OS) != "other"} {
  1512.         puts $fd "hint.guestOS = $db(OS)"
  1513.     } else {
  1514.         puts $fd "hint.guestOS = $db(OS):$db(OS.name)"
  1515.     }
  1516.     
  1517.     if {$db(OS) == "win2000"} {
  1518.         puts $fd "\n\# SVGA"
  1519.         puts $fd "PciSvgaDynamic = TRUE"
  1520.     }
  1521.  
  1522.     exec $db(helper.chmod) u+x $db(directory)/$db(OS.name).cfg
  1523.     
  1524.     close $fd
  1525.     
  1526.     
  1527.     ##
  1528.     ## all done
  1529.     ##
  1530.  
  1531.     if {$option(outputFileName)} {
  1532.         puts "file:$db(directory)$db(OS.name).cfg"
  1533.     }
  1534.     
  1535.     exit
  1536. }
  1537.  
  1538. proc CreateCOWDisk {fileName cyls heads secs} {
  1539.     set sectorSize         512
  1540.     set numLeafEntries     512
  1541.     set defaultGran        32 
  1542.     set defaultRootOffset  4 
  1543.  
  1544.     set numSectors [expr {$cyls * $heads * $secs}]
  1545.     set leafCoverage [expr {$numLeafEntries * $defaultGran}]
  1546.     set numRootEntries [expr {int(ceil(($numSectors*1.0) / $leafCoverage))}]
  1547.     set numRootSectors [expr {int(ceil(($numRootEntries*4.0) / $sectorSize))}]
  1548.     set size [expr {($numRootSectors+$defaultRootOffset) * $sectorSize}]
  1549.     set generation [random 1073741824]
  1550.  
  1551.     set header [binary format "a4iiiiiiiiii@1060ia60a512i@$size" \
  1552.                     "COWD" \
  1553.                     1 \
  1554.                     3 \
  1555.                     $numSectors \
  1556.                     $defaultGran \
  1557.                     $defaultRootOffset \
  1558.                     $numRootEntries \
  1559.                     0 \
  1560.                     $cyls \
  1561.                     $heads \
  1562.                     $secs \
  1563.                     $generation \
  1564.                     "nothing" \
  1565.                     "nothing" \
  1566.                     $generation ]
  1567.  
  1568.     if {[set fd [open $fileName w]] < 0} {
  1569.         return 1
  1570.     }
  1571.  
  1572.     puts -nonewline $fd $header
  1573.     close $fd
  1574.     return 0
  1575. }
  1576.  
  1577.  
  1578. ############################################################
  1579. ###
  1580. ### window
  1581. ###
  1582. ############################################################
  1583.  
  1584. image create photo logoimage -file images/logo.gif
  1585. canvas .logo -width 1.5i -height 6i -background white -yscrollincrement 1
  1586. .logo create image 1.5i 3i -anchor e -image logoimage -tag egg 
  1587. .logo bind egg <Control-ButtonPress-3> startLogo
  1588. .logo bind egg <ButtonPress-1> gotoWebsite
  1589.  
  1590. set started 0
  1591.  
  1592. proc gotoWebsite {} {
  1593.     global db
  1594.  
  1595.     if [catch {exec $db(helper.netscape) -remote "openURL(www.vmware.com, vmware-window, raise)" >& /dev/null}] {
  1596.         if [catch {exec $db(helper.netscape) www.vmware.com >& /dev/null &}] {
  1597.             DialogWin .error "Help Error" "Can't open $db(helper.netscape)." {} 0 OK
  1598.         }
  1599.     }
  1600. }
  1601.  
  1602. proc startLogo {} {
  1603.     global increment started
  1604.  
  1605.     if {!$started} {
  1606.         set increment -1
  1607.         set started 1
  1608.         moveLogo
  1609.     } elseif {$started > 5} {
  1610.         set started 0
  1611.         moveLogo
  1612.         DialogWin .winner "Configuration Wizard" "mendel\nbugnion\ndevine\nedward\nyoel\npatrick\nbhlim\nluigi\nbennett\njohnh\nmnelson\nsam\nhpreg\nchris" {} 0 OK
  1613.     } else {
  1614.         incr started
  1615.         set increment [expr {-1 * ($increment + $increment)}]    
  1616.     }
  1617.  
  1618. }
  1619.  
  1620. proc moveLogo {} {
  1621.     global increment started
  1622.     if {!$started} {
  1623.         .logo yview moveto 0
  1624.     } else {
  1625.         .logo yview scroll $increment units
  1626.         after 30 moveLogo
  1627.     }
  1628. }
  1629.  
  1630. wm title . "VMware for Linux Configuration Wizard"
  1631.  
  1632. pack .logo -fill y -side left
  1633. pack .nav -side bottom -padx 5m
  1634.  
  1635. NewPanel welcome
  1636. NewPanel os 
  1637. NewPanel dir
  1638. NewPanel diskType
  1639. NewPanel diskSize
  1640.  
  1641. foreach drive $db(hostRawDisk.drives)  {
  1642.     NewPanel rawDisk_${drive}
  1643. }
  1644.  
  1645. NewPanel cdrom
  1646. NewPanel floppy
  1647. NewPanel networking
  1648. NewPanel confirm
  1649.  
  1650. if {[info exists option(safedisk)]} {
  1651.     set drive $option(safedisk)
  1652.     
  1653.     GetRawDiskInfo $drive
  1654.  
  1655.  
  1656.     if {![info exists db(hostRawDisk.$option(safedisk).partitions)]} {
  1657.           puts "$drive is not a valid drive"
  1658.       exit
  1659.     }
  1660.     
  1661.     set panel(safeDisk.title) {Rawdisk Permissions Setting}
  1662.     set panel(safeDisk.init) RawDisk_Init
  1663.     set panel(safeDisk.activate) SafeDisk_Activate
  1664.     set panel(safeDisk.deactivate) SafeDisk_Deactivate
  1665.     set panel(safeDisk.next) cdrom
  1666.     set panel(safeDisk.text) "The IDE drive /dev/$drive has been detected on your system. Please select which partition(s) you want the virtual machine to access."
  1667.     set panel(safeDisk.drive) $drive
  1668.     
  1669.     proc SafeDisk_Activate {} {
  1670.         .nav.prev configure -state disabled -default normal
  1671.         .nav.next configure -state disabled -default normal
  1672.         .nav.finish configure -text Done -default active -underline 0
  1673.     }
  1674.     
  1675.     proc SafeDisk_Deactivate {} {
  1676.         global option
  1677.  
  1678.         set fileName [tk_getSaveFile -initialfile "safe_$option(safedisk)" \
  1679.                          -title "Save File As"]
  1680.         if {$fileName == ""} {
  1681.             return retry
  1682.         }
  1683.  
  1684.         RawDisk_Save $option(safedisk) $fileName
  1685.         exit
  1686.     }
  1687.  
  1688.     NewPanel safeDisk
  1689.     set panel(current) safeDisk
  1690. }
  1691.  
  1692. Activate $panel(current)
  1693.  
  1694. # Update the appearance of the (hidden) main window
  1695. update
  1696.  
  1697. # Show the main window
  1698. wm deiconify .
  1699.  
  1700. # Enter the main window event loop
  1701. tkwait window .
  1702. exit
  1703.