/[gli]/branches/overhaul/src/fe/dialog/gli-dialog.py
Gentoo

Contents of /branches/overhaul/src/fe/dialog/gli-dialog.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1745 - (show annotations) (download) (as text)
Sat Mar 3 20:58:14 2007 UTC (11 years, 7 months ago) by codeman
File MIME type: text/x-python
File size: 101998 byte(s)
fix boot device detection.  was only looking at drives with mounts b4. untested.
fixed silly bug in save filename
adding back in set_etc_portage to install process.
putting an exit(0) back in trunk just because.

1 #!/usr/bin/python
2 # Copyright 1999-2005 Gentoo Foundation
3 # This source code is distributed under the terms of version 2 of the GNU
4 # General Public License as published by the Free Software Foundation, a copy
5 # of which can be found in the main directory of this project.
6
7 import sys
8 sys.path.append("../..")
9
10 import dialog
11 import GLIException, GLIInstallProfile, GLIClientController, GLIUtility, Partitioning
12
13 import string, copy, time, re, glob, os, platform
14 import gettext
15 try:
16 gettext.install('gli-dialog', './languages')
17 translator = gettext.translation('gli-dialog', './languages')
18 _ = translator.gettext
19 except:
20 _ = gettext.gettext
21
22
23 # ------------------------------------------------------------------
24 class GLIDialog(object):
25 def __init__(self):
26 self._d = dialog.Dialog()
27 self._install_profile = GLIInstallProfile.InstallProfile()
28 self._cc = GLIClientController.GLIClientController(self._install_profile,pretend=False,verbose=True) #FIXME change to False
29
30 self._DLG_OK = 0
31 self._DLG_YES = 0
32 self._DLG_CANCEL = 1
33 self._DLG_NO = 1
34 self._DLG_ESC = 2
35 self._DLG_ERROR = 3
36 self._DLG_EXTRA = 4
37 self._DLG_HELP = 5
38 self._d.setBackgroundTitle("Gentoo Linux Installer")
39 self.profile_xml_file = None
40 self.advanced_mode = True
41 self.networkless = False
42 self.just_starting = 1
43
44
45 ############ ACCESSOR FUNCTIONS #############
46 def _dmenu_list_to_choices(self, list):
47 choices = []
48 for i in range(0, len(list)):
49 choices.append((str(i + 1), list[i]))
50 return choices
51
52 def install_profile(self):
53 return self._install_profile
54
55 def fatal(self,message):
56 self._d.msgbox(message)
57 sys.exit(0)
58
59 ############ QUESTION FUNCTIONS #################
60 def show_welcome_screen(self):
61
62 welcome_string = _(u"""Welcome to the Gentoo Linux Installer! This program will help install Gentoo on your computer.
63 Before proceeding please thoroughly read the Gentoo Installation Handbook available at
64 http://www.gentoo.org/doc/en/handbook/index.xml \n
65 Press OK to continue""")
66 self._d.msgbox(welcome_string, height=25, width=78, title=_(u"Welcome"))
67
68 def ask_advanced_mode(self):
69 #Set the Yes/No labels.
70 self._d.add_persistent_args(["--yes-label", _(u"Standard")])
71 self._d.add_persistent_args(["--no-label",_(u"Advanced")])
72 advanced_string = _(u"""This installer has two modes, an advanced mode for those knowledgable with the inner details of their computer and a standard mode where many of the defaults will be chosen for the user for simplicity and to speed up the install process. The advanced mode offers full customizability and is required for generating profiles to be used other computers. \nThe advanced mode is recommended by the developers.
73 """)
74 if self._d.yesno(advanced_string, width=55, height=15) == self._DLG_NO:
75 self.advanced_mode = True
76 else:
77 self.advanced_mode = False
78
79 def ask_networkless(self):
80 networkless_string = _(u"Do you want to do a networkless installation? This will limit the customizability of your install due to the limitations of the LiveCD. For example, choosing networkless will set your installation stage, portage snapshot, and limit your extra packages selections. NOTE: It is easily possible to do a networkless installation on a machine with an active Internet connection; in fact this may result in the fastest installations for many users.")
81 #Change the Yes/No buttons
82 self._d.add_persistent_args(["--yes-label", _(u"Networkless")])
83 self._d.add_persistent_args(["--no-label", _(u"Internet enabled")])
84 if self._d.yesno(networkless_string, width=65, height=20) == self._DLG_YES:
85 self.networkless = True
86 try:
87 self._install_profile.set_grp_install(None, True, None)
88 self._install_profile.set_install_stage(None, "3", None)
89 self._install_profile.set_dynamic_stage3(None, True, None)
90 self._install_profile.set_portage_tree_sync_type(None,"snapshot", None)
91 cd_snapshot_uri = GLIUtility.get_cd_snapshot_uri()
92 self._install_profile.set_portage_tree_snapshot_uri(None, cd_snapshot_uri, None)
93 self._install_profile.set_kernel_source_pkg(None, "livecd-kernel", None)
94 self._install_profile.set_cron_daemon_pkg(None, "vixie-cron", None)
95 self._install_profile.set_logging_daemon_pkg(None,"syslog-ng", None)
96 except:
97 self._d.msgbox(_(u"ERROR: Could not set networkless information in the profile"))
98 else:
99 self.networkless = False
100
101 def ask_load_profile(self):
102 #Reset the Yes/No labels.
103 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
104 self._d.add_persistent_args(["--no-label",_(u"No")])
105 #Ask
106 while 1:
107 string = _(u"""
108 All of the installation settings are stored in an XML file, which we call the InstallProfile. If you have a previously-created profile, you can load it now
109 for use in this installation.
110 Do you have a previously generated profile for the installer?
111 """)
112 if self._d.yesno(string, width=70, height=15, defaultno=1) == self._DLG_YES:
113 code, self.profile_xml_file = self._d.inputbox(_(u"Enter the filename of the XML file"))
114 if code != self._DLG_OK:
115 break
116 if GLIUtility.is_file(self.profile_xml_file):
117 break
118 self._d.msgbox(_(u"Cannot open file %s") % self.profile_xml_file, height=7, width=50)
119 self.profile_xml_file = None
120 continue
121 else:
122 break
123 if self.profile_xml_file != None:
124 self._install_profile.parse(self.profile_xml_file)
125 self.run_phase5()
126 sys.exit(0)
127
128 ############ STAGE1 FUNCTIONS #################
129
130 def set_arch_template(self):
131 subarches = { 'i386': 'x86', 'i486': 'x86', 'i586': 'x86', 'i686': 'x86', 'x86_64': 'amd64', 'parisc': 'hppa' }
132 arch = platform.machine()
133 if arch in subarches:
134 arch = subarches[arch]
135 self._arch = arch
136
137 def set_verbose(self):
138 #Don't show unless advanced.
139 if self.advanced_mode:
140 #Change the Yes/No buttons back.
141 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
142 self._d.add_persistent_args(["--no-label", _(u"No")])
143 if self._d.yesno(_(u"Do you want debugging output enabled during the install? This is mainly meant to help the developers debug any bugs."), width=60) == self._DLG_YES:
144 self._install_profile.set_verbose(None, True, None)
145 else:
146 self._install_profile.set_verbose(None, False, None)
147
148 def set_client_networking(self):
149 if self.networkless: return
150 if GLIUtility.ping("www.gentoo.org"): #If an active connection exists, ignore this step.
151 return
152
153 device_list = GLIUtility.get_eth_devices()
154
155 choice_list = []
156 for device in device_list:
157 choice_list.append((device, GLIUtility.get_interface_realname(device)))
158 choice_list.append((_(u"Other"),_(u"Type your own.")))
159 cnet_string1 = _(u"In order to complete most installs, an active Internet connection is required. Listed are the network devices already detected. In this step you will need to setup one network connection for GLI to use to connect to the Internet. If your desired device does not show up in the list, you can select Other and input the device name manually.")
160 code, interface = self._d.menu(cnet_string1, width=75, height=20, choices=choice_list)
161
162 if interface == _(u"Other"):
163 code, interface = self._d.inputbox(_(u"Enter the interface (NIC) you would like to use for installation (e.g. eth0):"))
164 if code != self._DLG_OK:
165 return
166
167 dhcp_options = ""
168
169 #Change the Yes/No buttons to new labels for this question.
170 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
171 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
172 cnet_string2 = _(u"To setup your network interface, you can either use DHCP if enabled, or manually enter your network information.\n DHCP (Dynamic Host Configuration Protocol) makes it possible to automatically receive networking information (IP address, netmask, broadcast address, gateway, nameservers etc.). This only works if you have a DHCP server in your network (or if your provider provides a DHCP service). If you do not, you must enter the information manually. Please select your networking configuration method:")
173 if self._d.yesno(cnet_string2, height=15, width=60) == self._DLG_YES: #DHCP
174 network_type = 'dhcp'
175 if self.advanced_mode:
176 code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list. If you have none, just press Enter."), height=13, width=50)
177 else:
178 network_type = 'static'
179 code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information) Your broadcast address is probably your IP address with 255 as the last tuple. DO NOT PRESS ENTER until all fields you intend to fill out are complete!'),
180 ((_(u'Enter your IP address:'), 15),
181 (_(u'Enter your Broadcast address:'), 15),
182 (_(u'Enter your Netmask:'),15,'255.255.255.0'),
183 (_(u'Enter your default gateway:'),15),
184 (_(u'Enter a DNS server:'),15,'4.2.2.1'),
185 (_(u'Enter a HTTP Proxy IP:'), 15),
186 (_(u'Enter a FTP Proxy IP:'), 15),
187 (_(u'Enter a RSYNC Proxy:'),15)
188 ))
189 (ip_address, broadcast, netmask, gateway, dnsservers, http_proxy, ftp_proxy, rsync_proxy) = data[:-1].split('\n')
190 if code != self._DLG_OK:
191 return
192 #Set the info now that it's all gathered.
193 try:
194 #FIXME REPLACE WITH REAL NETWORKING CODE
195 status = GLIUtility.configure_networking(network_type, interface, ip_address, broadcast, netmask, gateway, dnsservers, dhcp_options, http_proxy, ftp_proxy, rsync_proxy)
196 if not status:
197 fatal(_(u"Sorry, but the network could not be set up successfully. Please configure yourself manually and restart the installer."))
198 except:
199 self._d.msgbox(_(u"ERROR! Could not setup networking!"))
200 #FIXME ask if want to networkless or abort.
201
202 def set_enable_ssh(self):
203 #Change the Yes/No buttons back.
204 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
205 self._d.add_persistent_args(["--no-label", _(u"No")])
206 if self.advanced_mode and not self.networkless:
207 if self._d.yesno(_(u"Do you want SSH enabled during the install? This will allow you to login remotely during the installation process. If choosing Yes, be sure you select a new LiveCD root password!"), width=60) == self._DLG_YES:
208 # Enables SSH **Code originally from GLIClientController**
209 status = GLIUtility.spawn("/etc/init.d/sshd start")
210 if not GLIUtility.exitsuccess(status):
211 self._d.msgbox(_(u"ERROR! : Could not start the SSH daemon!"))
212
213 def set_livecd_password(self):
214 # The root password will be set here only if in advanced mode. Otherwise it is auto-scrambled.
215 if self.advanced_mode:
216 self._root_passwd = ""
217 match = False;
218 while not match:
219 livecd_password_string = _(u"""If you want to be able to login to your machine from another console during the installation,
220 you will want to enter a new root password for the LIVECD.
221 Note that this can be different from your new system's root password.
222 Presss Enter twice to skip this step.
223 Enter the new LIVECD root password (will not be echoed): """)
224 code, passwd1 = self._d.passwordbox(livecd_password_string, width=60, height=16)
225 if code != self._DLG_OK:
226 return
227 code, passwd2 = self._d.passwordbox(_(u"Enter the new LIVECD root password again to verify:"))
228 if code != self._DLG_OK:
229 return
230 if passwd1 != passwd2:
231 self._d.msgbox(_(u"The passwords do not match. Please try again."))
232 return
233 else:
234 match = True;
235 if passwd1 != "": #don't want to hash an empty password.
236 try:
237 self._root_passwd = GLIUtility.hash_password(passwd1)
238 except:
239 self._d.msgbox(_(u"ERROR! Could not hash the root password on the LiveCD!"))
240 ##
241 # Actually set it now. **Code originally from GLIClientController**
242 #self._logger.log("Setting root password.")
243 if self._root_passwd != "":
244 # The password specified in the configuration is encrypted.
245 status = GLIUtility.spawn("echo 'root:" + self._root_passwd + "' | chpasswd -e")
246
247 if not GLIUtility.exitsuccess(status):
248 self._d.msgbox(_(u"ERROR! Could not set the root password on the livecd environment!"))
249 # else:
250 # self._logger.log("Livecd root password set.")
251
252 def set_client_kernel_modules(self):
253 if self.advanced_mode:
254 status, output = GLIUtility.spawn("lsmod", return_output=True)
255 cmodules_string1 = _(u"Here is a list of modules currently loaded on your machine.\n Please look through and see if any modules are missing\n that you would like loaded.\n\n")
256 self._d.add_persistent_args(["--exit-label", _(u"Continue")])
257 self._d.scrollbox(cmodules_string1+output, height=20, width=70, title=_(u"Loaded Modules"))
258 cmodules_string2 = _(u"If you have additional modules you would like loaded before the installation begins (ex. a network driver), enter them in a space-separated list.")
259 code, kernel_modules_list = self._d.inputbox(cmodules_string2, init="", width=60, height=12)
260 if code != self._DLG_OK:
261 return
262
263
264 # Actually Load the kernel modules **Code originally from GLIClientController
265
266 #self._logger.log("DEBUG: load_kernel_modules(): modules are " + str(modules))
267 for module in kernel_modules_list.split():
268 try:
269 # if self._configuration.get_verbose(): self._logger.log("DEBUG: load_kernel_modules(): trying to load module " + module)
270 ret = GLIUtility.spawn('modprobe ' + module)
271 if not GLIUtility.exitsuccess(ret):
272 self._d.msgbox(_(u"ERROR! : Could not load module: %s ") % module)
273 # raise GLIException("KernelModuleError", 'warning', 'load_kernel_modules', 'Could not load module: ' + module)
274 #else:
275 # self._logger.log('kernel module: ' + module + ' loaded.')
276 except:
277 self._d.msgbox(_(u"ERROR!: An unknown error occurred during modprobing the modules. Please load them manually and then restart the installer."))
278
279 #######################################
280 #######################################
281 ### MAIN INSTALL SETUP FUNCTIONS START HERE
282
283 ############ STAGE2 FUNCTIONS #################
284
285 def set_mounts(self):
286 mounts = copy.deepcopy(self._install_profile.get_mounts())
287
288 if not mounts:
289 #No mountpoints defined. lets at least find the swap partitions and add them.
290 for drive in self._drives:
291 for part in self._devices[drive]:
292 if part['type'] == "linux-swap":
293 mounts.append({'devnode': part['devnode'], 'mountopts': '', 'mountpoint': '', 'type': "linux-swap"})
294
295 while 1:
296 menulist = []
297 for mount in mounts:
298 if mount['type'] == "linux-swap":
299 menulist.append(mount['devnode'] + " - swap")
300 else:
301 menulist.append(mount['devnode'] + " - " + mount['mountpoint'])
302 #menulist.append(_(u"Define a new mountpoint"))
303 choices = self._dmenu_list_to_choices(menulist)
304 choices.append((_(u"Add"),_(u"Define a new mountpoint")))
305 code, choice = self._d.menu(_(u"Please define the mountpoints of your partitions for the new system. At minimum, a / mountpoint must be defined. Defining /boot and /home mountpoints is recommended."),choices=choices, cancel=_(u"Save and Continue"), height=18)
306 if code == self._DLG_CANCEL:
307 try:
308 self._install_profile.set_mounts(mounts)
309 except:
310 self._d.msgbox(_(u"ERROR: Could net set mounts!"))
311 break
312 if choice == _(u"Add"):
313 parts = []
314 fstypes = {}
315
316 #Make a list of the partitions
317 for drive in self._drives:
318 for tmppart in self._devices[drive]:
319 skip = False
320 devnode = tmppart['devnode']
321 entry = ""
322 if tmppart['type'] == "free":
323 continue
324 elif tmppart['type'] == "extended":
325 continue
326 else:
327 if tmppart.is_logical():
328 entry += _(u"Logical (")
329 else:
330 entry += _(u"Primary (")
331 entry += tmppart['type'] + ", "
332 entry += str(tmppart['mb']) + "MB)"
333
334 #Go through and remove any already defined.
335 for mount in mounts:
336 if mount['devnode'] == devnode:
337 skip = True
338
339 if not skip:
340 #Add to the choices list.
341 parts.append((devnode,entry))
342 fstypes[devnode] = tmppart['type']
343
344 if not parts:
345 continue
346 code, partition = self._d.menu(_(u"Select a Partition to define a mountpoint for"), choices=parts, height=18)
347 if code != self._DLG_OK:
348 continue
349
350 fstype = fstypes[partition]
351 #Ask for mountpoint for this partition. #FIXME use Partition to get the type.
352 # choices_list = ['ext2', 'ext3', 'linux-swap', 'xfs', 'jfs', 'reiserfs','ntfs', 'fat16', 'fat32']
353 # choices = self._dmenu_list_to_choices(choices_list)
354 # code,fstypeidx = self._d.menu(_(u"Select the filesystem for partition %s") % partition, choices=choices, height=18)
355 # if fstypeidx:
356 # fstype = choices_list[int(fstypeidx)-1]
357 # else: continue
358
359 if fstype == 'linux-swap':
360 #We have all the info we need, now add the mount
361 mounts.append({'devnode': partition, 'mountopts': '', 'mountpoint': '', 'type': fstype})
362 continue
363
364 #Ask for the mountpoint
365 mountpoint_menu = ["/","/boot","/etc","/home","/lib","/mnt","/mnt/windows","/opt","/root","/usr","/usr/local","/usr/portage","/var",_(u"Other")]
366 code, mountpt = self._d.menu(_(u"Choose a mountpoint from the list or choose Other to type your own for partition %s. ") % partition, choices=self._dmenu_list_to_choices(mountpoint_menu)) #may have to make that an integer
367 if code == self._DLG_OK:
368 mountpoint = mountpoint_menu[int(mountpt)-1]
369 if mountpoint == _(u"Other"):
370 code, mountpoint = self._d.inputbox(_(u"Enter a mountpoint for partition %s") % partition)
371
372 if not mountpoint: continue
373
374 #Ask for mountopts
375 code, mountopts = self._d.inputbox(_(u"Enter mount options for mountpoint %s. Leave blank for defaults") % mountpoint, height=13, width=50)
376 if code != self._DLG_OK:
377 continue
378
379 #We have all the info we need, now add the mount
380 mounts.append({'devnode': partition, 'mountopts': mountopts, 'mountpoint': mountpoint, 'type': fstype})
381 elif choice: #EDITING A MOUNTPOINT
382 #Find the mount in question, based on devnode
383 idx = int(choice) - 1
384 devnode = mounts[idx]['devnode']
385 mountpoint = mounts[idx]['mountpoint']
386 mountopts = mounts[idx]['mountopts']
387 fstype = mounts[idx]['type']
388
389 menu = [_(u"Change Mountpoint"),
390 _(u"Change Filesystem Type"),
391 _(u"Change Mountoptions"),
392 _(u"Delete This Mountpoint")]
393 code, editchoice = self._d.menu(_(u"Select an option for device %(dev)s : Mountpoint: %(mt)s, Type: %(type)s, Options: %(opt)s" % {'dev': devnode, 'mt': mountpoint, 'type': fstype, 'opt': mountopts}), choices=self._dmenu_list_to_choices(menu))
394 if code == self._DLG_CANCEL:
395 continue
396 editchoice = menu[int(editchoice)-1]
397 if editchoice == _(u"Change Mountpoint"):
398 mountpoint_menu = ["/","/boot","/etc","/home","/lib","/mnt","/mnt/windows","/opt","/root","/usr","/usr/local","/usr/portage","/var",_(u"Other")]
399 code, mountpt = self._d.menu(_(u"Choose a mountpoint from the list or choose Other to type your own for partition %(part)s. Current mountpoint is: %(mt)s" % {'part': devnode, 'mt': mountpoint}) , choices=self._dmenu_list_to_choices(mountpoint_menu), height=18) #may have to make that an integer
400 if code == self._DLG_OK:
401 mountpoint = mountpoint_menu[int(mountpt)-1]
402 if mountpoint == _(u"Other"):
403 code, mountpoint = self._d.inputbox(_(u"Enter a mountpoint for partition %s") % devnode)
404 if not mountpoint: continue
405 mounts[idx]['mountpoint'] = mountpoint
406 elif editchoice == _(u"Change Filesystem Type"):
407 choices_list = ['ext2', 'ext3', 'linux-swap', 'xfs', 'jfs', 'reiserfs','ntfs', 'fat16', 'fat32']
408 choices = self._dmenu_list_to_choices(choices_list)
409 code,fstypeidx = self._d.menu(_(u"Select the filesystem for partition %(part)s. It is currently %(fs)s." % {'part': devnode,'fs': fstype}), choices=choices, height=18)
410 if fstypeidx:
411 fstype = choices_list[int(fstypeidx)-1]
412 else: continue
413 mounts[idx]['type'] = fstype
414 elif editchoice == _(u"Change Mountoptions"):
415 code, mountopts = self._d.inputbox(_(u"Enter mount options for mountpoint %s. Leave blank for defaults") % mountpoint, init=mountopts,height=13, width=50)
416 if code != self._DLG_OK:
417 continue
418 mounts[idx]['mountopts'] = mountopts
419 elif editchoice == _(u"Delete This Mountpoint"):
420 del mounts[idx]
421 else: continue #catchall.
422 def set_partitions(self):
423 partitions_string1 = _(u"""The first thing on the new system to setup is the partitoning.
424 You will first select a drive and then edit its partitions.
425 WARNING: CHANGES ARE MADE IMMEDIATELY TO DISK. BE CAREFUL
426 NOTE: YOU MUST AT LEAST SELECT ONE PARTITION AS YOUR ROOT PARTITION "/"
427 If your drive is pre-partitioned, just select the mountpoints and make
428 sure that the format option is set to FALSE or it will erase your data.
429 The installer does not yet support resizing of partitions (its not safe).
430 When in doubt, **Partition it yourself and then re-run the installer**
431 Please refer to the Gentoo Installation Handbook for more information
432 on partitioning and the various filesystem types available in Linux.""")
433 self._d.msgbox(partitions_string1, height=17, width=78)
434 drives = []
435 devices = {}
436 choice_list = []
437 tmp_drives = Partitioning.detect_devices()
438 tmp_drives.sort()
439 for drive in tmp_drives:
440 devices[drive] = Partitioning.Device(drive, self._arch, self._install_profile)
441 drives.append(drive)
442 choice_list.append((drive, devices[drive].get_model()))
443 self._drives = drives #Store for use in mounts.
444 self._devices = devices #Store for use in mounts.
445 while 1:
446 code, drive_to_partition = self._d.menu(_(u"Which drive would you like to partition?\n Info provided: Type, Size in MB"), choices=choice_list, cancel=_(u"Done"))
447 if code != self._DLG_OK: break
448 while 1:
449 partsmenu = []
450 # for part in partlist:
451 for tmppart in devices[drive_to_partition]:
452 # tmppart = tmpparts[part]
453 entry = ""
454 if tmppart['type'] == "free":
455 #partschoice = "New"
456 entry = _(u" - Unallocated space (")
457 if tmppart.is_logical():
458 entry += _(u"logical, ")
459 entry += str(tmppart['mb']) + "MB)"
460 elif tmppart['type'] == "extended":
461 entry = str(int(tmppart['minor']))
462 entry += _(u" - Extended Partition (") + str(tmppart['mb']) + "MB)"
463 else:
464 entry = str(int(tmppart['minor'])) + " - "
465 # Type: " + tmppart.get_type() + ", Mountpoint: " + tmppart.get_mountpoint() + ", Mountopts: " + tmppart.get_mountopts() + "("
466 if tmppart.is_logical():
467 entry += _(u"Logical (")
468 else:
469 entry += _(u"Primary (")
470 entry += tmppart['type'] + ", "
471 entry += str(tmppart['mb']) + "MB)"
472 partsmenu.append(entry)
473 #Add recommended partitioning option and clear option
474 partsmenu.append(_(u"Set Recommended Layout"))
475 partsmenu.append(_(u"Clear Partitions On This Drive."))
476 code, part_to_edit = self._d.menu(_(u"Select a partition or unallocated space to edit\nKey: Minor, Pri/Ext, Filesystem, Size."), width=70, choices=self._dmenu_list_to_choices(partsmenu), cancel=_(u"Back"))
477 if code != self._DLG_OK: break
478 partmenuchoice = partsmenu[int(part_to_edit)-1]
479 #Check for recommended and clear here before setting the tmppart
480 if partmenuchoice == _(u"Set Recommended Layout"):
481 if self._d.yesno(_(u"This will ERASE YOUR DRIVE and apply a recommended layout. Are you sure you wish to do this?")) == self._DLG_YES:
482 if self._d.yesno(_(u"This is your last chance. Are you SURE you want to CLEAR this drive and set a recommended layout? THERE IS NO TURNING BACK IF YOU SELECT YES."), defaultno=1) == self._DLG_YES:
483 devices[drive_to_partition].do_recommended()
484 continue
485 if partmenuchoice == _(u"Clear Partitions On This Drive."):
486 if self._d.yesno(_(u"This will remove all partitions on your drive. Are you sure you wish to do this?")) == self._DLG_YES:
487 if self._d.yesno(_(u"This is your last chance. Are you SURE you want to CLEAR this drive? THIS WILL DELETE ANY DATA ON THE DRIVE!"), defaultno=1) == self._DLG_YES:
488 devices[drive_to_partition].clear_partitions()
489 # self._d.msgbox(_(u"Partition table cleared successfully"))
490 # except:
491 # self._d.msgbox(_(u"ERROR: could not clear the partition table!"))
492 continue
493 #all other cases (partitions)
494 part_to_edit = int(part_to_edit) - 1
495 tmppart = devices[drive_to_partition][part_to_edit]
496 if tmppart['type'] == "free":
497 # partition size first
498 free_mb = long(tmppart['mb'])
499 code, new_mb = self._d.inputbox(_(u"Enter the size of the new partition in MB (max %s MB). If creating an extended partition input its entire size (not just the first logical size):") % str(free_mb), init=str(free_mb))
500 if code != self._DLG_OK: continue
501 if int(new_mb) > free_mb:
502 self._d.msgbox(_(u"The size you entered (%(entered)s MB) is larger than the maximum of %(max)s MB" % {'entered': new_mb, 'max': str(free_mb)}))
503 continue
504 # partition type
505 part_types = [("ext2", _(u"Old, stable, but no journaling")),
506 ("ext3", _(u"ext2 with journaling and b-tree indexing (RECOMMENDED)")),
507 ("linux-swap", _(u"Swap partition for memory overhead")),
508 ("fat32", _(u"Windows filesystem format used in Win9X and XP")),
509 # ("ntfs", _(u"Windows filesystem format used in Win2K and NT")),
510 # ("jfs", _(u"IBM's journaling filesystem. stability unknown.")),
511 # ("xfs", _(u"Don't use this unless you know you need it.")),
512 ("reiserfs", _(u"B*-tree based filesystem. great performance. Only V3 supported.")),
513 ("extended", _(u"Create an extended partition containing other logical partitions")),
514 (_(u"Other"), _(u"Something else we probably don't support."))]
515 code, type = self._d.menu(_(u"Choose the filesystem type for this new partition."), height=20, width=77, choices=part_types)
516 if code != self._DLG_OK: continue
517
518 # 'other' partition type
519 if type == _(u"Other"):
520 code, type = self._d.inputbox(_(u"Please enter the new partition's type:"))
521 if code != self._DLG_OK: continue
522
523 # now add it to the data structure
524 devices[drive_to_partition].add_partition(part_to_edit, int(new_mb), type)
525 else:
526 while 1:
527 tmppart = devices[drive_to_partition][part_to_edit]
528 tmptitle = drive_to_partition + str(tmppart['minor']) + " - "
529 if tmppart.is_logical():
530 tmptitle += _(u"Logical (")
531 else:
532 tmptitle += _(u"Primary (")
533 tmptitle += tmppart['type'] + ", "
534 tmptitle += str(tmppart['mb']) + "MB)"
535 menulist = [_(u"Delete"), _(u"Extra mkfs.* Parameters")]
536 code, part_action = self._d.menu(tmptitle, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
537 if code != self._DLG_OK: break
538 part_action = menulist[int(part_action)-1]
539 if part_action == _(u"Delete"):
540 answer = (self._d.yesno(_(u"Are you sure you want to delete the partition ") + drive_to_partition + str(tmppart['minor']) + "?") == self._DLG_YES)
541 if answer == True:
542 devices[drive_to_partition].remove_partition(part_to_edit)
543 break
544
545 elif part_action == _(u"Extra mkfs.* Parameters"):
546 self._d.msgbox(_(u"This feature is coming soon. Please go to console and do it yourself for now."))
547
548 def set_network_mounts(self):
549 # This is where any NFS mounts will be specified
550 network_mounts = copy.deepcopy(self._install_profile.get_network_mounts())
551 while 1:
552 menulist = []
553 for mount in network_mounts:
554 menulist.append(mount['host'] + ":" + mount['export'])
555 menulist.append(_(u"Add a new network mount"))
556 choices = self._dmenu_list_to_choices(menulist)
557 code, menuitemidx = self._d.menu(_(u"If you have any network shares you would like to mount during the install and for your new system, define them here. Select a network mount to edit or add a new mount. Currently GLI only supports NFS mounts."), choices=choices, cancel=_(u"Save and Continue"), height=18)
558 if code == self._DLG_CANCEL:
559 try:
560 self._install_profile.set_network_mounts(network_mounts)
561 except:
562 self._d.msgbox(_(u"ERROR: Could net set network mounts!"))
563 break
564 menuitem = menulist[int(menuitemidx)-1]
565 if menuitem == _(u"Add a new network mount"):
566 #Change the Yes/No buttons back.
567 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
568 self._d.add_persistent_args(["--no-label", _(u"No")])
569 if self._d.yesno(_(u"Do you want to start portmap to be able to search for NFS mounts?"), width=60) == self._DLG_YES:
570 status = GLIUtility.start_portmap()
571 if not status:
572 self._d.msgbox(_(u"ERROR: Could not start portmap!"))
573
574 code, nfsmount = self._d.inputbox(_(u"Enter NFS mount or just enter the IP/hostname to search for available mounts"), height=13, width=50)
575 if code != self._DLG_OK:
576 continue
577 if not GLIUtility.is_nfs(nfsmount):
578 if GLIUtility.is_ip(nfsmount) or GLIUtility.is_hostname(nfsmount):
579 status, remotemounts = GLIUtility.spawn("/usr/sbin/showmount -e " + nfsmount + " 2>&1 | egrep '^/' | cut -d ' ' -f 1 && echo", return_output=True)
580 remotemounts = remotemounts.strip().split("\n")
581 if (not GLIUtility.exitsuccess(status)) or (not len(remotemounts)) or not remotemounts[0]:
582 self._d.msgbox(_(u"No NFS exports were detected on ") + nfsmount)
583 continue
584 code, nfsmount2 = self._d.menu(_(u"Select a NFS export"), choices=self._dmenu_list_to_choices(remotemounts), cancel=_(u"Back"))
585 if code != self._DLG_OK:
586 continue
587 nfsmount2 = remotemounts[int(nfsmount2)-1]
588 else:
589 self._d.msgbox(_(u"The address you entered, %s, is not a valid IP or hostname. Please try again.") % nfsmount)
590 continue
591 else:
592 colon_location = nfsmount.find(':')
593 menuitem = nfsmount
594 nfsmount = menuitem[:colon_location]
595 nfsmount2 = menuitem[colon_location+1:]
596 for mount in network_mounts:
597 if nfsmount == mount['host'] and nfsmount2 == mount['export']:
598 self._d.msgbox(_(u"There is already an entry for ") + nfsmount + ":" + nfsmount2 + ".")
599 nfsmount = None
600 break
601 if nfsmount == None:
602 continue
603 network_mounts.append({'export': nfsmount2, 'host': nfsmount, 'mountopts': '', 'mountpoint': '', 'type': 'nfs'})
604 menuitem = nfsmount + ":" + nfsmount2
605 menuitemidx = len(network_mounts)
606
607 if menuitem.find(':') != -1:
608 colon_location = menuitem.find(':')
609 tmpmount = network_mounts[int(menuitemidx)-1]
610 code, mountpoint = self._d.inputbox(_(u"Enter a mountpoint"), init=tmpmount['mountpoint'])
611 if code == self._DLG_OK:
612 tmpmount['mountpoint'] = mountpoint
613 code, mountopts = self._d.inputbox(_(u"Enter mount options"), init=tmpmount['mountopts'])
614 if code == self._DLG_OK:
615 tmpmount['mountopts'] = mountopts
616 network_mounts[int(menuitemidx)-1] = tmpmount
617
618 ############ STAGE3 FUNCTIONS #################
619
620 def set_install_stage(self):
621 if self.networkless: return
622 # The install stage and stage tarball will be selected here
623 install_stages = (("3",_(u"Stage3 is a basic system that has been built for you (no compiling).")),
624 ("3+GRP", _(u"A Stage3 install but using binaries from the LiveCD when able.")))
625 code, install_stage = self._d.menu(_(u"Which stage do you want to start at?"), choices=install_stages, cancel=_(u"Back"), width=78)
626 stage3warning = ""
627 if code == self._DLG_OK:
628 if install_stage == "3+GRP":
629 stage3warning = _(u"WARNING: Since you are doing a GRP install it is HIGHLY recommended you choose Create from CD to avoid a potentially broken installation.")
630 try:
631 self._install_profile.set_grp_install(None, True, None)
632 except:
633 self._d.msgbox(_(u"ERROR! Could not set install stage!"))
634 install_stage = "3"
635 try:
636 self._install_profile.set_install_stage(None, install_stage, None)
637 except:
638 self._d.msgbox(_(u"ERROR! Could not set install stage!"))
639 has_systempkgs = GLIUtility.is_file("/usr/livecd/systempkgs.txt")
640 if install_stage == "3" and has_systempkgs:
641 #Change the Yes/No buttons to new labels for this question.
642 self._d.add_persistent_args(["--yes-label", _(u"Create from CD")])
643 self._d.add_persistent_args(["--no-label", _(u"Specify URI")])
644 if self._d.yesno(_(u"Do you want to generate a stage3 on the fly using the files on the LiveCD (fastest) or do you want to grab your stage tarball from the Internet?\n")+stage3warning, width=55) == self._DLG_YES:
645 #Generate on the FLY
646 try:
647 self._install_profile.set_dynamic_stage3(None, True, None)
648 except:
649 self._d.msgbox(_(u"ERROR: Could not set the stage tarball URI!"))
650 return
651 #Specify URI
652 #subarches = { 'x86': ("x86", "i686", "pentium3", "pentium4", "athlon-xp"), 'hppa': ("hppa1.1", "hppa2.0"), 'ppc': ("g3", "g4", "g5", "ppc"), 'sparc': ("sparc32", "sparc64")}
653
654 stage_tarball = ""
655 while (not stage_tarball) and (not GLIUtility.is_uri(stage_tarball)): #LOOP till valid.
656 type_it_in = False
657 if GLIUtility.ping("www.gentoo.org"): #Test for network connectivity
658 mirrors = GLIUtility.list_mirrors()
659 mirrornames = []
660 mirrorurls = []
661 for item in mirrors:
662 mirrornames.append(item[1])
663 mirrorurls.append(item[0])
664 code, mirror = self._d.menu(_(u"Select a mirror to grab the tarball from or select Cancel to enter an URI manually."), choices=self._dmenu_list_to_choices(mirrornames), width=77, height=20)
665 if code != self._DLG_OK:
666 type_it_in = True
667 else:
668 mirror = mirrorurls[int(mirror)-1]
669 tarballs = GLIUtility.list_stage_tarballs_from_mirror(mirror, self._arch)
670 code, stage_tarball = self._d.menu(_(u"Select your desired stage tarball:"), choices=self._dmenu_list_to_choices(tarballs), width=77, height=20)
671 if (code != self._DLG_OK):
672 type_it_in = True
673 else:
674 stage_tarball = mirror + "/releases/" + self._arch + "/current/stages/" + tarballs[int(stage_tarball)-1]
675 #get portageq envvar value of cflags and look for x86, i686,etc.
676 #URL SYNTAX
677 #http://gentoo.osuosl.org/releases/ARCHITECTURE/current/stages/
678 else:
679 type_it_in = True
680 if type_it_in:
681 code, stage_tarball = self._d.inputbox(_(u"Specify the stage tarball URI or local file:"), init=self._install_profile.get_stage_tarball_uri())
682 if code != self._DLG_OK:
683 return
684 #If Doing a local install, check for valid file:/// uri
685 if stage_tarball:
686 if not GLIUtility.is_uri(stage_tarball):
687 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."));
688 else: self._install_profile.set_stage_tarball_uri(None, stage_tarball, None)
689 else: self._d.msgbox(_(u"No URI was specified!"))
690
691 def set_portage_tree(self):
692 # This section will ask whether to sync the tree, whether to use a snapshot, etc.
693 if self._install_profile.get_dynamic_stage3(): #special case
694 try:
695 self._install_profile.set_portage_tree_sync_type(None,"snapshot", None)
696 cd_snapshot_uri = GLIUtility.get_cd_snapshot_uri()
697 self._install_profile.set_portage_tree_snapshot_uri(None, cd_snapshot_uri, None)
698 except:
699 self._d.msgbox(_(u"ERROR! Could not set the portage cd snapshot URI!"))
700 return
701
702 #Normal case
703 menulist = [("Sync", _(u"Normal. Use emerge sync RECOMMENDED!")),
704 ("Webrsync", _(u"HTTP daily snapshot. Use when rsync is firewalled.")),
705 ("Snapshot", _(u"Use a portage snapshot, either a local file or a URL")),
706 ("None", _(u"Extra cases such as if /usr/portage is an NFS mount"))]
707 code, portage_tree_sync = self._d.menu(_(u"Which method do you want to use to sync the portage tree for the installation? If choosing a snapshot you will need to provide the URI for the snapshot if it is not on the livecd."),width=75, height=17, choices=menulist)
708 if code != self._DLG_OK:
709 return
710 self._install_profile.set_portage_tree_sync_type(None, portage_tree_sync.lower(), None)
711 if portage_tree_sync == "Snapshot":
712 if self._install_profile.get_portage_tree_snapshot_uri():
713 initval = self._install_profile.get_portage_tree_snapshot_uri()
714 else:
715 initval = GLIUtility.get_cd_snapshot_uri()
716 code, snapshot = self._d.inputbox(_(u"Enter portage tree snapshot URI"), init=initval)
717 if code == self._DLG_OK:
718 if snapshot:
719 if not GLIUtility.is_uri(snapshot):
720 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."))
721 else:
722 self._install_profile.set_portage_tree_snapshot_uri(None, snapshot, None)
723
724 else:
725 self._d.msgbox(_(u"No URI was specified! Returning to default emerge sync."))
726 #if d.yesno("The specified URI is invalid. Use it anyway?") == DLG_YES: install_profile.set_stage_tarball_uri(None, stage_tarball, None)
727
728 ############ STAGE4 FUNCTIONS #################
729
730 def set_make_conf(self):
731 # This section will be for setting things like CFLAGS, ACCEPT_KEYWORDS, and USE
732 #special case for dynamic stage3
733 if self._install_profile.get_dynamic_stage3() or not self.advanced_mode:
734 return
735
736 etc_files = self._install_profile.get_etc_files()
737 if etc_files.has_key("make.conf"):
738 make_conf = etc_files['make.conf']
739 else:
740 make_conf = {}
741
742 self._d.msgbox(_(u"""The installer will now gather information regarding the contents of /etc/make.conf
743 One of the unique (and best) features of Gentoo is the ability to
744 define flags (called USE flags) that define what components are
745 compiled into applications. For example, you can enable the alsa
746 flag and programs that have alsa capability will use it.
747 The result is a finely tuned OS with no unnecessary components to
748 slow you down.
749 The installer divides USE flag selection into two screens, one for
750 global USE flags and one for local flags specific to each program.
751 Please be patient while the screens load. It may take awhile."""), width=73, height=16)
752
753 #First grab the system USE flags. These will be used often.
754 system_use_flags = GLIUtility.spawn("portageq envvar USE", return_output=True)[1].strip().split()
755
756 #Now get any stored USE flags.
757 remove_from_system = {}
758 add_flags = []
759 if make_conf.has_key("USE"):
760 stored_use_flags = make_conf["USE"].split()
761 for flag in stored_use_flags:
762 if "-" in flag: #A subtraction of a flag in the system USE
763 remove_flag = flag[1:]
764 remove_from_system[remove_flag] = 1
765 else:
766 add_flags.append(flag) #Add to checked list
767
768
769 #Load data.
770 use_flags = []
771 use_local_flags = []
772 use_desc = GLIUtility.get_global_use_flags()
773 use_local_desc = GLIUtility.get_local_use_flags()
774
775 #populate the choices list
776 sorted_use = use_desc.keys()
777 sorted_use.sort()
778 for flagname in sorted_use:
779 use_flags.append((flagname, use_desc[flagname], int((flagname in system_use_flags or flagname in add_flags) and not remove_from_system.has_key(flagname) )))
780 #present the menu
781 code, chosen_use_flags = self._d.checklist(_(u"Choose which *global* USE flags you want on the new system"), height=25, width=80,list_height=17, choices=use_flags)
782
783 #populate the chocies list
784 sorted_use = use_local_desc.keys()
785 sorted_use.sort()
786 for flagname in sorted_use:
787 use_local_flags.append((flagname, use_local_desc[flagname], int((flagname in system_use_flags or flagname in add_flags) and not remove_from_system.has_key(flagname) )))
788 #present the menu
789 code, chosen_use_local_flags = self._d.checklist(_(u"Choose which *local* USE flags you want on the new system"), height=25, width=80,list_height=17, choices=use_local_flags)
790
791
792 #Hash the chosen list for speed.
793 chosen_hash = {}
794 for flag in chosen_use_flags:
795 chosen_hash[flag] = 1
796 for flag in chosen_use_local_flags:
797 chosen_hash[flag] = 1
798
799 #Create the new string. Loop through ALL flags, look for match in hash then in USE
800 temp_use = ""
801 for flag in use_desc:
802 if chosen_hash.has_key(flag) and (flag in system_use_flags):
803 continue #Already in USE, don't need to add.
804 elif chosen_hash.has_key(flag):
805 temp_use += flag + " " #Checked. Add.
806 elif not chosen_hash.has_key(flag) and (flag in system_use_flags):
807 temp_use += "-"+flag+" " #Was unchecked. add a -flag to USE
808
809 for flag in use_local_desc:
810 if chosen_hash.has_key(flag) and (flag in system_use_flags):
811 continue #Already in USE, don't need to add.
812 elif chosen_hash.has_key(flag):
813 temp_use += flag + " " #Checked. Add.
814 elif not chosen_hash.has_key(flag) and (flag in system_use_flags):
815 temp_use += "-"+flag+" " #Was unchecked. add a -flag to USE
816 #Store it!
817 make_conf["USE"] = temp_use
818
819 if not self._install_profile.get_dynamic_stage3() and self.advanced_mode:
820 #Second, set the ACCEPT_KEYWORDS
821 #Change the Yes/No buttons to new labels for this question.
822 self._d.add_persistent_args(["--yes-label", _(u"Stable")])
823 self._d.add_persistent_args(["--no-label", _(u"Unstable")])
824 if self._d.yesno(_(u"Do you want to run the normal stable portage tree, or the bleeding edge unstable (i.e. ACCEPT_KEYWORDS=%s)? If unsure select stable. Stable is required for GRP installs." % self._arch), height=12, width=55) == self._DLG_YES:
825 #Stable
826 make_conf["ACCEPT_KEYWORDS"] = ""
827 else: #Unstable
828 make_conf["ACCEPT_KEYWORDS"] = "~" + self._arch
829 #Third, misc. stuff.
830 while self.advanced_mode:
831 menulist = [("CFLAGS",_(u"Edit your C Flags and Optimization level")),
832 ("CHOST", _(u"Change the Host Setting")),
833 ("MAKEOPTS", _(u"Specify number of parallel makes (-j) to perform.")),
834 ("FEATURES", _(u"Change portage functionality settings. (distcc/ccache)")),
835 ("GENTOO_MIRRORS", _(u"Specify mirrors to use for source retrieval.")),
836 ("SYNC", _(u"Specify server used by rsync to sync the portage tree.")),
837 (_(u"Other"), _(u"Specify your own variable and value."))]
838 if self._install_profile.get_dynamic_stage3(): #SPECIAL LIST WITHOUT CHOST
839 menulist = [("CFLAGS",_(u"Edit your C Flags and Optimization level")),
840 ("MAKEOPTS", _(u"Specify number of parallel makes (-j) to perform.")),
841 ("FEATURES", _(u"Change portage functionality settings. (distcc/ccache)")),
842 ("GENTOO_MIRRORS", _(u"Specify mirrors to use for source retrieval.")),
843 ("SYNC", _(u"Specify server used by rsync to sync the portage tree.")),
844 (_(u"Other"), _(u"Specify your own variable and value."))]
845 code, menuitem = self._d.menu(_(u"For experienced users, the following /etc/make.conf variables can also be defined. Choose a variable to edit or Done to continue."), choices=menulist, cancel=_(u"Done"), width=77)
846 if code != self._DLG_OK:
847 break
848 if menuitem == _(u"Other"):
849 code,menuitem = self._d.inputbox(_(u"Enter the variable name: "))
850 if code != self._DLG_OK:
851 continue
852 oldval = ""
853 if make_conf.has_key(menuitem):
854 oldval = make_conf[menuitem]
855 if oldval:
856 code, newval = self._d.inputbox(_(u"Enter new value for ") + menuitem, init=oldval)
857 if code == self._DLG_OK:
858 make_conf[menuitem] = newval
859 continue
860 #SPECIAL CASES here with their own menus.
861 if menuitem == "CFLAGS":
862 if not make_conf.has_key("CFLAGS"):
863 try:
864 cflags = GLIUtility.get_value_from_config("/etc/make.conf","CFLAGS")
865 except:
866 cflags = ""
867 else:
868 cflags = make_conf['CFLAGS']
869 while 1:
870 choices_list = [
871 (_(u"CLEAR"),_(u"Erase the current value and start over.")),
872 ("-mcpu",_(u"Add a CPU optimization (deprecated in GCC 3.4)")),
873 ("-mtune",_(u"Add a CPU optimization (GCC 3.4+)")),
874 ("-march",_(u"Add an Architecture optimization")),
875 ("-O",_(u"Add optimization level (please do NOT go over 2)")),
876 ("-fomit-frame-pointer",_(u"For advanced users only.")),
877 ("-pipe",_(u"Common additional flag")),
878 (_(u"Manual"),_(u"Specify your CFLAGS manually"))
879 ]
880 code, choice = self._d.menu(_(u"Choose a flag to add to the CFLAGS variable or Done to go back. The current value is: ")+ cflags, choices=choices_list, cancel=_(u"Done"), width=70)
881 if code != self._DLG_OK:
882 break
883 if choice == _(u"CLEAR"):
884 cflags = ""
885 elif choice == _(u"Manual"):
886 code, cflags = self._d.inputbox(_(u"Enter new value for ") + menuitem)
887 break
888 elif choice in ["-fomit-frame-pointer","-pipe"]:
889 cflags += " "+choice
890 else:
891 code, newval = self._d.inputbox(_(u"Enter the new value for %s (value only):") % choice)
892 if code != self._DLG_OK or not newval:
893 continue
894 if choice == "-O":
895 cflags += " "+choice+newval
896 else:
897 cflags += " "+choice+"="+newval
898 if cflags:
899 make_conf['CFLAGS'] = cflags
900 elif menuitem == "CHOST":
901 choices_list = GLIUtility.get_chosts(self._arch)
902 code, chost = self._d.menu(_(u"Choose from the available CHOSTs for your architecture."), choices=self._dmenu_list_to_choices(choices_list), width=77)
903 if code != self._DLG_OK:
904 continue
905 chost = choices_list[int(chost)-1]
906 make_conf['CHOST'] = chost
907 elif menuitem == "MAKEOPTS":
908 makeopt_string = _(u"Presently the only use is for specifying the number of parallel makes (-j) to perform. The suggested number for parallel makes is CPUs+1. Enter the NUMBER ONLY:")
909 code, newval = self._d.inputbox(makeopt_string, width=60)
910 if code != self._DLG_OK:
911 continue
912 make_conf['MAKEOPTS'] = "-j"+str(newval)
913 elif menuitem == "FEATURES":
914 choices_list = [("sandbox",_(u"enables sandboxing when running emerge and ebuild."),0),
915 ("ccache",_(u"enables ccache support via CC."),0),
916 ("distcc",_(u"enables distcc support via CC."),0),
917 ("distlocks",_(u"enables distfiles locking using fcntl or hardlinks."),0),
918 ("buildpkg",_(u"create binaries of all packages emerged"),0),
919 (_(u"Other"),_(u"Input your list of FEATURES manually."),0) ]
920 features_string = _(u"FEATURES are settings that affect the functionality of portage. Most of these settings are for developer use, but some are available to non-developers as well.")
921 code, choices = self._d.checklist(features_string, choices=choices_list, width=75)
922 if code != self._DLG_OK:
923 continue
924 if _(u"Other") in choices:
925 code, features = self._d.inputbox(_(u"Enter the value of FEATURES: "))
926 elif choices:
927 features = string.join(choices, ' ')
928 else:
929 features = ""
930 if features:
931 make_conf['FEATURES'] = features
932 else:
933 code, newval = self._d.inputbox(_(u"Enter new value for ") + menuitem)
934 if code == self._DLG_OK and newval:
935 make_conf[menuitem] = newval
936
937 try:
938 if make_conf:
939 etc_files['make.conf'] = make_conf
940 self._install_profile.set_etc_files(etc_files)
941 except:
942 self._d.msgbox(_(u"ERROR! Could not set the make_conf correctly!"))
943
944 def set_distcc(self):
945 #Change the Yes/No buttons for this question.
946 if self._install_profile.get_dynamic_stage3() or not self.advanced_mode:
947 return
948 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
949 self._d.add_persistent_args(["--no-label", _(u"No")])
950 if self._d.yesno(_(u"Do you want to use distcc to compile your extra packages during the install and for future compilations as well?"), height=12, width=60, defaultno=1) == self._DLG_YES:
951 #Add distcc to the services list.
952 if self._install_profile.get_services():
953 services = self._install_profile.get_services()
954 if isinstance(services, str):
955 services = services.split(',')
956 else:
957 services = []
958 if not "distccd" in services:
959 services.append("distccd")
960 try:
961 services = string.join(services, ',')
962 if services:
963 self._install_profile.set_services(None, services, None)
964 except:
965 self._d.msgbox(_(u"ERROR! Could not set the services list."))
966 return
967 #Set the distcc flag to emerge earlier than other packages.
968 try:
969 self._install_profile.set_install_distcc(None, True, None)
970 except:
971 self._d.msgbox(_(u"ERROR! Could not set the install distcc flag!"))
972 return
973
974 #Add distcc to the FEATURES in make.conf and add DISTCC_HOSTS too.
975 etc_files = self._install_profile.get_etc_files()
976 #load up the make.conf
977 if etc_files.has_key("make.conf"):
978 make_conf = etc_files['make.conf']
979 else:
980 make_conf = {}
981 #Check for FEATURES and add if not already there.
982 if make_conf.has_key("FEATURES"):
983 if not "distcc" in make_conf['FEATURES']:
984 make_conf['FEATURES'] += " distcc"
985 else:
986 make_conf['FEATURES'] = "distcc"
987 #Now while still working in make.conf, figure out what HOSTS to set.
988 if make_conf.has_key("DISTCC_HOSTS"):
989 initval = make_conf['DISTCC_HOSTS']
990 else:
991 initval = "localhost "
992 distcc_string = _(u"Enter the hosts to be used by distcc for compilation:\nExample: localhost 192.168.0.2 192.168.0.3:4000/10")
993 code, hosts = self._d.inputbox(distcc_string, width=75, init=initval)
994 if code != self._DLG_OK:
995 hosts = initval
996 make_conf['DISTCC_HOSTS'] = hosts
997 try:
998 etc_files['make.conf'] = make_conf
999 self._install_profile.set_etc_files(etc_files)
1000 except:
1001 self._d.msgbox(_(u"ERROR! Could not set the make_conf correctly!"))
1002
1003 def set_etc_portage(self):
1004 if self.networkless: return
1005 #This section will be for editing the /etc/portage/* files and other /etc/* files. This should be for advanced users only.
1006 etc_files = self._install_profile.get_etc_files()
1007 while self.advanced_mode:
1008
1009 menulist = [("portage/package.mask",_(u"A list of DEPEND atoms to mask.")),
1010 ("portage/package.unmask",_(u"A list of packages to unmask.")),
1011 ("portage/package.keywords",_(u"Per-package KEYWORDS (like ACCEPT_KEYWORDS).")),
1012 ("portage/package.use",_(u"Per-package USE flags.")),
1013 (_(u"Other"),_(u"Type your own name of a file to edit in /etc/"))]
1014 code, menuitem = self._d.menu(_(u"For experienced users, the following /etc/* variables can also be defined. Choose a variable to edit or Done to continue."), choices=menulist, cancel=_(u"Done"), width=77)
1015 if code != self._DLG_OK:
1016 break #get out of the while loop. then save and continue
1017
1018 if menuitem == _(u"Other"):
1019 code, menuitem = self._d.inputbox(_(u"Enter the name of the /etc/ file you would like to edit (DO NOT type /etc/)"))
1020 if code != self._DLG_OK:
1021 return
1022 oldval = ""
1023 if etc_files.has_key(menuitem):
1024 oldval = etc_files[menuitem]
1025
1026 code, newval = self._d.inputbox(_(u"Enter new contents (use \\n for newline) of ") + menuitem, init=oldval)
1027 if code == self._DLG_OK:
1028 etc_files[menuitem] = []
1029 etc_files[menuitem].append(newval)
1030 try:
1031 self._install_profile.set_etc_files(etc_files)
1032 except:
1033 self._d.msgbox(_(u"ERROR! Could not set etc/portage/* correctly!"))
1034
1035
1036
1037 def set_kernel(self):
1038 if self.networkless: return
1039 # This section will be for choosing kernel sources, choosing (and specifying) a custom config or genkernel, modules to load at startup, etc.
1040 kernel_sources = [("livecd-kernel", _(u"Copy over the current running kernel (fastest)")),
1041 ("vanilla-sources", _(u"The Unaltered Linux Kernel ver 2.6+ (safest)")),
1042 ("gentoo-sources", _(u"Gentoo's optimized 2.6+ kernel. (less safe)")),
1043 ("hardened-sources", _(u"Hardened sources for the 2.6 kernel tree")),
1044 ("grsec-sources",_(u"Vanilla sources with grsecurity patches")),
1045 (_(u"Other"), _(u"Choose one of the other sources available."))]
1046 code, menuitem = self._d.menu(_(u"Choose which kernel sources to use for your system. If using a previously-made kernel configuration, make sure the sources match the kernel used to create the configuration."), choices=kernel_sources, width=77, height=17)
1047 if code != self._DLG_OK:
1048 return
1049 if menuitem == _(u"Other"):
1050 code, menuitem = self._d.inputbox(_(u"Please enter the desired kernel sources package name:"))
1051 if code != self._DLG_OK: return
1052 try:
1053 self._install_profile.set_kernel_source_pkg(None, menuitem, None)
1054 except:
1055 self._d.msgbox(_(u"ERROR! Could not set the kernel source package!"))
1056 if not menuitem == "livecd-kernel":
1057 #Change the Yes/No buttons to new labels for this question.
1058 self._d.add_persistent_args(["--yes-label", _(u"Genkernel")])
1059 self._d.add_persistent_args(["--no-label", _(u"Traditional (requires a config!)")])
1060 kernel_string1 = _(u"There are currently two ways the installer can compile a kernel for your new system. You can either provide a previously-made kernel configuration file and use the traditional kernel-compiling procedure (no initrd) or have genkernel automatically create your kernel for you (with initrd). \n\n If you do not have a previously-made kernel configuration, YOU MUST CHOOSE Genkernel. Choose which method you want to use.")
1061 if self._d.yesno(kernel_string1, width=76,height=13) == self._DLG_YES: #Genkernel
1062 self._install_profile.set_kernel_build_method(None,"genkernel", None)
1063 if self.advanced_mode:
1064 #Change the Yes/No buttons back.
1065 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1066 self._d.add_persistent_args(["--no-label", _(u"No")])
1067 if self._d.yesno(_(u"Do you want the bootsplash screen to show up on bootup?")) == self._DLG_YES:
1068 self._install_profile.set_kernel_bootsplash(None, True, None)
1069 else:
1070 self._install_profile.set_kernel_bootsplash(None, False, None)
1071 else: #Custom
1072 self._install_profile.set_kernel_build_method(None,"custom", None)
1073 if self.advanced_mode:
1074 code, custom_kernel_uri = self._d.inputbox(_(u"If you have a custom kernel configuration, enter its location (otherwise just press Enter to continue):"), height=13, width=50)
1075 if code == self._DLG_OK:
1076 if custom_kernel_uri:
1077 if not GLIUtility.is_uri(custom_kernel_uri, checklocal=self.local_install):
1078 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."))
1079 else:
1080 try:
1081 self._install_profile.set_kernel_config_uri(None, custom_kernel_uri, None)
1082 except:
1083 self._d.msgbox(_(u"ERROR! Could not set the kernel config URI!"))
1084 #else: self._d.msgbox(_(u"No URI was specified! Reverting to using genkernel"))
1085
1086 def set_boot_loader(self):
1087 mounts = self._install_profile.get_mounts()
1088 boot_drive_choices = []
1089 #Bootloader code yanked from the x86ArchTemplate
1090 kernel_params = self._install_profile.get_bootloader_kernel_args()
1091 if self._install_profile.get_boot_device():
1092 boot_device = self._install_profile.get_boot_device()
1093 else:
1094 boot_device = ""
1095 foundboot = False
1096 for mount in mounts:
1097 #if not mount['devnode'][:-1] in boot_drive_choices:
1098 # boot_drive_choices.append(mount['devnode'][:-1])
1099 mountpoint = mount['mountpoint']
1100 if (mountpoint == "/boot"):
1101 foundboot = True
1102 if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
1103 if not "doscsi" in kernel_params.split():
1104 if mount['devnode'].startswith("/dev/sd"): kernel_params += " doscsi"
1105 for drive in self._drives:
1106 boot_drive_choices.append((drive, self._devices[drive].get_model()))
1107 arch_loaders = { 'x86': [
1108 ("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED"))],
1109 'amd64': [
1110 ("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED"))]} #FIXME ADD OTHER ARCHS
1111 if not self.networkless:
1112 arch_loaders['x86'].append(("lilo",_(u"LInux LOader, older, traditional.(detects windows partitions)")))
1113 boot_loaders = arch_loaders[self._arch]
1114 boot_loaders.append(("none", _(u"Do not install a bootloader. (System may be unbootable!)")))
1115 boot_string1 = _(u"To boot successfully into your new Linux system, a bootloader will be needed. If you already have a bootloader you want to use you can select None here. The bootloader choices available are dependent on what GLI supports and what architecture your system is. Choose a bootloader")
1116 code, menuitem = self._d.menu(boot_string1, choices=boot_loaders, height=16, width=74)
1117 if code != self._DLG_OK:
1118 return
1119 try:
1120 self._install_profile.set_boot_loader_pkg(None, menuitem, None)
1121 except:
1122 self._d.msgbox(_(u"ERROR! Could not set boot loader pkg! ")+menuitem)
1123 if menuitem != "none" and self.advanced_mode:
1124 #Reset the Yes/No labels.
1125 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1126 self._d.add_persistent_args(["--no-label",_(u"No")])
1127 boot_string2 = _(u"Most bootloaders have the ability to install to either the Master Boot Record (MBR) or some other partition. Most people will want their bootloader installed on the MBR for successful boots, but if you have special circumstances, you can have the bootloader installed to the /boot partition instead. Do you want the boot loader installed in the MBR? (YES is RECOMMENDED)")
1128 if self._d.yesno(boot_string2, height=13, width=55) == self._DLG_YES:
1129 self._install_profile.set_boot_loader_mbr(None, True, None)
1130 else:
1131 self._install_profile.set_boot_loader_mbr(None, False, None)
1132 if self._install_profile.get_boot_loader_mbr(): #If we're installing to MBR gotta check the device.
1133 if self.advanced_mode or (boot_device and boot_device[-1] != 'a'):
1134 #show the menu.
1135 boot_string3_std = _(u"Your boot device may not be correct. It is currently set to %s, but this device may not be the first to boot. Usually boot devices end in 'a' such as hda or sda.") % boot_device
1136 boot_string3 = _(u" Please confirm your boot device by choosing it from the menu.")
1137 if not self.advanced_mode:
1138 boot_string3 = boot_string3_std + boot_string3
1139 if not boot_drive_choices:
1140 self._d.msgbox(_(u"ERROR: No drives set up. Please complete the Partitioning screen first!"))
1141 return
1142 code, boot_drive_choice = self._d.menu(boot_string3, choices=self._dmenu_list_to_choices(boot_drive_choices), height=16, width=70)
1143 if code != self._DLG_OK:
1144 return
1145 boot_drive_choice = boot_drive_choices[int(boot_drive_choice)-1]
1146 try:
1147 self._install_profile.set_boot_device(None,boot_drive_choice,None)
1148 except:
1149 self._d.msgbox(_(u"ERROR! Could not set the boot device!")+boot_drive_choice)
1150 if self.advanced_mode:
1151 code, bootloader_kernel_args = self._d.inputbox(_(u"If you have any additional optional arguments you want to pass to the kernel at boot, type them here or just press Enter to continue:"), height=12, width=55, init=kernel_params)
1152 if code == self._DLG_OK:
1153 try:
1154 self._install_profile.set_bootloader_kernel_args(None, bootloader_kernel_args, None)
1155 except:
1156 self._d.msgbox(_(u"ERROR! Could not set bootloader kernel arguments! ")+bootloader_kernel_args)
1157 elif kernel_params: #If we are in standard mode but have the dosci to add.
1158 try:
1159 self._install_profile.set_bootloader_kernel_args(None, kernel_params, None)
1160 except:
1161 self._d.msgbox(_(u"ERROR! Could not set bootloader kernel arguments! ")+bootloader_kernel_args)
1162
1163
1164 def set_timezone(self):
1165 # This section will be for setting the timezone.
1166 zonepath = "/usr/share/zoneinfo"
1167 skiplist = ["zone.tab","iso3166.tab","posixrules"]
1168 while 1:
1169 tzlist = []
1170 for entry in os.listdir(zonepath):
1171 if entry not in skiplist:
1172 if os.path.isdir(zonepath + "/" + entry): entry += "/"
1173 tzlist.append(entry)
1174 tzlist.sort()
1175 timezone_string = _(u"Please select the timezone for the new installation. Entries ending with a / can be selected to reveal a sub-list of more specific locations. For example, you can select America/ and then Chicago.")
1176 code, tznum = self._d.menu(timezone_string, choices=self._dmenu_list_to_choices(tzlist), height=20, cancel="Back")
1177 if code == self._DLG_OK:
1178 zonepath = os.path.join(zonepath,tzlist[int(tznum)-1])
1179 if tzlist[int(tznum)-1][-1:] != "/":
1180 break
1181 else:
1182 if zonepath == "/usr/share/zoneinfo":
1183 return
1184 slashloc = zonepath[:-1].rfind("/")
1185 zonepath = zonepath[:slashloc]
1186 try:
1187 self._install_profile.set_time_zone(None, zonepath[20:], None)
1188 except:
1189 self._d.msgbox(_(u"ERROR: Could not set that timezone!"))
1190
1191 def set_networking(self):
1192 # This section will be for setting up network interfaces
1193 interfaces = self._install_profile.get_network_interfaces()
1194
1195 while 1:
1196 net_string1 = _(u"Here you will enter all of your network interface information for the new system. You can either choose a network interface to edit, add a network interface, delete an interface, or edit the miscellaneous options such as hostname and proxy servers.")
1197 net_string2 = _(u"To setup your network interface, you can either use DHCP if enabled, or manually enter your network information.\n DHCP (Dynamic Host Configuration Protocol) makes it possible to automatically receive networking information (IP address, netmask, broadcast address, gateway, nameservers etc.). This only works if you have a DHCP server in your network (or if your provider provides a DHCP service). If you do not, you must enter the information manually. Please select your networking configuration method:")
1198 choice_list = []
1199 for iface in interfaces:
1200 if interfaces[iface][0] == 'dhcp':
1201 choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1]))
1202 else:
1203 choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+_(u" Netmask: ")+interfaces[iface][2]))
1204 choice_list.append((_(u"Add"),_(u"Add a new network interface")))
1205 code, iface_choice = self._d.menu(net_string1, choices=choice_list, cancel=_(u"Save and Continue"), height=18, width=77)
1206 if code != self._DLG_OK:
1207 try:
1208 self._install_profile.set_network_interfaces(interfaces)
1209 except:
1210 self._d.msgbox(_(u"ERROR! Could not set the network interfaces!"))
1211 break #This should hopefully move the user down to part two of set_networking
1212 if iface_choice == _(u"Add"):
1213
1214 device_list = GLIUtility.get_eth_devices()
1215 newchoice_list = []
1216 for device in device_list:
1217 if device not in interfaces:
1218 newchoice_list.append((device, GLIUtility.get_interface_realname(device)))
1219 newchoice_list.append((_(u"Other"),_(u"Type your own.")))
1220 code, newnic = self._d.menu(_(u"Choose an interface from the list or Other to type your own if it was not detected."), choices=newchoice_list, width=75)
1221
1222 if newnic == _(u"Other"):
1223 code, newnic = self._d.inputbox(_(u"Enter name for new interface (eth0, ppp0, etc.)"))
1224 if code != self._DLG_OK:
1225 continue
1226 if newnic in interfaces:
1227 self._d.msgbox(_(u"An interface with the name is already defined."))
1228 continue
1229 #create the interface in the data structure.
1230 #interfaces[newnic] = ("", "", "")
1231 #Change the Yes/No buttons to new labels for this question.
1232 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
1233 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
1234 if self._d.yesno(net_string2, height=15, width=60) == self._DLG_YES: #DHCP
1235 dhcp_options = ""
1236 if self.advanced_mode:
1237 code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list. If you have none, just press Enter."), height=13, width=50)
1238 interfaces[newnic] = ('dhcp', dhcp_options, None)
1239 else:
1240 network_type = 'static'
1241 code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information) Your broadcast address is probably your IP address with 255 as the last tuple. Do not press Enter until all fields are complete!'),
1242 ((_(u'Enter your IP address:'), 15),
1243 (_(u'Enter your Broadcast address:'), 15),
1244 (_(u'Enter your Netmask:'),15,'255.255.255.0')))
1245 (ip_address, broadcast, netmask) = data[:-1].split('\n')
1246 if code != self._DLG_OK:
1247 continue
1248 #Set the info now that it's all gathered.
1249 interfaces[newnic] = (ip_address, broadcast, netmask)
1250 else: #they have chosen an interface, present them with edit/delete
1251 #Change the Yes/No buttons to new labels for this question.
1252 self._d.add_persistent_args(["--yes-label", _(u"Edit")])
1253 self._d.add_persistent_args(["--no-label", _(u"Delete")])
1254 if self._d.yesno(_(u"For interface %s, you can either edit the interface information (IP Address, Broadcast, Netmask) or Delete the interface.") % iface_choice) == self._DLG_YES:
1255 #Edit
1256 #Change the Yes/No buttons to new labels for this question.
1257 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
1258 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
1259 if self._d.yesno(net_string2, height=15, width=60) == self._DLG_YES: #DHCP
1260 dhcp_options = ""
1261 if self.advanced_mode:
1262 code, dhcp_options = self._d.inputbox(_(u"If you have any additional DHCP options to pass, type them here in a space-separated list. If you have none, just press Enter."), height=13, width=50)
1263 interfaces[iface_choice] = ('dhcp', dhcp_options, None)
1264 else:
1265 network_type = 'static'
1266 code, data = self._d.form(_(u'Enter your networking information: (See Chapter 3 of the Handbook for more information) Your broadcast address is probably your IP address with 255 as the last tuple. Do not press Enter until all fields are complete!'),
1267 ((_(u'Enter your IP address:'), 15, interfaces[iface_choice][0]),
1268 (_(u'Enter your Broadcast address:'), 15, interfaces[iface_choice][1]),
1269 (_(u'Enter your Netmask:'),15,interfaces[iface_choice][2])))
1270 (ip_address, broadcast, netmask) = data[:-1].split('\n')
1271 if code != self._DLG_OK:
1272 continue
1273 #Set the info now that it's all gathered.
1274 interfaces[iface_choice] = (ip_address, broadcast, netmask)
1275 else:
1276 #Delete
1277 #Reset the Yes/No buttons
1278 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1279 self._d.add_persistent_args(["--no-label", _(u"No")])
1280 if self._d.yesno(_(u"Are you sure you want to remove the interface ") + iface_choice + "?") == self._DLG_YES:
1281 del interfaces[iface_choice]
1282
1283 #This section is for defining DNS servers, default routes/gateways, hostname, etc.
1284 #First ask for the default gateway device and IP
1285 interfaces = self._install_profile.get_network_interfaces()
1286 choice_list = []
1287 for iface in interfaces:
1288 if interfaces[iface][0] == 'dhcp':
1289 choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1],0))
1290 else:
1291 choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+_(u" Netmask: ")+interfaces[iface][2],0))
1292 net_string3 = _(u"To be able to surf on the internet, you must know which host shares the Internet connection. This host is called the gateway. It is usually similar to your IP address, but ending in .1\nIf you have DHCP then just select your primary Internet interface (no IP will be needed) Start by choosing which interface accesses the Internet:")
1293 if choice_list:
1294 if len(choice_list) == 1: #Only one, no need for menu.
1295 gateway_iface = choice_list[0][0]
1296 else:
1297 code, gateway_iface = self._d.radiolist(net_string3, choices=choice_list, height=20, width=67)
1298 if (code == self._DLG_OK) or gateway_iface: #They made a choice. Ask the IP if not DHCP.
1299 while interfaces[gateway_iface][0] != 'dhcp':
1300 code, ip = self._d.inputbox(_(u"Enter the gateway IP address for ") + gateway_iface, init=interfaces[gateway_iface][0])
1301 if code != self._DLG_OK:
1302 break
1303 if not GLIUtility.is_ip(ip):
1304 self._d.msgbox(_(u"Invalid IP Entered! Please try again."))
1305 continue
1306 try:
1307 self._install_profile.set_default_gateway(None, ip,{'interface': gateway_iface})
1308 except:
1309 self._d.msgbox(_(u"ERROR! Coult not set the default gateway with IP %(ip)s for interface %(iface)s" % {'ip': ip, 'iface' : gateway_iface}))
1310 break
1311 #Now ask for the other info in a large form.
1312 error = True
1313 hostname = ""
1314 domainname = ""
1315 nisdomainname = ""
1316 primary_dns = ""
1317 backup_dns = ""
1318 http_proxy = ""
1319 ftp_proxy = ""
1320 rsync_proxy = ""
1321 while error:
1322 error = False
1323 if self.advanced_mode:
1324 code, data = self._d.form(_(u'Fill out the remaining networking settings. The hostname is manditory as that is the name of your computer. Leave the other fields blank if you are not using them. If using DHCP you do not need to enter DNS servers. Do not press Enter until all fields are complete!'),
1325 ((_(u'Enter your Hostname:'), 25, self._install_profile.get_hostname()),
1326 (_(u'Enter your Domain Name:'), 25, self._install_profile.get_domainname()),
1327 (_(u'Enter your NIS Domain Name:'),25,self._install_profile.get_nisdomainname()),
1328 (_(u'Enter a primary DNS server:'),15),
1329 (_(u'Enter a backup DNS server:'),15),
1330 (_(u'Enter a HTTP Proxy IP:'), 15,self._install_profile.get_http_proxy()),
1331 (_(u'Enter a FTP Proxy IP:'), 15, self._install_profile.get_ftp_proxy()),
1332 (_(u'Enter a RSYNC Proxy:'),15,self._install_profile.get_rsync_proxy())))
1333 if code != self._DLG_OK:
1334 return
1335 (hostname, domainname, nisdomainname, primary_dns, backup_dns, http_proxy, ftp_proxy, rsync_proxy) = data[:-1].split('\n')
1336 else: #standard mode
1337 code, data = self._d.form(_(u'Fill out the remaining networking settings. The hostname is manditory as that is the name of your computer. Leave the other fields blank if you are not using them. If using DHCP you do not need to enter DNS servers. Do not press Enter until all fields are complete!'),
1338 ((_(u'Enter your Hostname:'), 25, self._install_profile.get_hostname()),
1339 (_(u'Enter your Domain Name:'), 25, self._install_profile.get_domainname()),
1340 (_(u'Enter a primary DNS server:'),15),
1341 (_(u'Enter a backup DNS server:'),15)))
1342 if code != self._DLG_OK:
1343 return
1344 (hostname, domainname, primary_dns, backup_dns) = data[:-1].split('\n')
1345 #Check the data before entering it.
1346 if hostname:
1347 if type(hostname) != str:
1348 self._d.msgbox(_(u"Incorrect hostname! It must be a string. Not saved."))
1349 error = True
1350 else:
1351 try:
1352 self._install_profile.set_hostname(None, hostname, None)
1353 except:
1354 self._d.msgbox(_(u"ERROR! Could not set the hostname:")+hostname)
1355 error = True
1356 if domainname:
1357 if type(domainname) != str:
1358 self._d.msgbox(_(u"Incorrect domainname! It must be a string. Not saved."))
1359 error = True
1360 else:
1361 try:
1362 self._install_profile.set_domainname(None, domainname, None)
1363 except:
1364 self._d.msgbox(_(u"ERROR! Could not set the domainname:")+domainname)
1365 error = True
1366 if nisdomainname:
1367 if type(nisdomainname) != str:
1368 self._d.msgbox(_(u"Incorrect nisdomainname! It must be a string. Not saved."))
1369 error = True
1370 else:
1371 try:
1372 self._install_profile.set_nisdomainname(None, nisdomainname, None)
1373 except:
1374 self._d.msgbox(_(u"ERROR! Could not set the nisdomainname:")+nisdomainname)
1375 error = True
1376 if primary_dns:
1377 if not GLIUtility.is_ip(primary_dns):
1378 self._d.msgbox(_(u"Incorrect Primary DNS Server! Not saved."))
1379 error = True
1380 else:
1381 if backup_dns:
1382 if not GLIUtility.is_ip(backup_dns):
1383 self._d.msgbox(_(u"Incorrect Backup DNS Server! Not saved."))
1384 error = True
1385 else:
1386 primary_dns = primary_dns + " " + backup_dns
1387 try:
1388 self._install_profile.set_dns_servers(None, primary_dns, None)
1389 except:
1390 self._d.msgbox(_(u"ERROR! Could not set the DNS Servers:")+primary_dns)
1391 error = True
1392 if http_proxy:
1393 if not GLIUtility.is_uri(http_proxy):
1394 self._d.msgbox(_(u"Incorrect HTTP Proxy! It must be a uri. Not saved."))
1395 error = True
1396 else:
1397 try:
1398 self._install_profile.set_http_proxy(None, http_proxy, None)
1399 except:
1400 self._d.msgbox(_(u"ERROR! Could not set the HTTP Proxy:")+http_proxy)
1401 error = True
1402 if ftp_proxy:
1403 if not GLIUtility.is_uri(ftp_proxy):
1404 self._d.msgbox(_(u"Incorrect FTP Proxy! It must be a uri. Not saved."))
1405 error = True
1406 else:
1407 try:
1408 self._install_profile.set_ftp_proxy(None, ftp_proxy, None)
1409 except:
1410 self._d.msgbox(_(u"ERROR! Could not set the FTP Proxy:")+ftp_proxy)
1411 error = True
1412 if rsync_proxy:
1413 if not GLIUtility.is_uri(rsync_proxy):
1414 self._d.msgbox(_(u"Incorrect RSYNC Proxy! It must be a uri. Not saved."))
1415 error = True
1416 else:
1417 try:
1418 self._install_profile.set_rsync_proxy(None, rsync_proxy, None)
1419 except:
1420 self._d.msgbox(_(u"ERROR! Could not set the RSYNC Proxy:")+rsync_proxy)
1421 error = True
1422
1423
1424 def set_cron_daemon(self):
1425 if self.networkless: return
1426 cron_daemons = (("vixie-cron", _(u"Paul Vixie's cron daemon, fully featured, RECOMMENDED.")),
1427 ("dcron",_(u"A cute little cron from Matt Dillon.")),
1428 ("fcron", _(u"A scheduler with extended capabilities over cron & anacron")),
1429 ("None", _(u"Don't use a cron daemon. (NOT Recommended!)")))
1430 cron_string = _(u"A cron daemon executes scheduled commands. It is very handy if you need to execute some command regularly (for instance daily, weekly or monthly). Gentoo offers three possible cron daemons: dcron, fcron and vixie-cron. Installing one of them is similar to installing a system logger. However, dcron and fcron require an extra configuration command, namely crontab /etc/crontab. If you don't know what to choose, use vixie-cron. If doing a networkless install, choose vixie-cron. Choose your cron daemon:")
1431 code, menuitem = self._d.menu(cron_string, choices=cron_daemons, height=21, width=77)
1432 if code == self._DLG_OK:
1433 if menuitem == "None":
1434 menuitem = ""
1435 self._install_profile.set_cron_daemon_pkg(None, menuitem, None)
1436
1437 def set_logger(self):
1438 if self.networkless: return
1439 loggers = (("syslog-ng", _(u"An advanced system logger.")),
1440 ("metalog", _(u"A Highly-configurable system logger.")),
1441 ("syslogkd", _(u"The traditional set of system logging daemons.")))
1442 logger_string = _(u"Linux has an excellent history of logging capabilities -- if you want you can log everything that happens on your system in logfiles. This happens through the system logger. Gentoo offers several system loggers to choose from. If you plan on using sysklogd or syslog-ng you might want to install logrotate afterwards as those system loggers don't provide any rotation mechanism for the log files. If doing networkless, choose syslog-ng. Choose a system logger:")
1443 code, menuitem = self._d.menu(logger_string, choices=loggers, height=21, width=68)
1444 if code == self._DLG_OK:
1445 self._install_profile.set_logging_daemon_pkg(None, menuitem, None)
1446
1447 def set_extra_packages(self):
1448 #d.msgbox("This section is for selecting extra packages (pcmcia-cs, rp-pppoe, xorg-x11, etc.) and setting them up")
1449 if self._install_profile.get_install_packages():
1450 install_packages = self._install_profile.get_install_packages()
1451 if isinstance(install_packages, str):
1452 install_packages = install_packages.split()
1453 else:
1454 install_packages = []
1455 package_list = self._install_profile.get_install_package_list()
1456 highlevel_menu = []
1457 for group in package_list:
1458 highlevel_menu.append( (group, package_list[group][0]) )
1459 highlevel_menu.append( (_(u"Manual"), "Type your own space-separated list of packages.") )
1460
1461 while 1:
1462 extra_string1 = _(u"There are thousands of applications available to Gentoo users through Portage, Gentoo's package management system. Select some of the more common ones below or add your own additional package list by choosing 'Manual'.")
1463 code, submenu = self._d.menu(extra_string1+ _(u"\nYour current package list is: ")+string.join(install_packages, ','), choices=highlevel_menu, cancel=_(u"Save and Continue"), width=70, height=23)
1464 if code != self._DLG_OK: #Save and move on.
1465 try:
1466 packages = string.join(install_packages, ' ')
1467 if packages:
1468 self._install_profile.set_install_packages(None, packages, None)
1469 except:
1470 self._d.msgbox(_(u"ERROR! Could not set the install packages! List of packages:"))
1471 return
1472 #Popular Desktop Applications
1473 choices_list = []
1474 #pkgs = {}
1475
1476 #Special case first.
1477 if submenu == _(u"Manual"):
1478 code, tmp_install_packages = self._d.inputbox(_(u"Enter a space-separated list of extra packages to install on the system"), init=string.join(install_packages, ' '), width=70)
1479 if code == self._DLG_OK:
1480 install_packages = tmp_install_packages.split()
1481 continue
1482
1483 #All other cases load pkgs and GRP
1484 pkgs = package_list[submenu][1]
1485 grp_list = GLIUtility.get_grp_pkgs_from_cd()
1486 for pkg in pkgs:
1487 if pkg in grp_list:
1488 choices_list.append((pkg, "(GRP) "+pkgs[pkg], int(pkg in install_packages)))
1489 else:
1490 if not self.networkless:
1491 choices_list.append((pkg, pkgs[pkg], int(pkg in install_packages)))
1492 if not choices_list: continue
1493 code, choices = self._d.checklist(_(u"Choose from the listed packages. If doing a networkless install, only choose (GRP) packages."), choices=choices_list, height=19, list_height=10, width=77)
1494 if code != self._DLG_OK:
1495 continue
1496 for pkg in pkgs: #clear out packages from this list that are already in install_packages so that you can uncheck packages and they will be removed. the ones that remain checked will be re-added.
1497 for i, tmppkg in enumerate(install_packages):
1498 if tmppkg == pkg:
1499 del install_packages[i]
1500
1501 for package in choices:
1502 install_packages.append(package)
1503 #special cases for desktop environments
1504 if package in ["xorg-x11", "gnome","kde", "kde-meta","blackbox","enlightenment","e17", "fluxbox","xfce4"]: #ask about X
1505 #Add xorg-x11 if not already there.
1506 if not 'xorg-x11' in install_packages:
1507 install_packages.append('xorg-x11')
1508
1509 #Reset the Yes/No buttons
1510 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1511 self._d.add_persistent_args(["--no-label", _(u"No")])
1512 if not self.advanced_mode or self._d.yesno(_(u"Do you want to start X on bootup?")) == self._DLG_YES:
1513 services = self._install_profile.get_services() or 'xdm'
1514 if isinstance(services, list):
1515 services = string.join(services, ',')
1516 if not 'xdm' in services:
1517 services += ',xdm'
1518 try:
1519 self._install_profile.set_services(None, services, None)
1520 except:
1521 self._d.msgbox(_(u"ERROR! Could not set the services list."))
1522 #rc.conf changes specific to packages.
1523 if package == "gnome":
1524 etc_files = self._install_profile.get_etc_files()
1525 if not "rc.conf" in etc_files:
1526 etc_files['rc.conf'] = {}
1527 etc_files['rc.conf']['DISPLAYMANAGER'] = "gdm"
1528 self._install_profile.set_etc_files(etc_files)
1529 if package == "kde" or package == "kde-meta":
1530 etc_files = self._install_profile.get_etc_files()
1531 if not "rc.conf" in etc_files:
1532 etc_files['rc.conf'] = {}
1533 etc_files['rc.conf']['DISPLAYMANAGER'] = "kdm"
1534 self._install_profile.set_etc_files(etc_files)
1535 if package == "enlightenment":
1536 etc_files = self._install_profile.get_etc_files()
1537 if not "rc.conf" in etc_files:
1538 etc_files['rc.conf'] = {}
1539 etc_files['rc.conf']['DISPLAYMANAGER'] = "entrance"
1540 self._install_profile.set_etc_files(etc_files)
1541 if package == "fluxbox":
1542 etc_files = self._install_profile.get_etc_files()
1543 if not "rc.conf" in etc_files:
1544 etc_files['rc.conf'] = {}
1545 etc_files['rc.conf']['XSESSION'] = "fluxbox"
1546 self._install_profile.set_etc_files(etc_files)
1547
1548
1549
1550 def set_services(self):
1551 if self._install_profile.get_services():
1552 services = self._install_profile.get_services()
1553 if isinstance(services, str):
1554 services = services.split(',')
1555 else:
1556 services = []
1557 choice_list = [("alsasound", _(u"ALSA Sound Daemon"),int("alsasound" in services)),
1558 ("apache", _(u"Common web server (version 1.x)"),int("apache" in services)),
1559 ("apache2", _(u"Common web server (version 2.x)"),int("apache2" in services)),
1560 ("distccd", _(u"Distributed Compiling System"),int("distccd" in services)),
1561 ("esound", _(u"ESD Sound Daemon"),int("esound" in services)),
1562 ("hdparm", _(u"Hard Drive Tweaking Utility"),int("hdparm" in services)),
1563 ("local", _(u"Run scripts found in /etc/conf.d/local.start"),int("local" in services)),
1564 ("portmap", _(u"Port Mapping Service"),int("portmap" in services)),
1565 ("proftpd", _(u"Common FTP server"),int("proftpd" in services)),
1566 ("sshd", _(u"SSH Daemon (allows remote logins)"),int("sshd" in services)),
1567 ("xfs", _(u"X Font Server"),int("xfs" in services)),
1568 ("xdm", _(u"X Daemon"),int("xdm" in services)),
1569 (_(u"Other"),_(u"Manually specify your services in a comma-separated list."),0)]
1570 services_string = _(u"Choose the services you want started on bootup. Note that depending on what packages are selected, some services listed will not exist.")
1571 code, services_list = self._d.checklist(services_string, choices=choice_list, height=21, list_height=12, width=77)
1572 if code != self._DLG_OK:
1573 return
1574 services = []
1575 for service in services_list:
1576 services.append(service)
1577 if _(u"Other") in services_list:
1578 code, services = self._d.inputbox(_(u"Enter a comma-separated list of services to start on boot"), init=string.join(services, ','))
1579 if code != self._DLG_OK:
1580 return
1581 try:
1582 services = string.join(services, ',')
1583 if services:
1584 self._install_profile.set_services(None, services, None)
1585 except:
1586 self._d.msgbox(_(u"ERROR! Could not set the services list."))
1587 return
1588
1589 def set_rc_conf(self):
1590 # This section is for editing /etc/rc.conf
1591 if not self.advanced_mode:
1592 return
1593 etc_files = self._install_profile.get_etc_files()
1594 keymap = ""
1595 windowkeys = ""
1596 ext_keymap = ""
1597 font = ""
1598 trans = ""
1599 clock = ""
1600 editor = ""
1601 disp_manager = ""
1602 xsession = ""
1603 rc_string1 = _(u"Additional configuration settings for Advanced users (rc.conf)\nHere are some other variables you can set in various configuration files on the new system. If you don't know what a variable does, don't change it!")
1604 menulist = [("KEYMAP",_(u"Use KEYMAP to specify the default console keymap.")),
1605 ("SET_WINDOWKEYS", _(u"Decision to first load the 'windowkeys' console keymap")),
1606 ("EXTENDED_KEYMAPS", _(u"maps to load for extended keyboards. Most users will leave this as is.")),
1607 ("CONSOLEFONT", _(u"Specifies the default font that you'd like Linux to use on the console.")),
1608 ("CONSOLETRANSLATION", _(u"The charset map file to use.")),
1609 ("CLOCK", _(u"Set the clock to either UTC or local")),
1610 ("EDITOR", _(u"Set EDITOR to your preferred editor.")),
1611 ("DISPLAYMANAGER", _(u"What display manager do you use ? [ xdm | gdm | kdm | entrance ]")),
1612 ("XSESSION", _(u"a new variable to control what window manager to start default with X"))]
1613 while 1:
1614 code, variable = self._d.menu(rc_string1, choices=menulist, cancel=_(u"Save and Continue"), width=77, height=19)
1615 if code != self._DLG_OK:
1616 break
1617 if variable == "KEYMAP":
1618 keymap_list = GLIUtility.generate_keymap_list()
1619 code, keymap = self._d.menu(_(u"Choose your desired keymap:"), choices=self._dmenu_list_to_choices(keymap_list), height=19)
1620 if code != self._DLG_OK:
1621 continue
1622 keymap = keymap_list[int(keymap)-1]
1623
1624 elif variable == "SET_WINDOWKEYS":
1625 #Reset the Yes/No buttons
1626 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1627 self._d.add_persistent_args(["--no-label", _(u"No")])
1628 if self._d.yesno(_(u"Should we first load the 'windowkeys' console keymap? Most x86 users will say 'yes' here. Note that non-x86 users should leave it as 'no'.")) == self._DLG_YES:
1629 windowkeys = "yes"
1630 else:
1631 windowkeys = "no"
1632 elif variable == "EXTENDED_KEYMAPS":
1633 code, ext_keymap = self._d.inputbox(_(u"This sets the maps to load for extended keyboards. Most users will leave this as is. Enter new value for EXTENDED_KEYMAPS"), width=60)
1634 elif variable == "CONSOLEFONT":
1635 font_list = GLIUtility.generate_consolefont_list()
1636 code, font = self._d.menu(_(u"Choose your desired console font:"), choices=self._dmenu_list_to_choices(font_list), height=19)
1637 if code != self._DLG_OK:
1638 continue
1639 font = font_list[int(font)-1]
1640 elif variable == "CONSOLETRANSLATION":
1641 trans_list = GLIUtility.generate_consoletranslation_list()
1642 code, trans = self._d.menu(_(u"Choose your desired console translation:"), choices=self._dmenu_list_to_choices(trans_list), height=19)
1643 if code != self._DLG_OK:
1644 continue
1645 trans = trans_list[int(trans)-1]
1646 elif variable == "CLOCK":
1647 #Change the Yes/No buttons to new labels for this question.
1648 self._d.add_persistent_args(["--yes-label", "UTC"])
1649 self._d.add_persistent_args(["--no-label", "local"])
1650 if self._d.yesno(_(u"Should CLOCK be set to UTC or local? Unless you set your timezone to UTC you will want to choose local.")) == self._DLG_YES:
1651 clock = "UTC"
1652 else:
1653 clock = "local"
1654 elif variable == "EDITOR":
1655 choice_list = [("/bin/nano", _(u"Default editor.")), ("/usr/bin/vim", _(u"vi improved editor.")), ("/usr/bin/emacs", _(u"The emacs editor."))]
1656 code, editor = self._d.menu(_(u"Choose your default editor: "), choices=choice_list)
1657 elif variable == "DISPLAYMANAGER":
1658 choice_list = [("xdm", _(u"X Display Manager")),
1659 ("gdm", _(u"Gnome Display Manager")),
1660 ("kdm", _(u"KDE Display Manager")),
1661 ("entrance", _(u"Login Manager for Enlightenment"))]
1662 code, disp_manager = self._d.menu(_(u"Choose your desired display manager to use when starting X (note you must make sure that package also gets installed for it to work):"), choices=choice_list, width=65)
1663 elif variable == "XSESSION":
1664 code, xsession = self._d.inputbox(_(u"Choose what window manager you want to start default with X if run with xdm, startx, or xinit. (common options are Gnome or Xsession):"), width=65, height=12)
1665
1666 if not "conf.d/keymaps" in etc_files:
1667 if keymap or windowkeys or ext_keymap:
1668 etc_files['conf.d/keymaps'] = {}
1669 if not "conf.d/consolefont" in etc_files:
1670 if font or trans:
1671 etc_files['conf.d/consolefont'] = {}
1672 if not "conf.d/clock" in etc_files:
1673 if clock:
1674 etc_files['conf.d/clock'] = {}
1675 if not "rc.conf" in etc_files:
1676 if editor or disp_manager or xsession:
1677 etc_files['rc.conf'] = {}
1678 if keymap:
1679 etc_files['conf.d/keymaps']['KEYMAP'] = keymap
1680 if windowkeys:
1681 etc_files['conf.d/keymaps']['SET_WINDOWKEYS'] = windowkeys
1682 if ext_keymap:
1683 etc_files['conf.d/keymaps']['EXTENDED_KEYMAPS'] = ext_keymap
1684 if font:
1685 etc_files['conf.d/consolefont']['CONSOLEFONT'] = font
1686 if trans:
1687 etc_files['conf.d/consolefont']['CONSOLETRANSLATION'] = trans
1688 if clock:
1689 etc_files['conf.d/clock']['CLOCK'] = clock
1690 if editor:
1691 etc_files['rc.conf']['EDITOR'] = editor
1692 if disp_manager:
1693 etc_files['rc.conf']['DISPLAYMANAGER'] = disp_manager
1694 if xsession:
1695 etc_files['rc.conf']['XSESSION'] = xsession
1696 self._install_profile.set_etc_files(etc_files)
1697
1698 def set_root_password(self):
1699 # The root password will be set here
1700 while 1:
1701 code, passwd1 = self._d.passwordbox(_(u"Please enter your desired password for the root account. (note it will not show the password. Also do not try to use backspace.):"))
1702 if code != self._DLG_OK:
1703 return
1704 code, passwd2 = self._d.passwordbox(_(u"Enter the new root password again for confirmation"))
1705 if code != self._DLG_OK:
1706 return
1707 if passwd1 != passwd2:
1708 self._d.msgbox(_(u"The passwords do not match. Please try again or cancel."))
1709 else:
1710 try:
1711 self._install_profile.set_root_pass_hash(None, GLIUtility.hash_password(passwd1), None)
1712 except:
1713 self._d.msgbox(_(u"ERROR! Could not set the new system root password!"))
1714 self._d.msgbox(_(u"Password saved. Press Enter to continue."))
1715 return
1716
1717 def set_additional_users(self):
1718 # This section will be for adding non-root users
1719 users = {}
1720 for user in self._install_profile.get_users():
1721 users[user[0]] = (user[0], user[1], user[2], user[3], user[4], user[5], user[6])
1722 while 1:
1723 menu_list = []
1724 for user in users:
1725 menu_list.append(user)
1726 menu_list.sort()
1727 menu_list.append(_(u"Add user"))
1728 users_string1 = _(u"Working as root on a Unix/Linux system is dangerous and should be avoided as much as possible. Therefore it is strongly recommended to add a user for day-to-day use. Choose a user to edit:")
1729 code, menuitem = self._d.menu(users_string1, choices=self._dmenu_list_to_choices(menu_list), cancel=_(u"Save and Continue"), height=19)
1730 if code != self._DLG_OK:
1731 #if self._d.yesno("Do you want to save changes?") == self._DLG_YES:
1732 tmpusers = []
1733 for user in users:
1734 tmpusers.append(users[user])
1735 try:
1736 self._install_profile.set_users(tmpusers)
1737 except:
1738 self._d.msgbox(_(u"ERROR! Could not set the additional users!"))
1739 break
1740 menuitem = menu_list[int(menuitem)-1]
1741 if menuitem == _(u"Add user"):
1742 code, newuser = self._d.inputbox(_(u"Enter the username for the new user"))
1743 if code != self._DLG_OK:
1744 continue
1745 if newuser in users:
1746 self._d.msgbox(_(u"A user with that name already exists"))
1747 continue
1748 match = False
1749 while not match:
1750 code, passwd1 = self._d.passwordbox(_(u"Enter the new password for user %s. (will not be echoed)") % newuser)
1751 code, passwd2 = self._d.passwordbox(_(u"Enter the new password again for confirmation"))
1752 if code == self._DLG_OK:
1753 if passwd1 != passwd2:
1754 self._d.msgbox(_(u"The passwords do not match! Please try again."))
1755 else:
1756 match = True
1757 else:
1758 self._d.msgbox(_(u"You must enter a password for the user! Even a blank password will do. You can always edit it again later from the menu."));
1759 #Create the entry for the new user
1760 new_user = [newuser, GLIUtility.hash_password(passwd1), ('users',), '/bin/bash', '/home/' + newuser, '', '']
1761 users[newuser] = new_user
1762 menuitem = newuser
1763 while 1:
1764 menulist = [_(u"Password"), _(u"Group Membership"), _(u"Shell"), _(u"Home Directory"), _(u"UID"), _(u"Comment"), _(u"Delete")]
1765 code, menuitem2 = self._d.menu(_(u"Choose an option for user %s") % menuitem, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
1766 if code != self._DLG_OK:
1767 break
1768 menuitem2 = menulist[int(menuitem2)-1]
1769 if menuitem2 == _(u"Password"):
1770 code, passwd1 = self._d.passwordbox(_(u"Enter the new password"))
1771 if code != self._DLG_OK:
1772 continue
1773 code, passwd2 = self._d.passwordbox(_(u"Enter the new password again"))
1774 if code != self._DLG_OK:
1775 continue
1776 if passwd1 != passwd2:
1777 self._d.msgbox(_(u"The passwords do not match! Try again."))
1778 continue
1779 self._d.msgbox(_(u"Password saved. Press Enter to continue."))
1780 users[menuitem][1] = GLIUtility.hash_password(passwd1)
1781 elif menuitem2 == _(u"Group Membership"):
1782 prechk = users[menuitem][2]
1783 choice_list = [("users", _(u"The usual group for normal users."), int("users" in prechk)),
1784 ("wheel", _(u"Allows users to attempt to su to root."), int("wheel" in prechk)),
1785 ("audio", _(u"Allows access to audio devices."), int("audio" in prechk)),
1786 ("games", _(u"Allows access to games."), int("games" in prechk)),
1787 ("apache", _(u"For users who know what they're doing only."), int("apache" in prechk)),
1788 ("cdrom", _(u"For users who know what they're doing only."), int("cdrom" in prechk)),
1789 ("ftp", _(u"For users who know what they're doing only."), int("ftp" in prechk)),
1790 ("video", _(u"For users who know what they're doing only."), int("video" in prechk)),
1791 (_(u"Other"), _(u"Manually specify your groups in a comma-separated list."), 0)]
1792 users_string2 = _(u"Select which groups you would like the user %s to be in." % menuitem)
1793 code, group_list = self._d.checklist(users_string2, choices=choice_list, height=19, list_height=10, width=77)
1794 if code != self._DLG_OK:
1795 break
1796 groups = ""
1797 for group in group_list:
1798 groups += group + ","
1799 if groups:
1800 groups = groups[:-1]
1801 if _(u"Other") in group_list:
1802 code, groups = self._d.inputbox(_(u"Enter a comma-separated list of groups the user is to be in"), init=",".join(users[menuitem][2]))
1803 if code != self._DLG_OK: continue
1804 users[menuitem][2] = string.split(groups, ",")
1805 elif menuitem2 == _(u"Shell"):
1806 code, shell = self._d.inputbox(_(u"Enter the shell you want the user to use. default is /bin/bash. "), init=users[menuitem][3])
1807 if code != self._DLG_OK:
1808 continue
1809 users[menuitem][3] = shell
1810 elif menuitem2 == _(u"Home Directory"):
1811 code, homedir = self._d.inputbox(_(u"Enter the user's home directory. default is /home/username. "), init=users[menuitem][4])
1812 if code != self._DLG_OK:
1813 continue
1814 users[menuitem][4] = homedir
1815 elif menuitem2 == _(u"UID"):
1816 code, uid = self._d.inputbox(_(u"Enter the user's UID. If left blank the system will choose a default value (this is recommended)."), init=users[menuitem][5], height=11, width=55)
1817 if code != self._DLG_OK:
1818 continue
1819 if type(uid) != int:
1820 continue
1821 users[menuitem][5] = uid
1822 elif menuitem2 == _(u"Comment"):
1823 code, comment = self._d.inputbox(_(u"Enter the user's comment. This is completely optional."), init=users[menuitem][6])
1824 if code != self._DLG_OK:
1825 continue
1826 users[menuitem][6] = comment
1827 elif menuitem2 == _(u"Delete"):
1828 #Reset the Yes/No buttons
1829 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1830 self._d.add_persistent_args(["--no-label", _(u"No")])
1831 if self._d.yesno(_(u"Are you sure you want to delete the user %s ?") % menuitem) == self._DLG_YES:
1832 del users[menuitem]
1833 break
1834
1835 def save_install_profile(self, xmlfilename="", askforfilename=True):
1836 #Reset the Yes/No buttons
1837 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1838 self._d.add_persistent_args(["--no-label", _(u"No")])
1839 if self._d.yesno(_(u"Would you like to save these install settings for use again later?")) == self._DLG_YES:
1840 code = 0
1841 filename = xmlfilename
1842 if askforfilename:
1843 code, filename = self._d.inputbox(_(u"Enter a filename for the XML file. Use full path!"), init=xmlfilename)
1844 if code != self._DLG_OK or not filename:
1845 return None
1846 if GLIUtility.is_file(filename):
1847 if not self._d.yesno(_(u"The file %s already exists. Do you want to overwrite it?") % filename) == self._DLG_YES:
1848 return None
1849 try:
1850 configuration = open(filename ,"w")
1851 configuration.write(self._install_profile.serialize())
1852 configuration.close()
1853 except:
1854 self._d.msgbox(_(u"Error. File couldn't be saved. Saving to /tmp/installprofile.xml instead."))
1855 else:
1856 filename = "/tmp/installprofile.xml"
1857 try:
1858 configuration = open("/tmp/installprofile.xml", "w")
1859 configuration.write(self._install_profile.serialize())
1860 configuration.close()
1861 except:
1862 self._d.msgbox(_(u"Complete failure to save install profile!"))
1863 return filename
1864
1865 ############ RUN PHASE FUNCTIONS ############
1866 def run_phase1(self):
1867 self.set_arch_template()
1868 self.set_verbose()
1869 self.set_client_networking()
1870 self.set_enable_ssh()
1871 self.set_livecd_password()
1872 self.set_client_kernel_modules()
1873 def run_phase2(self):
1874 self.set_partitions()
1875 self.set_mounts()
1876 self.set_network_mounts()
1877 self.try_steps(['mount_local_partitions','mount_network_shares'])
1878 def run_phase3(self):
1879 self.set_install_stage()
1880 self.set_portage_tree()
1881 self.try_steps(['unpack_stage_tarball', 'update_config_files', 'configure_make_conf','prepare_chroot','install_portage_tree'])
1882 def run_phase4(self):
1883 self.set_make_conf()
1884 self.set_etc_portage()
1885 self.set_distcc()
1886 self.try_steps(['update_config_files', 'configure_make_conf', 'stage1', 'stage2', 'install_distcc'])
1887
1888 self.set_root_password()
1889 self.set_timezone()
1890 self.try_steps(['set_root_password','set_timezone'])
1891
1892 self.set_kernel()
1893 self.try_steps(['emerge_kernel_sources','build_kernel'])
1894
1895 self.set_networking()
1896 self.try_steps(['setup_network_post'])
1897
1898 if self.advanced_mode:
1899 self.set_cron_daemon()
1900 self.set_logger()
1901 self.try_steps(['install_logging_daemon','install_cron_daemon','install_filesystem_tools'])
1902
1903 self.set_boot_loader()
1904 self.try_steps(['install_bootloader','setup_and_run_bootloader'])
1905
1906 self.set_additional_users()
1907 self.try_steps(['set_users'])
1908
1909 self.set_extra_packages()
1910 if self.advanced_mode:
1911 self.set_services()
1912 self.set_rc_conf()
1913
1914 #Save the profile
1915 self.save_install_profile()
1916
1917 self.try_steps(['update_config_files','install_mta','install_packages','set_services','run_post_install_script','finishing_cleanup'])
1918
1919
1920
1921
1922 def run_phase5(self):
1923 #test function for getting steps.
1924 steps = ['do_recommended_partitioning',
1925 'mount_local_partitions',
1926 'mount_network_shares',
1927 'unpack_stage_tarball',
1928 'update_config_files',
1929 'configure_make_conf',
1930 'prepare_chroot',
1931 'install_portage_tree',
1932 'stage1',
1933 'stage2',
1934 'set_root_password',
1935 'set_timezone',
1936 'emerge_kernel_sources',
1937 'build_kernel',
1938 'install_distcc',
1939 'install_mta',
1940 'install_logging_daemon',
1941 'install_cron_daemon',
1942 'install_filesystem_tools',
1943 'setup_network_post',
1944 'install_bootloader',
1945 'setup_and_run_bootloader',
1946 'update_config_files',
1947 'set_users',
1948 'install_packages',
1949 # services for startup need to come after installing extra packages
1950 # otherwise some of the scripts will not exist.
1951 'set_services',
1952 'run_post_install_script',
1953 'finishing_cleanup']
1954
1955 self.try_steps(steps)
1956
1957 def finish_up(self):
1958 self._d.gauge_update(100, _(u"Install completed!"), update_text=1)
1959 self._d.gauge_stop()
1960 print _(u"Install done!")
1961 sys.exit(0)
1962
1963 def try_steps(self, steps):
1964 try:
1965 self.do_steps(steps)
1966 sys.stderr.write('\07') #BEEP
1967 except GLIException.GLIException, e:
1968 sys.stderr.write('\07') #BEEP
1969 error = e.get_error_msg()
1970 self.handle_exception(error,steps)
1971
1972 def handle_exception(self, error, steps):
1973 #Reset the Yes/No labels.
1974 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
1975 self._d.add_persistent_args(["--no-label",_(u"No")])
1976 message = _(u"There was an Exception received during the install that is outside of the normal install errors. This is a bad thing. The error was: %s \n You have several ways of handling this. If you cannot resolve it, please submit a bug report (after searching to make sure it's not a known issue and verifying you didn't do something stupid) with the contents of /var/log/install.log and /tmp/installprofile.xml and the version of the installer you used." % str(error))
1977 #options: 1. drop to console and retry 2. retry. 3. restart the phase 4. clean up and exit 5. don't clean up and exit.
1978 choices = ['Drop to console and then retry on return.',
1979 'Just retry the step.',
1980 #'Go back and change your choices.',
1981 'Clean up (unmount partitions) and exit.',
1982 'Just exit']
1983 code, choice = self._d.menu(message,choices=self._dmenu_list_to_choices(choices), width=77, height=22)
1984 if code == self._DLG_CANCEL:
1985 sys.exit(0)
1986 choice = choices[int(choice)-1]
1987 if choice == 'Drop to console and then retry on return.':
1988 GLIUtility.spawn_bash()
1989 self.try_steps(steps)
1990 elif choice == 'Just retry the step.':
1991 self.try_steps(steps) #Not sure if this will leave me in a bad spot.
1992 elif choice == 'Go back and change your choices.':
1993 sys.exit(0)
1994 elif choice == 'Clean up (unmount partitions) and exit.':
1995 self.do_steps(['install_failed_cleanup'])
1996 sys.exit(0)
1997 else: #just exit
1998 sys.exit(0)
1999
2000 def do_steps(self, install_steps):
2001 #Start the rest of the installation
2002 # INSTALLATION TIME
2003 # current_item = 0
2004 # self._cc.set_install_profile(self._install_profile)
2005 install_steps = list(install_steps)
2006 # self._cc.start_install()
2007 if self.just_starting == 1:
2008 self._d.gauge_start(_(u"Installation Started!"), title=_(u"Installation progress"), height="10")
2009 self.just_starting = 0
2010 else:
2011 self._d.gauge_start(_(u"Continuing Installation"), title=_(u"Installation progress"), height="10")
2012 self.num_steps_completed = 1
2013 self.num_steps = len(install_steps)
2014 step_name = install_steps.pop(0)
2015 next_step = self._cc.get_step_info(step_name)
2016 self._cc.run_step(step_name)
2017 i = 0
2018 while 1:
2019 notification = self._cc.getNotification()
2020 if notification == None:
2021 time.sleep(1)
2022 continue
2023 type_r = notification.get_type()
2024 data = notification.get_data()
2025 if type_r == "exception":
2026 #We need to raise an exception here. This will hopefully be caught by the calling function in a try/except block so that they can decide how best to handle this.
2027 raise GLIException.GLIException("DoStepFailure",'fatal','do_steps',str(data))
2028 elif type_r == "progress":
2029 #SECONDARY UPDATIN' GOIN ON IN HERE
2030 diff = (data[0]*100)/self.num_steps
2031 self._d.gauge_update(i+diff, _(u"On step %(A)d of %(B)d. Current step: %(C)s\n%(D)s" % {'A': self.num_steps_completed, 'B': self.num_steps, 'C': next_step, 'D': data[1]}), update_text=1)
2032 elif type_r == "int":
2033 if data == GLIClientController.NEXT_STEP_READY:
2034 if len(install_steps):
2035 step_name = install_steps.pop(0)
2036 else:
2037 return
2038 #print "Step name: " + step_name
2039 next_step = self._cc.get_step_info(step_name)
2040 # num_steps = self._cc.get_num_steps()
2041 i = (self.num_steps_completed*100)/self.num_steps
2042 self._d.gauge_update(i, _(u"On step %(A)d of %(B)d. Current step: %(C)s" % {'A': self.num_steps_completed, 'B': self.num_steps, 'C': next_step}), update_text=1)
2043 self.num_steps_completed += 1
2044 #print "Next step: " + next_step
2045 #if self._cc.has_more_steps():
2046 self._cc.run_step(step_name)
2047 continue
2048
2049 # --------------------------End of functions------------------------
2050 # --------------------------Beginning of MAIN-----------------------
2051 if __name__ == '__main__':
2052
2053
2054 #d = dialog.Dialog()
2055
2056 gli = GLIDialog()
2057
2058 gli.show_welcome_screen()
2059 gli.ask_load_profile()
2060 gli.ask_advanced_mode()
2061 gli.ask_networkless()
2062
2063
2064 gli.run_phase1() #Set up networking
2065 gli.run_phase2() #Do partitioning
2066 gli.run_phase3() #Install stage tarball and portage
2067 gli.run_phase4() #Do everything else
2068
2069 gli.finish_up()
2070
2071 sys.exit(0)
2072 #########################End of main#################################

Properties

Name Value
svn:eol-style native
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.20