/[gli]/trunk/src/GLIGenDialog.py
Gentoo

Contents of /trunk/src/GLIGenDialog.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 718 - (show annotations) (download) (as text)
Tue Jun 28 04:49:19 2005 UTC (9 years, 2 months ago) by codeman
File MIME type: text/x-python
File size: 68302 byte(s)
finished almost all internationalization of GenDialog.

1 import dialog, platform, string, os, glob, copy, re
2 import GLIInstallProfile
3 import GLIClientConfiguration
4 import GLIStorageDevice
5 import GLIUtility
6 import gettext
7 _ = gettext.gettext
8 #This is a parent class to centralize the code between UserGenCC and UserGenIP
9
10 class GLIGen(object):
11 def __init__(self):
12 self._d = dialog.Dialog()
13 self._DLG_OK = 0
14 self._DLG_YES = 0
15 self._DLG_CANCEL = 1
16 self._DLG_NO = 1
17 self._DLG_ESC = 2
18 self._DLG_ERROR = 3
19 self._DLG_EXTRA = 4
20 self._DLG_HELP = 5
21
22 def _dmenu_list_to_choices(self, list):
23 choices = []
24 for i in range(0, len(list)):
25 choices.append((str(i + 1), list[i]))
26
27 return choices
28
29 def client_profile(self):
30 return self._client_profile
31
32 def install_profile(self):
33 return self._install_profile
34
35 #This class will generate a client config and return it as a xml string
36 class GLIGenCF(GLIGen):
37 def __init__(self, client_profile, local_install=True, advanced_mode=True):
38 GLIGen.__init__(self)
39 self._client_profile = client_profile
40 self.local_install = local_install
41 self.advanced_mode = advanced_mode
42
43 def serialize(self):
44 return self._client_profile.serialize()
45 #-----------------------------------------------
46 #Functions for generating a client configuration
47 #-----------------------------------------------
48 def set_arch_template(self):
49 subarches = { 'i386': 'x86', 'i486': 'x86', 'i586': 'x86', 'i686': 'x86', 'x86_64': 'amd64', 'parisc': 'hppa' }
50 arch = platform.machine()
51 if arch in subarches:
52 arch = subarches[arch]
53 if self.local_install:
54 try:
55 self._client_profile.set_architecture_template(None, arch, None)
56 except:
57 self._d.msgbox(_(u"Error! Undefined architecture template specified or found on the current machine"))
58 else:
59 template_choices = ["x86", "amd64", "sparc", "alpha", "hppa", "ppc"]
60 string = _(u"Please select the architecture of the computer that gentoo will be installed on. For pentium and AMD 32-bit processors, choose x86. If you don't know your architecture, you should consider another Linux distribution.")
61 code, menuitem = self._d.menu(string, choices=self._dmenu_list_to_choices(template_choices), default_item=str(template_choices.index(arch)+1), height=20)
62 if code == self._DLG_OK:
63 menuitem = template_choices[int(menuitem)-1]
64 try:
65 self._client_profile.set_architecture_template(None, menuitem, None)
66 except:
67 self._d.msgbox(_(u"Error! Undefined architecture template specified or found on the current machine"))
68
69 def set_logfile(self):
70 #If not advanced, the default will suffice.
71 if self.advanced_mode:
72 string = _(u"""
73 The installer logs all important events during the install process to a logfile for debugging purposes.
74 The file gets copied to the new system once the install is complete.
75 Enter the desired filename and path for the install log (the default is recommended):""")
76 initval = self._client_profile.get_log_file()
77 code, logfile = self._d.inputbox(string, init=initval, width=60, height=15)
78 if code == self._DLG_OK:
79
80 self._client_profile.set_log_file(None, logfile, None)
81
82 def set_root_mount_point(self):
83 #If not advanced, the default will suffice.
84 if self.advanced_mode:
85 string = _(u"Enter the mount point to be used to mount the partition(s) where the new system will be installed. The default is /mnt/gentoo and is greatly recommended, but any mount point will do.")
86 initval = self._client_profile.get_root_mount_point()
87 code, rootmountpoint = self._d.inputbox(string, init=initval, width=60, height=11)
88 if code == self._DLG_OK:
89 self._client_profile.set_root_mount_point(None, rootmountpoint, None)
90
91 def set_client_networking(self):
92 if GLIUtility.ping("www.gentoo.org") and not self.advanced_mode: #If an active connection exists, ignore this step if standard mode
93 return
94 if self.local_install:
95 device_list = GLIUtility.get_eth_devices()
96 else:
97 device_list = []
98 choice_list = []
99 for device in device_list:
100 choice_list.append((device, GLIUtility.get_interface_realname(device)))
101 choice_list.append(("Other",_(u"Type your own.")))
102 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.")
103 code, interface = self._d.menu(string1, width=75, height=20, choices=choice_list)
104 if code != self._DLG_OK:
105 return
106 if interface == "Other":
107 code, interface = self._d.inputbox(_(u"Enter the interface (NIC) you would like to use for installation (e.g. eth0):"))
108 if code != self._DLG_OK:
109 return
110
111 #Not sure if I can get rid of these yet.
112 #network_type = ""
113 #ip_address = ""
114 #broadcast = ""
115 #netmask = ""
116 #gateway = ""
117 dhcp_options = ""
118
119 #Change the Yes/No buttons to new labels for this question.
120 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
121 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
122 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:")
123 if self._d.yesno(string2, height=15, width=60) == self._DLG_YES: #DHCP
124 network_type = 'dhcp'
125 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)
126 else:
127 network_type = 'static'
128 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!'), ((_(u'Enter your IP address:'), 15),(_(u'Enter your Broadcast address:'), 15),(_(u'Enter your Netmask:'),15,'255.255.255.0'),(_(u'Enter your default gateway:'),15), (_(u'Enter a DNS server:'),15,'128.118.25.3')))
129 (ip_address, broadcast, netmask, gateway, dnsservers) = data[:-1].split('\n')
130 if code != self._DLG_OK:
131 return
132 #Set the info now that it's all gathered.
133 try:
134 self._client_profile.set_network_type(None, network_type, None)
135 self._client_profile.set_network_interface(None, interface, None)
136 if not network_type == 'dhcp':
137 self._client_profile.set_network_ip(None, ip_address, None)
138 self._client_profile.set_network_broadcast(None, broadcast, None)
139 self._client_profile.set_network_netmask(None, netmask, None)
140 self._client_profile.set_network_gateway(None, gateway, None)
141 self._client_profile.set_dns_servers(None, dnsservers, None)
142 else:
143 if dhcp_options:
144 self._client_profile.set_network_dhcp_options(None, dhcp_options, None)
145 except:
146 self._d.msgbox(_(u"ERROR! Could not set networking information!"))
147
148 def set_enable_ssh(self):
149 #Change the Yes/No buttons back.
150 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
151 self._d.add_persistent_args(["--no-label", _(u"No")])
152 if self.advanced_mode:
153 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:
154 self._client_profile.set_enable_ssh(None, True, None)
155 else:
156 self._client_profile.set_enable_ssh(None, False, None)
157
158 def set_livecd_password(self):
159 # The root password will be set here only if in advanced mode. Otherwise it is auto-scrambled.
160 if self.advanced_mode:
161 match = False;
162 while not match:
163 string = _(u"""If you want to be able to login to your machine from another console during the installation,
164 you will want to enter a new root password for the LIVECD.
165 Note that this can be different from your new system's root password.
166 Presss Enter twice to skip this step.
167 Enter the new LIVECD root password: """)
168 code, passwd1 = self._d.passwordbox(string, width=60, height=16)
169 if code != self._DLG_OK:
170 return
171 code, passwd2 = self._d.passwordbox(_(u"Enter the new LIVECD root password again to verify:"))
172 if code != self._DLG_OK:
173 return
174 if passwd1 != passwd2:
175 self._d.msgbox(_(u"The passwords do not match. Please try again."))
176 return
177 else:
178 match = True;
179 if passwd1 != "": #don't want to hash an empty password.
180 try:
181 self._client_profile.set_root_passwd(None, GLIUtility.hash_password(passwd1), None)
182 except:
183 d.msgbox(_(u"ERROR! Could not set the root password on the LiveCD!"))
184 self._d.msgbox(_(u"Password saved. Press Enter to continue."))
185
186 def set_client_kernel_modules(self):
187 if self.advanced_mode:
188 status, output = GLIUtility.spawn("lsmod", return_output=True)
189 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")
190 self._d.add_persistent_args(["--exit-label", _(u"Continue")])
191 self._d.scrollbox(string1+output, height=20, width=70, title=_(u"Loaded Modules"))
192 string2 = _(u"\nIf you have additional modules you would like loaded before the installation begins (ex. a network driver), enter them in a space-separated list.")
193 code, kernel_modules_list = self._d.inputbox(string2, init="", width=60, height=12)
194 if code == self._DLG_OK:
195 try:
196 self._client_profile.set_kernel_modules(None, kernel_modules_list, None)
197 except:
198 d.msgbox(_(u"ERROR! Could not set the list of kernel modules!"))
199
200 def save_client_profile(self, xmlfilename="", askforfilename=True):
201 code = 0
202 filename = xmlfilename
203 if askforfilename:
204 code, filename = self._d.inputbox(_(u"Enter a filename for the XML file"), init=xmlfilename)
205 if code != self._DLG_OK:
206 return
207 if GLIUtility.is_file(filename):
208 #Change the Yes/No buttons back.
209 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
210 self._d.add_persistent_args(["--no-label", _(u"No")])
211 if not self._d.yesno(_(u"The file %s already exists. Do you want to overwrite it?") % filename) == self._DLG_YES:
212 return
213 configuration = open(filename ,"w")
214 configuration.write(self._client_profile.serialize())
215 configuration.close()
216
217 class GLIGenIP(GLIGen):
218 def __init__(self, client_profile, install_profile, local_install=True, advanced_mode=True):
219 GLIGen.__init__(self)
220 self._client_profile = client_profile
221 self._install_profile = install_profile
222 self.local_install = local_install
223 self.advanced_mode = advanced_mode
224 self._fn = (
225 { 'text': "Partitioning", 'fn': self._set_partitions },
226 { 'text': "Network mounts", 'fn': self._set_network_mounts },
227 { 'text': "Install Stage", 'fn': self._set_install_stage },
228 { 'text': "Portage Tree", 'fn': self._set_portage_tree },
229 { 'text': "make.conf", 'fn': self._set_make_conf },
230 { 'text': "Kernel", 'fn': self._set_kernel },
231 { 'text': "Bootloader", 'fn': self._set_boot_loader },
232 { 'text': "Timezone", 'fn': self._set_timezone },
233 { 'text': "Networking", 'fn': self._set_networking },
234 { 'text': "Cron daemon", 'fn': self._set_cron_daemon },
235 { 'text': "Logging daemon", 'fn': self._set_logger },
236 { 'text': "Extra packages", 'fn': self._set_extra_packages },
237 { 'text': "Services", 'fn': self._set_services },
238 { 'text': "rc.conf", 'fn': self._set_rc_conf },
239 { 'text': "Root password", 'fn': self._set_root_password },
240 { 'text': "Additional Users", 'fn': self._set_additional_users })
241 self._menu_list = []
242 for item in self._fn:
243 self._menu_list.append(item['text'])
244 current_item = 0
245 while 1:
246 code, menuitem = self._d.menu("Choose an option", choices=self._dmenu_list_to_choices(self._menu_list), default_item=str(current_item), height=23, menu_height=17, cancel="Done")
247 if code != self._DLG_OK:
248 break
249 current_item = int(menuitem)
250 menuitem = self._menu_list[int(menuitem)-1]
251 for item in self._fn:
252 if menuitem == item['text']:
253 item['fn']()
254 current_item += 1
255
256 def serialize(self):
257 return self._install_profile.serialize()
258 #---------------------------------------
259 #Functions to generate a install profile
260 #---------------------------------------
261 def _set_timezone(self):
262 # This section will be for setting the timezone.
263 zonepath = "/usr/share/zoneinfo"
264 skiplist = ["zone.tab","iso3166.tab","posixrules"]
265 while 1:
266 tzlist = []
267 for entry in os.listdir(zonepath):
268 if entry not in skiplist:
269 if os.path.isdir(zonepath + "/" + entry): entry += "/"
270 tzlist.append(entry)
271 tzlist.sort()
272 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.")
273 code, tznum = self._d.menu(string, choices=self._dmenu_list_to_choices(tzlist), height=20, cancel="Back")
274 if code == self._DLG_OK:
275 zonepath = os.path.join(zonepath,tzlist[int(tznum)-1])
276 if tzlist[int(tznum)-1][-1:] != "/":
277 break
278 else:
279 if zonepath == "/usr/share/zoneinfo":
280 return
281 slashloc = zonepath[:-1].rfind("/")
282 zonepath = zonepath[:slashloc]
283 try:
284 self._install_profile.set_time_zone(None, zonepath[20:], None)
285 except:
286 self._d.msgbox(_(u"ERROR: Could not set that timezone!"))
287
288 def _set_portage_tree(self):
289 # This section will ask whether to sync the tree, whether to use a snapshot, etc.
290 menulist = [("Sync", _(u"Normal. Use emerge sync RECOMMENDED!")), ("Webrsync", _(u"HTTP daily snapshot. Use when rsync is firewalled.")), ("Snapshot", _(u"Use a portage snapshot, either a local file or a URL")), ("None", _(u"Extra cases such as if /usr/portage is an NFS mount"))]
291 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=60, height=15, choices=menulist)
292 if code != self._DLG_OK:
293 return
294 #portage_tree_sync = menulist[int(portage_tree_sync)-1]
295 #FIX ME when python 2.4 comes out.
296 #if portage_tree_sync == "Normal 'emerge sync'":
297 # self._install_profile.set_portage_tree_sync_type(None, "sync", None)
298 #if portage_tree_sync == "Webrsync (rsync is firewalled)":
299 # self._install_profile.set_portage_tree_sync_type(None, "webrsync", None)
300 #if portage_tree_sync == "None (NFS mount)":
301 # self._install_profile.set_portage_tree_sync_type(None, "none", None)
302 #if portage_tree_sync == "Snapshot (using a portage snapshot)":
303 # self._install_profile.set_portage_tree_sync_type(None, "snapshot", None)
304 self._install_profile.set_portage_tree_sync_type(None, portage_tree_sync.lower(), None)
305 snapshot_options = (_(u"Use Local"), _(u"Specify URI"))
306 code, snapshot_option = self._d.menu(_(u"Select a local portage snapshot or manually specify a location:"), choices=self._dmenu_list_to_choices(snapshot_options))
307 snapshot_option = snapshot_options[int(snapshot_option)-1]
308 if snapshot_option == _(u"Use Local"):
309 snapshot_dir = "/mnt/cdrom/snapshots"
310 if os.path.isdir(snapshot_dir) and os.listdir(snapshot_dir):
311 local_snapshots = glob.glob(snapshot_dir + "/portage*.bz2")
312 if len(local_snapshots) == 1:
313 snapshot = local_snapshots[0]
314 else:
315 local_snapshots.sort()
316 code, snapshot = self._d.menu(_(u"Select a local portage snapshot:"), choices=self._dmenu_list_to_choices(local_snapshots))
317 if code != self._DLG_OK: return
318 snapshot = local_snapshots[int(snapshot)-1]
319 else:
320 self._d.msgbox(_(u"There don't seem to be any local portage snapshots available. Hit OK to manually specify a URI."))
321 snapshot_option = _(u"Specify URI")
322 if snapshot_option != _(u"Use Local"):
323 code, snapshot = self._d.inputbox(_(u"Enter portage tree snapshot URI"), init=self._install_profile.get_portage_tree_snapshot_uri())
324 if code == self._DLG_OK:
325 if snapshot:
326 if not GLIUtility.is_uri(snapshot, checklocal=self.local_install):
327 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."))
328 else:
329 self._install_profile.set_portage_tree_snapshot_uri(None, snapshot, None)
330
331 else:
332 self._d.msgbox(_(u"No URI was specified! Returning to default emerge sync."))
333 #if d.yesno("The specified URI is invalid. Use it anyway?") == DLG_YES: install_profile.set_stage_tarball_uri(None, stage_tarball, None)
334
335 def _set_partitions(self):
336 string1 = _("""The first thing on the new system to setup is the partitoning on the new system.
337 You will first select a drive and then edit its partitions.
338 No changes will be saved until the end of the step.
339 No changes to your disk will be made until the installation.
340 NOTE: YOU MUST AT LEAST SELECT ONE PARTITION AS YOUR ROOT PARTITION "/"
341 If your drive is pre-partitioned, just select the mountpoints and make
342 sure that the format option is set to FALSE or it will erase your data.
343 The installer does not yet support resizing of partitions (its not safe).
344 Please refer to the Gentoo Installation Handbook for more information
345 on partitioning and the various filesystem types available in Linux.""")
346 self._d.msgbox(string1, height=17, width=78)
347 devices = self._install_profile.get_partition_tables()
348 drives = devices.keys()
349 drives.sort()
350 choice_list = []
351 if not devices:
352 tmp_drives = GLIStorageDevice.detect_devices()
353 tmp_drives.sort()
354 for drive in tmp_drives:
355 devices[drive] = GLIStorageDevice.Device(drive)
356 if self.local_install:
357 devices[drive].set_partitions_from_disk()
358 drives.append(drive)
359 choice_list.append((drive, devices[drive].get_model()))
360 #choice_list.append(("Other", "Type your own drive name)) # I DONT THINK GLISD CAN DO NONEXISTANT DRIVES
361 while 1:
362 code, drive_to_partition = self._d.menu(_(u"Which drive would you like to partition?\n Info provided: Type, mkfs Options, Mountpoint, Mountopts, Size in MB"), choices=choice_list, cancel=_(u"Save and Continue"))
363 if code != self._DLG_OK: break
364 while 1:
365 partitions = devices[drive_to_partition].get_partitions()
366 partlist = devices[drive_to_partition].get_ordered_partition_list()
367 tmpparts = devices[drive_to_partition].get_partitions()
368 partsmenu = []
369 for part in partlist:
370 tmppart = tmpparts[part]
371 entry = ""
372 if tmppart.get_type() == "free":
373 #partschoice = "New"
374 entry = _(u" - Unallocated space (")
375 if tmppart.is_logical():
376 entry += _(u"logical, ")
377 entry += str(tmppart.get_mb()) + "MB)"
378 elif tmppart.get_type() == "extended":
379 entry = str(int(tmppart.get_minor()))
380 entry += _(u" - Extended Partition (") + str(tmppart.get_mb()) + "MB)"
381 else:
382 entry = str(int(tmppart.get_minor())) + " - "
383 # Type: " + tmppart.get_type() + ", Mountpoint: " + tmppart.get_mountpoint() + ", Mountopts: " + tmppart.get_mountopts() + "("
384 if tmppart.is_logical():
385 entry += _(u"Logical (")
386 else:
387 entry += _(u"Primary (")
388 entry += tmppart.get_type() + ", "
389 entry += (tmppart.get_mkfsopts() or "none") + ", "
390 entry += (tmppart.get_mountpoint() or "none") + ", "
391 entry += (tmppart.get_mountopts() or "none") + ", "
392 entry += str(tmppart.get_mb()) + "MB)"
393 partsmenu.append(entry)
394 code, part_to_edit = self._d.menu(_(u"Select a partition or unallocated space to edit"), width=70, choices=self._dmenu_list_to_choices(partsmenu), cancel=_(u"Back"))
395 if code != self._DLG_OK: break
396 part_to_edit = partlist[int(part_to_edit)-1]
397 tmppart = tmpparts[part_to_edit]
398 if tmppart.get_type() == "free":
399 # partition size first
400 free_mb = tmppart.get_mb()
401 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))
402 if code != self._DLG_OK: continue
403 if int(new_mb) > free_mb:
404 self._d.msgbox(_(u"The size you entered (%s MB) is larger than the maximum of %s MB") % (new_mb, str(free_mb)))
405 continue
406 # partition type
407 part_types = [("ext2", _(u"Old, stable, but no journaling")), ("ext3", _(u"ext2 with journaling and b-tree indexing (RECOMMENDED)")), ("linux-swap", _(u"Swap partition for memory overhead")), ("fat32", _(u"Windows filesystem format used in Win9X and XP")), ("ntfs", _(u"Windows filesystem format used in Win2K and NT")),("jfs", _(u"IBM's journaling filesystem. stability unknown.")), ("xfs", _(u"Don't use this unless you know you need it.")), ("reiserfs", _(u"B*-tree based filesystem. great performance. Only V3 supported.")), ("extended", _(u"Create an extended partition containing other logical partitions")), ("other", _(u"Something else we probably don't support."))]
408 code, type = self._d.menu(_(u"Choose the filesystem type for this new partition."), height=20, width=77, choices=part_types)
409 if code != self._DLG_OK: continue
410
411 # 'other' partition type
412 if type == "other":
413 code, type = self._d.inputbox(_(u"Please enter the new partition's type:"))
414 if code != self._DLG_OK: continue
415
416 # now add it to the data structure
417 devices[drive_to_partition].add_partition(part_to_edit, int(new_mb), 0, 0, type)
418 else:
419 while 1:
420 tmppart = tmpparts[part_to_edit]
421 tmptitle = drive_to_partition + str(part_to_edit) + " - "
422 if tmppart.is_logical():
423 tmptitle += _(u"Logical (")
424 else:
425 tmptitle += _(u"Primary (")
426 tmptitle += tmppart.get_type() + ", "
427 tmptitle += (tmppart.get_mkfsopts() or "none") + ", "
428 tmptitle += (tmppart.get_mountpoint() or "none") + ", "
429 tmptitle += (tmppart.get_mountopts() or "none") + ", "
430 tmptitle += str(tmppart.get_mb()) + "MB)"
431 menulist = [_(u"Delete"), _(u"Mount Point"), _(u"Mount Options"), _(u"Format"), _(u"Extra mkfs.* Parameters")]
432 code, part_action = self._d.menu(tmptitle, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
433 if code != self._DLG_OK: break
434 part_action = menulist[int(part_action)-1]
435 if part_action == _(u"Delete"):
436 answer = (self._d.yesno(_(u"Are you sure you want to delete the partition ") + drive_to_partition + str(part_to_edit) + "?") == self._DLG_YES)
437 if answer == True:
438 tmpdev = tmppart.get_device()
439 tmpdev.remove_partition(part_to_edit)
440 break
441 elif part_action == _(u"Mount Point"):
442 code, answer = self._d.inputbox(_(u"Enter a mountpoint for partition ") + str(part_to_edit), init=tmppart.get_mountpoint())
443 if code == self._DLG_OK: tmppart.set_mountpoint(answer)
444 elif part_action == _(u"Mount Options"):
445 code, answer = self._d.inputbox(_(u"Enter your mount options for partition ") + str(part_to_edit), init=(tmppart.get_mountopts() or "defaults"))
446 if code == self._DLG_OK: tmppart.set_mountopts(answer)
447 elif part_action == _(u"Format"):
448 code = d.yesno(_(u"Do you want to format this partition?"))
449 if code == self._DLG_YES:
450 tmppart.set_format(True)
451 else:
452 tmppart.set_format(False)
453 elif part_action == _(u"Extra mkfs.* Parameters"):
454 new_mkfsopts = tmppart.get_mkfsopts()
455 # extra mkfs options
456 if tmppart.get_type() != "extended":
457 code, new_mkfsopts = self._d.inputbox(_(u"Extra mkfs.* Parameters"), init=new_mkfsopts)
458 if code == self._DLG_OK: tmppart.set_mkfsopts(new_mkfsopts)
459 try:
460 self._install_profile.set_partition_tables(devices)
461 except:
462 self._d.msgbox(_(u"ERROR: The partition tables could not be set correctly!"))
463
464 def _set_network_mounts(self):
465 # This is where any NFS mounts will be specified
466 network_mounts = copy.deepcopy(self._install_profile.get_network_mounts())
467 while 1:
468 menulist = []
469 for mount in network_mounts:
470 menulist.append(mount['host'] + ":" + mount['export'])
471 menulist.append(_(u"Add a new network mount"))
472 choices = self._dmenu_list_to_choices(menulist)
473 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"))
474 if code == self._DLG_CANCEL:
475 try:
476 self._install_profile.set_network_mounts(network_mounts)
477 except:
478 self._d.msgbox(_(u"ERROR: Could net set network mounts!"))
479 break
480 menuitem = menulist[int(menuitemidx)-1]
481 if menuitem == _(u"Add a new network mount"):
482 code, nfsmount = self._d.inputbox(_(u"Enter NFS mount or just enter the IP/hostname to search for available mounts"))
483 if code != self._DLG_OK:
484 continue
485 if not GLIUtility.is_nfs(nfsmount):
486 if GLIUtility.is_ip(nfsmount) or GLIUtility.is_hostname(nfsmount):
487 status, remotemounts = GLIUtility.spawn("/usr/sbin/showmount -e " + nfsmount + " 2>&1 | egrep '^/' | cut -d ' ' -f 1 && echo", return_output=True)
488 if not len(remotemounts):
489 self._d.msgbox(_(u"No NFS exports were detected on ") + nfsmount)
490 continue
491 for i in range(0, len(remotemounts)):
492 remotemounts[i] = string.strip(remotemounts[i])
493 code, nfsmount2 = self._d.menu(_(u"Select a NFS export"), choices=self._dmenu_list_to_choices(remotemounts), cancel=_(u"Back"))
494 if code != self._DLG_OK:
495 continue
496 nfsmount2 = remotemounts[int(nfsmount2)-1]
497 else:
498 self._d.msgbox(_(u"The address you entered, %s, is not a valid IP or hostname. Please try again.") % nfsmount)
499 continue
500 else:
501 colon_location = nfsmount.find(':')
502 menuitem = nfsmount
503 nfsmount = menuitem[:colon_location]
504 nfsmount2 = menuitem[colon_location+1:]
505 for mount in network_mounts:
506 if nfsmount == mount['host'] and nfsmount2 == mount['export']:
507 self._d.msgbox(_(u"There is already an entry for ") + nfsmount + ":" + nfsmount2 + ".")
508 nfsmount = None
509 break
510 if nfsmount == None:
511 continue
512 network_mounts.append({'export': nfsmount2, 'host': nfsmount, 'mountopts': '', 'mountpoint': '', 'type': 'nfs'})
513 menuitem = nfsmount + ":" + nfsmount2
514 menuitemidx = len(network_mounts)
515
516 if menuitem.find(':') != -1:
517 colon_location = menuitem.find(':')
518 tmpmount = network_mounts[int(menuitemidx)-1]
519 code, mountpoint = self._d.inputbox(_(u"Enter a mountpoint"), init=tmpmount['mountpoint'])
520 if code == self._DLG_OK:
521 tmpmount['mountpoint'] = mountpoint
522 code, mountopts = self._d.inputbox(_(u"Enter mount options"), init=tmpmount['mountopts'])
523 if code == self._DLG_OK:
524 tmpmount['mountopts'] = mountopts
525 network_mounts[int(menuitemidx)-1] = tmpmount
526
527 def _set_make_conf(self):
528 # This section will be for setting things like CFLAGS, ACCEPT_KEYWORDS, and USE
529 make_conf = self._install_profile.get_make_conf()
530
531 self._d.msgbox(_(u"""The installer will now gather information regarding the contents of /etc/make.conf
532 One of the unique (and best) features of Gentoo is the ability to
533 define flags (called USE flags) that define what components are
534 compiled into applications. For example, you can enable the alsa
535 flag and programs that have alsa capability will use it.
536 The result is a finely tuned OS with no unnecessary components to
537 slow you down.
538 The installer divides USE flag selection into two screens, one for
539 global USE flags and one for local flags specific to each program.
540 Please be patient while the screens load. It may take awhile."""), width=73, height=16)
541
542 #Second set the USE flags, this is a biggie.
543 system_use_flags = GLIUtility.spawn("portageq envvar USE", return_output=True)[1].strip().split()
544 use_flags = []
545 use_local_flags = []
546 use_desc = {}
547 use_local_desc = {}
548 f = open("/usr/portage/profiles/use.desc", "r")
549 for line in f:
550 line = line.strip()
551 if not line or line.startswith("#"): continue
552 dash_pos = line.find(" - ")
553 if dash_pos == -1: continue
554 flagname = line[:dash_pos] or line[dash_pos-1]
555 desc = line[dash_pos+3:]
556 use_desc[flagname] = desc
557 f.close()
558
559 f = open("/usr/portage/profiles/use.local.desc", "r")
560 for line in f:
561 line = line.strip()
562 if not line or line.startswith("#"): continue
563 dash_pos = line.find(" - ")
564 if dash_pos == -1: continue
565 colon_pos = line.find(":", 0, dash_pos)
566 pkg = line[:colon_pos]
567 flagname = line[colon_pos+1:dash_pos] or line[colon_pos+1]
568 desc = "(" + pkg + ") " + line[dash_pos+3:]
569 use_local_desc[flagname] = desc
570 f.close()
571
572 #populate the choices list
573 sorted_use = use_desc.keys()
574 sorted_use.sort()
575 for flagname in sorted_use:
576 use_flags.append((flagname, use_desc[flagname], int(flagname in system_use_flags)))
577 #present the menu
578 code, use_flags = self._d.checklist(_(u"Choose which *global* USE flags you want on the new system"), height=25, width=80,list_height=19, choices=use_flags)
579
580 #populate the chocies list
581 sorted_use = use_local_desc.keys()
582 sorted_use.sort()
583 for flagname in sorted_use:
584 use_local_flags.append((flagname, use_local_desc[flagname], int(flagname in system_use_flags)))
585 #present the menu
586 code, use_local_flags = self._d.checklist(_(u"Choose which *local* USE flags you want on the new system"), height=25, width=80,list_height=19, choices=use_local_flags)
587 temp_use = "-* "
588 for flag in use_flags:
589 temp_use += flag + " "
590 for flag in use_local_flags:
591 temp_use += flag + " "
592 make_conf["USE"] = temp_use
593
594 #Second, set the ACCEPT_KEYWORDS
595 #Change the Yes/No buttons to new labels for this question.
596 self._d.add_persistent_args(["--yes-label", _(u"Stable")])
597 self._d.add_persistent_args(["--no-label", _(u"Unstable")])
598 if self._d.yesno(_(u"Do you want to run the normal stable portage tree, or the bleeding edge unstable (i.e. ACCEPT_KEYWORDS=arch)? If unsure select stable. Stable is required for GRP installs.")) == self._DLG_YES:
599 #Stable
600 make_conf["ACCEPT_KEYWORDS"] = ""
601 else: #Unstable
602 make_conf["ACCEPT_KEYWORDS"] = "~" + self._client_profile.get_architecture_template()
603 #Third, misc. stuff.
604 while 1:
605 menulist = [("CFLAGS",_(u"Edit your C Flags and Optimization level")), ("CHOST", _(u"Change the Host Setting")), ("MAKEOPTS", _(u"Specify number of parallel makes (-j) to perform. (ex. CPUs+1)")), ("FEATURES", _(u"Change portage functionality settings.")), ("GENTOO_MIRRORS", _(u"Specify mirrors to use for source retrieval.")), ("SYNC", _(u"Specify server used by rsync to sync the portage tree."))]
606 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"))
607 if code != self._DLG_OK:
608 self._install_profile.set_make_conf(make_conf)
609 break
610 oldval = ""
611 if make_conf.has_key(menuitem):
612 oldval = make_conf[menuitem]
613 code, newval = self._d.inputbox(_(u"Enter new value for ") + menuitem, init=oldval)
614 if code == self._DLG_OK:
615 make_conf[menuitem] = newval
616
617
618 def _set_kernel(self):
619 # This section will be for choosing kernel sources, choosing (and specifying) a custom config or genkernel, modules to load at startup, etc.
620 kernel_sources = [("vanilla-sources", _(u"The Unaltered Linux Kernel ver 2.6+ (safest)")), ("gentoo-sources", _(u"Gentoo's optimized 2.6+ kernel. (less safe)")), ("hardened-sources", _(u"Hardened sources for the 2.6 kernel tree")), ("grsec-sources",_(u"Vanilla sources with grsecurity patches")), ("livecd-kernel", _(u"Use the current running kernel for the new system (fastest)")), (_(u"Other"), _(u"Choose one of the other sources available."))]
621 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)
622 if code != self._DLG_OK:
623 return
624 if menuitem == _(u"Other"):
625 code, menuitem = self._d.inputbox(_(u"Please enter the desired kernel sources package name:"))
626 if code != self._DLG_OK: return
627 try:
628 self._install_profile.set_kernel_source_pkg(None, menuitem, None)
629 except:
630 self._d.msgbox(_(u"ERROR! Could not set the kernel source package!"))
631 if not menuitem == "livecd-kernel":
632 #Change the Yes/No buttons to new labels for this question.
633 self._d.add_persistent_args(["--yes-label", _(u"Genkernel")])
634 self._d.add_persistent_args(["--no-label", _(u"Traditional (requires config file!)")])
635 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.")
636 if self._d.yesno(string1, width=70, height=13) == self._DLG_YES: #Genkernel
637 self._install_profile.set_kernel_build_method(None,"genkernel", None)
638 #Change the Yes/No buttons back.
639 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
640 self._d.add_persistent_args(["--no-label", _(u"No")])
641 if self._d.yesno(_(u"Do you want the bootsplash screen to show up on bootup?")) == self._DLG_YES:
642 self._install_profile.set_kernel_bootsplash(None, True, None)
643 else:
644 self._install_profile.set_kernel_bootsplash(None, False, None)
645 else: #Custom
646 self._install_profile.set_kernel_build_method(None,"custom", None)
647
648 code, custom_kernel_uri = self._d.inputbox(_(u"If you have a custom kernel configuration, enter its location (otherwise just press Enter to continue):"))
649 if code == self._DLG_OK:
650 if custom_kernel_uri:
651 if not GLIUtility.is_uri(custom_kernel_uri, checklocal=self.local_install):
652 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."))
653 else:
654 try:
655 self._install_profile.set_kernel_config_uri(None, custom_kernel_uri, None)
656 except:
657 self._d.msgbox(_(u"ERROR! Could not set the kernel config URI!"))
658 #else: self._d.msgbox(_(u"No URI was specified! Reverting to using genkernel"))
659
660
661
662 def _set_install_stage(self):
663 # The install stage and stage tarball will be selected here
664 install_stages = (("1",_(u"Stage1 is used when you want to bootstrap and build the entire system from scratch.")), ("2",_(u"Stage2 is used for building the entire system from a bootstrapped semi-compiled state.")), ("3",_(u"Stage3 installation is a basic Gentoo Linux system that has been built for you (no compiling).")), ("3 + GRP", _(u"A Stage3 install but using binary packages from the LiveCD whenever possible")))
665 code, install_stage = self._d.menu(_(u"Which stage do you want to start at?"), choices=install_stages, cancel=_(u"Back"), width=77)
666 if code == self._DLG_OK:
667 if install_stage == "3 + GRP":
668 install_stage = "3"
669 try:
670 self._install_profile.set_grp_install(None, True, None)
671 self._install_profile.set_install_stage(None, install_stage, None)
672 except:
673 self._d.msgbox(_(u"ERROR! Could not set install stage!"))
674 #Change the Yes/No buttons to new labels for this question.
675 self._d.add_persistent_args(["--yes-label", _(u"Use Local")])
676 self._d.add_persistent_args(["--no-label", _(u"Specify URI")])
677 if self._d.yesno(_(u"Do you want to use a local tarball on the LiveCD (or other local location) or do you want to grab your stage tarball from the Internet?")) == self._DLG_YES:
678 #Use Local
679 stages_dir = "/mnt/cdrom/stages"
680 if os.path.isdir(stages_dir) and os.listdir(stages_dir):
681 local_tarballs = glob.glob(stages_dir + "/stage" + install_stage + "*.bz2")
682 local_tarballs.sort()
683 code, stage_tarball = self._d.menu(_(u"Select a local tarball:"), choices=self._dmenu_list_to_choices(local_tarballs))
684 if code != self._DLG_OK:
685 return
686 stage_tarball = local_tarballs[int(stage_tarball)-1]
687 try:
688 self._install_profile.set_stage_tarball_uri(None, stage_tarball, None)
689 except:
690 self._d.msgbox(_(u"ERROR: Could not set the stage tarball URI!"))
691 return
692 else:
693 self._d.msgbox(_(u"There don't seem to be any local tarballs available. Hit OK to manually specify a URI."))
694
695 #Specify URI
696 #subarches = { 'x86': ("x86", "i686", "pentium3", "pentium4", "athlon-xp"), 'hppa': ("hppa1.1", "hppa2.0"), 'ppc': ("g3", "g4", "g5", "ppc"), 'sparc': ("sparc32", "sparc64")}
697 type_it_in = False
698 stage_tarball = ""
699 if GLIUtility.ping("www.gentoo.org"): #Test for network connectivity
700 mirrors = GLIUtility.list_mirrors()
701 mirrornames = []
702 mirrorurls = []
703 for item in mirrors:
704 mirrornames.append(item[1])
705 mirrorurls.append(item[0])
706 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)
707 if code != self._DLG_OK:
708 type_it_in = True
709 else:
710 mirror = mirrorurls[int(mirror)-1]
711 arch = self._client_profile.get_architecture_template()
712 subarches = GLIUtility.list_subarch_from_mirror(mirror,arch)
713 code, subarch = self._d.menu(_(u"Select the sub-architecture that most closely matches your system (this changes the amount of optimization):"), choices=self._dmenu_list_to_choices(subarches))
714 if code != self._DLG_OK:
715 type_it_in = True
716 else:
717 subarch = subarches[int(subarch)-1]
718 tarballs = GLIUtility.list_stage_tarballs_from_mirror(mirror, arch, subarch)
719 code, stage_tarball = self._d.menu(_(u"Select your desired stage tarball:"), choices=self._dmenu_list_to_choices(tarballs))
720 if (code != self._DLG_OK):
721 type_it_in = True
722 else:
723 stage_tarball = mirror + "/releases/" + arch + "/current/stages/" + subarch + tarballs[int(stage_tarball)-1]
724 #get portageq envvar value of cflags and look for x86, i686,etc.
725 #URL SYNTAX
726 #http://gentoo.osuosl.org/releases/ARCHITECTURE/current/stages/SUB-ARCH/
727 else:
728 type_it_in = True
729 if type_it_in:
730 code, stage_tarball = self._d.inputbox(_(u"Specify the stage tarball URI or local file:"), init=self._install_profile.get_stage_tarball_uri())
731 if code != self._DLG_OK:
732 return
733 #If Doing a local install, check for valid file:/// uri
734 if stage_tarball:
735 if not GLIUtility.is_uri(stage_tarball, checklocal=self.local_install):
736 self._d.msgbox(_(u"The specified URI is invalid. It was not saved. Please go back and try again."));
737 else: self._install_profile.set_stage_tarball_uri(None, stage_tarball, None)
738 else: self._d.msgbox(_(u"No URI was specified!"))
739 #if d.yesno("The specified URI is invalid. Use it anyway?") == DLG_YES: install_profile.set_stage_tarball_uri(None, stage_tarball, None)
740
741 def _set_boot_loader(self):
742 arch = self._client_profile.get_architecture_template()
743 arch_loaders = { 'x86': [("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED")),("lilo",_(u"LInux LOader, older, traditional.(detects windows partitions)"))], 'amd64': [("grub",_(u"GRand Unified Bootloader, newer, RECOMMENDED"))]} #FIXME ADD OTHER ARCHS
744 boot_loaders = arch_loaders[arch]
745 boot_loaders.append(("none", _(u"Do not install a bootloader. (System may be unbootable!)")))
746 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")
747 code, menuitem = self._d.menu(string1, choices=boot_loaders)
748 if code != self._DLG_OK:
749 return
750 try:
751 self._install_profile.set_boot_loader_pkg(None, menuitem, None)
752 except:
753 self._d.msgbox(_(u"ERROR! Could not set boot loader pkg! ")+menuitem)
754 if menuitem != "none":
755 #Reset the Yes/No labels.
756 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
757 self._d.add_persistent_args(["--no-label",_(u"No")])
758 if self._d.yesno(_(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)")) == self._DLG_YES:
759 self._install_profile.set_boot_loader_mbr(None, True, None)
760 else:
761 self._install_profile.set_boot_loader_mbr(None, False, None)
762 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:"))
763 if code == self._DLG_OK:
764 try:
765 self._install_profile.set_bootloader_kernel_args(None, bootloader_kernel_args, None)
766 except:
767 self._d.msgbox(_(u"ERROR! Could not set bootloader kernel arguments! ")+bootloader_kernel_args)
768
769 def _set_networking(self):
770 # This section will be for setting up network interfaces
771 interfaces = self._install_profile.get_network_interfaces()
772 CC_iface = self._client_profile.get_network_interface()
773 if CC_iface and (CC_iface not in interfaces):
774 #The CC has a network config that's not already there. Preload it.
775 CC_net_type = self._client_profile.get_network_type()
776 if CC_net_type == 'dhcp':
777 try:
778 interfaces[CC_iface] = ('dhcp', self._client_profile.get_network_dhcp_options(), None)
779 except:
780 pass
781 else:
782 try:
783 interfaces[CC_iface] = (self._client_profile.get_network_ip(), self._client_profile.get_network_broadcast(), self._client_profile.get_network_netmask())
784 except:
785 pass
786
787 while 1:
788 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.")
789 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:")
790 choice_list = []
791 for iface in interfaces:
792 if interfaces[iface][0] == 'dhcp':
793 choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1]))
794 else:
795 choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+" Netmask: "+interfaces[iface][2]))
796 choice_list.append(("Add",_(u"Add a new network interface")))
797 code, iface_choice = self._d.menu(string1, choices=choice_list, cancel=_(u"Save and Continue"), height=18, width=67)
798 if code != self._DLG_OK:
799 try:
800 self._install_profile.set_network_interfaces(interfaces)
801 except:
802 self_d.msgbox(_(u"ERROR! Could not set the network interfaces!"))
803 break #This should hopefully move the user down to part two of set_networking
804 if iface_choice == "Add":
805 if self.local_install:
806 device_list = GLIUtility.get_eth_devices()
807 newchoice_list = []
808 for device in device_list:
809 if device not in interfaces:
810 newchoice_list.append((device, GLIUtility.get_interface_realname(device)))
811 newchoice_list.append((_(u"Other"),_(u"Type your own.")))
812 code, newnic = self._d.menu(_("Choose an interface from the list or Other to type your own if it was not detected."), choices=newchoice_list, width=75)
813 else:
814 newnic == _(u"Other")
815 if newnic == _(u"Other"):
816 code, newnic = self._d.inputbox(_(u"Enter name for new interface (eth0, ppp0, etc.)"))
817 if code != self._DLG_OK:
818 continue
819 if newnic in interfaces:
820 self._d.msgbox(_(u"An interface with the name is already defined."))
821 continue
822 #create the interface in the data structure.
823 #interfaces[newnic] = ("", "", "")
824 #Change the Yes/No buttons to new labels for this question.
825 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
826 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
827 if self._d.yesno(string2, height=15, width=60) == self._DLG_YES: #DHCP
828 dhcp_options = ""
829 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)
830 interfaces[newnic] = ('dhcp', dhcp_options, None)
831 else:
832 network_type = 'static'
833 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!'), ((_(u'Enter your IP address:'), 15),(_(u'Enter your Broadcast address:'), 15),(_(u'Enter your Netmask:'),15,'255.255.255.0')))
834 (ip_address, broadcast, netmask) = data[:-1].split('\n')
835 if code != self._DLG_OK:
836 continue
837 #Set the info now that it's all gathered.
838 interfaces[newnic] = (ip_address, broadcast, netmask)
839 else: #they have chosen an interface, present them with edit/delete
840 #Change the Yes/No buttons to new labels for this question.
841 self._d.add_persistent_args(["--yes-label", _(u"Edit")])
842 self._d.add_persistent_args(["--no-label", _(u"Delete")])
843 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:
844 #Edit
845 #Change the Yes/No buttons to new labels for this question.
846 self._d.add_persistent_args(["--yes-label", _(u"DHCP")])
847 self._d.add_persistent_args(["--no-label", _(u"Static IP/Manual")])
848 if self._d.yesno(string2, height=15, width=60) == self._DLG_YES: #DHCP
849 dhcp_options = ""
850 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)
851 interfaces[iface_choice] = ('dhcp', dhcp_options, None)
852 else:
853 network_type = 'static'
854 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!'), ((_(u'Enter your IP address:'), 15, interfaces[iface_choice][0]),(_(u'Enter your Broadcast address:'), 15, interfaces[iface_choice][1]),(_(u'Enter your Netmask:'),15,interfaces[iface_choice][2])))
855 (ip_address, broadcast, netmask) = data[:-1].split('\n')
856 if code != self._DLG_OK:
857 continue
858 #Set the info now that it's all gathered.
859 interfaces[iface_choice] = (ip_address, broadcast, netmask)
860 else:
861 #Delete
862 #Reset the Yes/No buttons
863 self._d.add_persistent_args(["--yes-label", _(u"Yes")])
864 self._d.add_persistent_args(["--no-label", _(u"No")])
865 if self._d.yesno(_(u"Are you sure you want to remove the interface ") + iface_choice + "?") == self._DLG_YES:
866 del interfaces[iface_choice]
867
868 #This section is for defining DNS servers, default routes/gateways, hostname, etc.
869 #First ask for the default gateway device and IP
870 interfaces = self._install_profile.get_network_interfaces()
871 choice_list = []
872 for iface in interfaces:
873 if interfaces[iface][0] == 'dhcp':
874 choice_list.append((iface, _(u"Settings: DHCP. Options: ")+ interfaces[iface][1],0))
875 else:
876 choice_list.append((iface, _(u"IP: ")+interfaces[iface][0]+_(u" Broadcast: ")+interfaces[iface][1]+" Netmask: "+interfaces[iface][2],0))
877 string3 = _("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:")
878 code, gateway_iface = self._d.radiolist(string3, choices=choice_list, height=18, width=67)
879 if code == self._DLG_OK: #They made a choice. Ask the IP if not DHCP.
880 while interfaces[gateway_iface][0] != 'dhcp':
881 code, ip = self._d.inputbox(_(u"Enter the gateway IP address for ") + gateway_iface, init=interfaces[gateway_iface][0])
882 if code != self._DLG_OK:
883 break
884 if not GLIUtility.is_ip(ip):
885 self._d.msgbox(_(u"Invalid IP Entered! Please try again."))
886 continue
887 try:
888 self._install_profile.set_default_gateway(None, ip,{'interface': gateway_iface})
889 except:
890 self._d.msgbox(_(u"ERROR! Coult not set the default gateway with IP %s for interface %s") % (ip, gateway_iface))
891 break
892 #Now ask for the other info in a large form.
893 error = True
894 while error:
895 error = False
896 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!'), ((_(u'Enter your Hostname:'), 25, self._install_profile.get_hostname()),(_(u'Enter your Domain Name:'), 25, self._install_profile.get_domainname()),(_(u'Enter your NIS Domain Name:'),25,self._install_profile.get_nisdomainname()),(_(u'Enter a primary DNS server:'),15),(_(u'Enter a backup DNS server:'),15), (_(u'Enter a HTTP Proxy IP:'), 15,self._install_profile.get_http_proxy()),(_(u'Enter a FTP Proxy IP:'), 15, self._install_profile.get_ftp_proxy()), (_(u'Enter a RSYNC Proxy:'),15,self._install_profile.get_rsync_proxy())))
897 if code != self._DLG_OK:
898 return
899 (hostname, domainname, nisdomainname, primary_dns, backup_dns, http_proxy, ftp_proxy, rsync_proxy) = data[:-1].split('\n')
900 #Check the data before entering it.
901 if hostname:
902 if type(hostname) != str:
903 self._d.msgbox(_(u"Incorrect hostname! It must be a string. Not saved."))
904 error = True
905 else:
906 try:
907 self._install_profile.set_hostname(None, hostname, None)
908 except:
909 self._d.msgbox(_(u"ERROR! Could not set the hostname:")+hostname)
910 error = True
911 if domainname:
912 if type(domainname) != str:
913 self._d.msgbox(_(u"Incorrect domainname! It must be a string. Not saved."))
914 error = True
915 else:
916 try:
917 self._install_profile.set_domainname(None, domainname, None)
918 except:
919 self._d.msgbox(_(u"ERROR! Could not set the domainname:")+domainname)
920 error = True
921 if nisdomainname:
922 if type(nisdomainname) != str:
923 self._d.msgbox(_(u"Incorrect nisdomainname! It must be a string. Not saved."))
924 error = True
925 else:
926 try:
927 self._install_profile.set_nisdomainname(None, nisdomainname, None)
928 except:
929 self._d.msgbox(_(u"ERROR! Could not set the nisdomainname:")+nisdomainname)
930 error = True
931 if primary_dns:
932 if not GLIUtility.is_ip(primary_dns):
933 self._d.msgbox(_(u"Incorrect Primary DNS Server! Not saved."))
934 error = True
935 else:
936 if backup_dns:
937 if not GLIUtility.is_ip(backup_dns):
938 self._d.msgbox(_(u"Incorrect Backup DNS Server! Not saved."))
939 error = True
940 else:
941 primary_dns = primary_dns + " " + backup_dns
942 try:
943 self._install_profile.set_dns_servers(None, primary_dns, None)
944 except:
945 self._d.msgbox(_(u"ERROR! Could not set the DNS Servers:")+primary_dns)
946 error = True
947 if http_proxy:
948 if not GLIUtility.is_uri(http_proxy):
949 self._d.msgbox(_(u"Incorrect HTTP Proxy! It must be a uri. Not saved."))
950 error = True
951 else:
952 try:
953 self._install_profile.set_http_proxy(None, http_proxy, None)
954 except:
955 self._d.msgbox(_(u"ERROR! Could not set the HTTP Proxy:")+http_proxy)
956 error = True
957 if ftp_proxy:
958 if not GLIUtility.is_uri(ftp_proxy):
959 self._d.msgbox(_(u"Incorrect FTP Proxy! It must be a uri. Not saved."))
960 error = True
961 else:
962 try:
963 self._install_profile.set_ftp_proxy(None, ftp_proxy, None)
964 except:
965 self._d.msgbox(_(u"ERROR! Could not set the FTP Proxy:")+ftp_proxy)
966 error = True
967 if rsync_proxy:
968 if not GLIUtility.is_uri(rsync_proxy):
969 self._d.msgbox(_(u"Incorrect RSYNC Proxy! It must be a uri. Not saved."))
970 error = True
971 else:
972 try:
973 self._install_profile.set_rsync_proxy(None, rsync_proxy, None)
974 except:
975 self._d.msgbox(_(u"ERROR! Could not set the RSYNC Proxy:")+rsync_proxy)
976 error = True
977
978 def _set_cron_daemon(self):
979 cron_daemons = (("vixie-cron", _(u"Paul Vixie's cron daemon, fully featured, RECOMMENDED.")), ("dcron",_(u"A cute little cron from Matt Dillon.")), ("fcron", _(u"A command scheduler with extended capabilities over cron and anacron")), ("None", _(u"Don't use a cron daemon. (NOT Recommended!)")))
980 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:")
981 code, menuitem = self._d.menu(string, choices=cron_daemons, height=21, width=68)
982 if code == self._DLG_OK:
983 if menuitem == "None":
984 menuitem = ""
985 self._install_profile.set_cron_daemon_pkg(None, menuitem, None)
986
987 def _set_logger(self):
988 loggers = (("syslog-ng", _(u"An advanced system logger.")), ("metalog", _(u"A Highly-configurable system logger.")), ("syslogkd", _(u"The traditional set of system logging daemons.")))
989 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. Choose a system logger:")
990 code, menuitem = self._d.menu(string, choices=loggers, height=21, width=68)
991 if code == self._DLG_OK:
992 self._install_profile.set_logging_daemon_pkg(None, menuitem, None)
993
994 def _set_extra_packages(self):
995 #d.msgbox("This section is for selecting extra packages (pcmcia-cs, rp-pppoe, xorg-x11, etc.) and setting them up")
996 install_packages = ""
997 while 1:
998 highlevel_menu = [(_(u"Desktop"), _(u"Popular Desktop Applications")), (_(u"Servers"), _(u"Applications often found on servers.")), (_(u"X11"), _(u"Window managers and X selection.")), (_(u"Misc"), _(u"Miscellaneous Applications you may want.")), (_(u"Recommended"), _(u"Applications recommended by the Gentoo Linux Installer Team.")), (_(u"Manual"), _(u"Type your own space-separated list of packages to install."))]
999 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'.")
1000 code, submenu = self._d.menu(string1+ _(u"\nYour current package list is: ")+install_packages, choices=highlevel_menu, cancel=_(u"Save and Continue"), width=70, height=23)
1001 if code != self._DLG_OK: #Save and move on.
1002 try:
1003 if install_packages[-1] == " ":
1004 install_packages = install_packages[:-1]
1005 self._install_profile.set_install_packages(None, install_packages, None)
1006 except:
1007 self._d.msgbox(_(u"ERROR! Could not set the install packages! List of packages:")+install_packages)
1008 return
1009 #Popular Desktop Applications
1010 choices_list = []
1011 if submenu == _(u"Desktop"):
1012 choices_list = [("gaim","GTK Instant Messenger client",0), ("gftp","Gnome based FTP Client",0), ("evolution","A GNOME groupware application, a Microsoft Outlook workalike",0), ("mozilla-firefox","The Mozilla Firefox Web Browser",0), ("mplayer","Media Player for Linux",0), ("openoffice","OpenOffice.org, a full office productivity suite.",0), ("openoffice-bin","Same as OpenOffice but a binary package (no compiling!)",0), ("realplayer","Real Media Player",0), ("xchat","Graphical IRC Client",0), ("xmms", "X MultiMedia System",0)]
1013 #Applications often found on servers.
1014 elif submenu == _(u"Servers"):
1015 choices_list = [("apache","Apache Web Server",0), ("iptables","Linux kernel (2.4+) firewall, NAT and packet mangling tools",0), ("proftpd","ProFTP Server",0), ("samba","SAMBA client/server programs for UNIX",0), ("traceroute","Utility to trace the route of IP packets",0)]
1016 #Window managers and X selection.
1017 elif submenu == _(u"X11"):
1018 choices_list = [("xorg-x11","An X11 implementation maintained by the X.Org Foundation.",0), ("gnome","The Gnome Desktop Environment",0), ("kde","The K Desktop Environment",0), ("blackbox","A small, fast, full-featured window manager for X",0), ("enlightenment","Enlightenment Window Manager",0), ("fluxbox","Fluxbox is an X11 window manager featuring tabs and an iconbar",0), ("xfce4","XFCE Desktop Environment",0)]
1019 #Miscellaneous Applications you may want.
1020 elif submenu == _(u"Misc"):
1021 choices_list = [("gkrellm","Single process stack of various system monitors",0), ("logrotate","Rotates, compresses, and mails system logs",0), ("slocate","Secure way to index and quickly search for files on your system",0), ("ufed","Gentoo Linux USE flags editor",0)]
1022 #Recommended by the Gentoo Linux Installer Team
1023 elif submenu == _(u"Recommended"):
1024 choices_list = [("anjuta","A versatile IDE for GNOME",0), ("chkrootkit","a tool to locally check for signs of a rootkit",0), ("crack-attack","Addictive OpenGL-based block game",0), ("enemy-territory","Return to Castle Wolfenstein: Enemy Territory",0), ("netcat","the network swiss army knife",0), ("nmap","A utility for network exploration or security auditing",0), ("screen","full-screen window manager that multiplexes between several processes",0)]
1025 elif submenu == _(u"Manual"):
1026 code, install_packages = self._d.inputbox(_(u"Enter a space-separated list of extra packages to install on the system"), init=install_packages, width=70)
1027 continue
1028 code, choices = self._d.checklist(_(u"Choose from the listed packages"), choices=choices_list, height=19, list_height=10, width=77)
1029 if code != self._DLG_OK:
1030 continue
1031 for package in choices:
1032 install_packages += package + " "
1033 def _set_rc_conf(self):
1034 # This section is for editing /etc/rc.conf
1035 rc_conf = self._install_profile.get_rc_conf()
1036 menulist = ["KEYMAP", "SET_WINDOWSKEYS", "EXTENDED_KEYMAPS", "CONSOLEFONT", "CONSOLETRANSLATION", "CLOCK", "EDITOR", "PROTOCOLS", "DISPLAYMANAGER", "XSESSION"]
1037 while 1:
1038 code, menuitem = self._d.menu("Choose a variable to edit", choices=self._dmenu_list_to_choices(menulist), cancel="Done")
1039 if code != self._DLG_OK:
1040 break
1041 menuitem = menulist[int(menuitem)-1]
1042 oldval = ""
1043 if rc_conf.has_key(menuitem):
1044 oldval = rc_conf[menuitem]
1045 code, newval = self._d.inputbox("Enter new value for " + menuitem, init=oldval)
1046 if code == self._DLG_OK:
1047 rc_conf[menuitem] = newval
1048 self._install_profile.set_rc_conf(rc_conf)
1049
1050 def _set_root_password(self):
1051 # The root password will be set here
1052 while 1:
1053 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.):"))
1054 if code != self._DLG_OK:
1055 return
1056 code, passwd2 = self._d.passwordbox(_(u"Enter the new root password again for confirmation"))
1057 if code != self._DLG_OK:
1058 return
1059 if passwd1 != passwd2:
1060 self._d.msgbox(_(u"The passwords do not match. Please try again or cancel."))
1061 else:
1062 try:
1063 self._install_profile.set_root_pass_hash(None, GLIUtility.hash_password(passwd1), None)
1064 except:
1065 self._d.msgbox(_(u"ERROR! Could not set the new system root password!"))
1066 self._d.msgbox(_(u"Password saved. Press Enter to continue."))
1067 return
1068
1069 def _set_additional_users(self):
1070 # This section will be for adding non-root users
1071 users = {}
1072 for user in self._install_profile.get_users():
1073 users[user[0]] = (user[0], user[1], user[2], user[3], user[4], user[5], user[6])
1074 while 1:
1075 menu_list = []
1076 for user in users:
1077 menu_list.append(user)
1078 menu_list.sort()
1079 menu_list.append(_(u"Add user"))
1080 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:")
1081 code, menuitem = self._d.menu(string1, choices=self._dmenu_list_to_choices(menu_list), cancel="Save and Continue")
1082 if code != self._DLG_OK:
1083 #if self._d.yesno("Do you want to save changes?") == self._DLG_YES:
1084 tmpusers = []
1085 for user in users:
1086 tmpusers.append(users[user])
1087 try:
1088 self._install_profile.set_users(tmpusers)
1089 except:
1090 self._d.msgbox(_(u"ERROR! Could not set the additional users!"))
1091 break
1092 menuitem = menu_list[int(menuitem)-1]
1093 if menuitem == _(u"Add user"):
1094 code, newuser = self._d.inputbox(_(u"Enter the username for the new user"))
1095 if code != self._DLG_OK:
1096 continue
1097 if newuser in users:
1098 self._d.msgbox(_(u"A user with that name already exists"))
1099 continue
1100 code, passwd1 = self._d.passwordbox(_(u"Enter the new password for user ")+ newuser)
1101 code, passwd2 = self._d.passwordbox(_(u"Enter the new password again for confirmation"))
1102 if code == self._DLG_OK:
1103 if passwd1 != passwd2:
1104 self._d.msgbox(_(u"The passwords do not match! Go to the menu and try again."))
1105 #Create the entry for the new user
1106 new_user = [newuser, GLIUtility.hash_password(passwd1), ('users',), '/bin/bash', '/home/' + newuser, '', '']
1107 users[newuser] = new_user
1108 menuitem = newuser
1109 while 1:
1110 menulist = [_(u"Password"), _(u"Group Membership"), _(u"Shell"), _(u"Home Directory"), _(u"UID"), _(u"Comment"), _(u"Delete")]
1111 code, menuitem2 = self._d.menu(_(u"Choose an option for user ") + menuitem, choices=self._dmenu_list_to_choices(menulist), cancel=_(u"Back"))
1112 if code != self._DLG_OK:
1113 break
1114 menuitem2 = menulist[int(menuitem2)-1]
1115 if menuitem2 == _(u"Password"):
1116 code, passwd1 = self._d.passwordbox(_(u"Enter the new password"))
1117 if code != self._DLG_OK:
1118 continue
1119 code, passwd2 = self._d.passwordbox(_(u"Enter the new password again"))
1120 if code != self._DLG_OK:
1121 continue
1122 if passwd1 != passwd2:
1123 self._d.msgbox(_(u"The passwords do not match! Try again."))
1124 continue
1125 self._d.msgbox(_(u"Password saved. Press Enter to continue."))
1126 users[menuitem][1] = GLIUtility.hash_password(passwd1)
1127 elif menuitem2 == _(u"Group Membership"):
1128 choice_list = [("users", _(u"The usual group for normal users."), 1), ("wheel", _(u"Allows users to attempt to su to root."), 0), ("audio", _(u"Allows access to audio devices."), 0), ("games", _(u"Allows access to games."), 0), ("apache", _(u"For users who know what they're doing only."), 0), ("cdrom", _(u"For users who know what they're doing only."), 0), ("ftp", _(u"For users who know what they're doing only."), 0), ("video", _(u"For users who know what they're doing only."), 0), (_(u"Other"), _(u"Manually specify your groups in a comma-separated list."), 0)]
1129 string2 = _(u"Select which groups you would like the user %s to be in." % menuitem)
1130 code, group_list = self._d.checklist(string2, choices=choice_list, height=19, list_height=10, width=68)
1131 groups = ""
1132 for group in group_list:
1133 groups += group + ","
1134 groups = groups[:-1]
1135 if _(u"Other") in group_list:
1136 code, groups = self._d.inputbox(_(u"Enter a comma-separated list of groups the user is to be in"), init=",".join(users[menuitem][2]))
1137 if code != self._DLG_OK: continue
1138 users[menuitem][2] = string.split(groups, ",")
1139 elif menuitem2 == _(u"Shell"):
1140 code, shell = self._d.inputbox(_(u"Enter the shell you want the user to use. default is /bin/bash. "), init=users[menuitem][3])
1141 if code != self._DLG_OK:
1142 continue
1143 users[menuitem][3] = shell
1144 elif menuitem2 == _(u"Home Directory"):
1145 code, homedir = self._d.inputbox(_(u"Enter the user's home directory. default is /home/username. "), init=users[menuitem][4])
1146 if code != self._DLG_OK:
1147 continue
1148 users[menuitem][4] = homedir
1149 elif menuitem2 == _(u"UID"):
1150 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])
1151 if code != self._DLG_OK:
1152 continue
1153 if type(uid) != int:
1154 continue
1155 users[menuitem][5] = uid
1156 elif menuitem2 == _(u"Comment"):
1157 code, comment = self._d.inputbox(_(u"Enter the user's comment. This is completely optional."), init=users[menuitem][6])
1158 if code != self._DLG_OK:
1159 continue
1160 users[menuitem][6] = comment
1161 elif menuitem2 == _(u"Delete"):
1162 if self._d.yesno(_(u"Are you sure you want to delete the user ") + menuitem + "?") == self._DLG_YES:
1163 del users[menuitem]
1164 break
1165
1166 def _set_services(self):
1167 choice_list = [("alsasound", _(u"ALSA Sound Daemon"),0), ("apache", _(u"Common web server (version 1.x)"),0), ("apache2", _(u"Common web server (version 2.x)"),0), ("distccd", _(u"Distributed Compiling System"),0), ("esound", _(u"ESD Sound Daemon"),0), ("hdparm", _(u"Hard Drive Tweaking Utility"),0), ("local", _(u"Run scripts found in /etc/conf.d/local.start"),0), ("portmap", _(u"Port Mapping Service"),0), ("proftpd", _(u"Common FTP server"),0), ("sshd", _(u"SSH Daemon (allows remote logins)"),0), (_(u"Other"),_(u"Manually specify your services in a comma-separated list."),0)]
1168 string = _(u"Choose the services you want started on bootup. Note that depending on what packages are selected, some services listed will not exist.")
1169 code, services_list = self._d.checklist(string, choices=choice_list, height=19, list_height=10, width=68)
1170 if code != self._DLG_OK:
1171 return
1172 services = ""
1173 for service in services_list:
1174 services += service + ","
1175 services = services[:-1]
1176 if _(u"Other") in services_list:
1177 code, services = self._d.inputbox(_(u"Enter a comma-separated list of services to start on boot"))
1178 if code != self._DLG_OK:
1179 return
1180 try:
1181 self._install_profile.set_services(None, services, None)
1182 except:
1183 self._d.msgbox(_(u"ERROR! Could not set the services list: "+ services))
1184
1185 def _save_install_profile(self, xmlfilename="", askforfilename=True):
1186 code = 0
1187 filename = xmlfilename
1188 if askforfilename:
1189 code, filename = self._d.inputbox(_(u"Enter a filename for the XML file"), init=xmlfilename)
1190 if code != self._DLG_OK:
1191 return None
1192 if GLIUtility.is_file(filename):
1193 if not self._d.yesno(_(u"The file %s already exists. Do you want to overwrite it?") % filename) == self._DLG_YES:
1194 return None
1195 configuration = open(filename ,"w")
1196 configuration.write(self._install_profile.serialize())
1197 configuration.close()
1198 return filename

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20