]>
Commit | Line | Data |
---|---|---|
13e6891b MT |
1 | #!/usr/bin/python |
2 | ||
3 | from snack import * | |
4 | ||
099849d4 MT |
5 | from storage.deviceaction import * |
6 | import storage | |
13e6891b | 7 | import storage.formats as formats |
2a4aeefe | 8 | from storage.devicelibs.lvm import safeLvmName |
13e6891b MT |
9 | |
10 | from constants import * | |
11 | ||
12 | import gettext | |
13 | _ = lambda x: gettext.ldgettext("pomona", x) | |
14 | ||
2a4aeefe MT |
15 | def logicalVolumeGroupList(installer): |
16 | storage = installer.ds.storage | |
17 | ||
18 | vgs = [] | |
19 | for vg in storage.vgs: | |
20 | vgs.append(vg.name) | |
21 | (button, choice) = ListboxChoiceWindow(installer.intf.screen, | |
22 | _("Volume Group Selection"), | |
23 | _("What language would you like to use during the " | |
24 | "installation process?"), vgs, | |
25 | buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], | |
26 | width = 30, scroll = 1, | |
27 | height = min((8, len(vgs)))) | |
28 | if button == TEXT_BACK_CHECK: | |
29 | return | |
30 | ||
31 | for vg in storage.vgs: | |
32 | if choice == vg.name: | |
33 | return vg | |
34 | return | |
35 | ||
13e6891b MT |
36 | class PartitionWindow(object): |
37 | def populate(self): | |
38 | self.lb.clear() | |
39 | ||
40 | for vg in self.storage.vgs: | |
2a4aeefe MT |
41 | self.lb.append([vg.name, "", "", "",], vg) |
42 | ||
43 | freespace = vg.freeSpace | |
44 | if freespace: | |
45 | self.lb.append([" %s" % _("Free Space"), "", "", "%dM" % freespace,], | |
46 | None, [LEFT, LEFT, LEFT, RIGHT]) | |
13e6891b MT |
47 | |
48 | for disk in self.storage.disks: | |
49 | self.lb.append([disk.path, "", "", "",], None) | |
50 | for part in self.storage.partitions: | |
51 | if disk == part.disk: | |
52 | mountpoint = type = "" | |
53 | if part.format: | |
54 | type = part.format.name | |
55 | try: | |
56 | mountpoint = part.format.mountpoint | |
57 | except AttributeError: | |
58 | pass | |
59 | self.lb.append([" %s" % part.name, | |
60 | mountpoint, | |
61 | type, | |
62 | "%dM" % part.size,], | |
63 | part, | |
64 | [LEFT, LEFT, LEFT, RIGHT]) | |
65 | ||
66 | def makeFileSystemList(self, device): | |
67 | grid = Grid(1, 2) | |
68 | ||
69 | label = Label(_("File System type:")) | |
70 | grid.setField(label, 0, 0) | |
71 | ||
72 | fstype = Listbox(height=4, scroll=1) | |
73 | for fs in sorted(formats.device_formats.values()): | |
74 | if not fs.supported: | |
75 | continue | |
76 | if fs.formattable: | |
77 | fstype.append(fs._type, fs) | |
78 | # XXX select default | |
79 | #current = formats.device_formats[formats.get_default_filesystem_type()] | |
80 | #print current | |
81 | #fstype.setCurrent(current) | |
82 | ### XXX Callback | |
83 | grid.setField(fstype, 0, 1) | |
84 | return (grid, fstype) | |
85 | ||
86 | def makeDriveList(self, device): | |
87 | grid = Grid(1, 2) | |
88 | ||
89 | label = Label(_("Allowable Drives:")) | |
90 | grid.setField(label, 0, 0) | |
91 | ||
92 | drivelist = CheckboxTree(height=4, scroll=1) | |
93 | for disk in self.storage.disks: | |
94 | drivelist.append(disk.name) | |
95 | grid.setField(drivelist, 0, 1) | |
96 | return (grid, drivelist) | |
97 | ||
98 | def makeMountPoint(self, device): | |
99 | grid = Grid(2, 1) | |
100 | label = Label(_("Mount Point:")) | |
101 | grid.setField(label, 0, 0, (0,0,0,0), anchorLeft = 1) | |
102 | ||
103 | try: | |
104 | mountpoint = device.format.mountpoint | |
105 | except AttributeError: | |
106 | mountpoint = "" | |
107 | mount = Entry(20, mountpoint) | |
108 | ||
109 | grid.setField(mount, 1, 0, anchorRight = 1, growx = 1) | |
110 | ||
111 | return (grid, mount) | |
2a4aeefe MT |
112 | |
113 | def makeVGName(self, device): | |
114 | grid = Grid(2, 1) | |
115 | label = Label(_("VG Name:")) | |
116 | grid.setField(label, 0, 0, (0,0,0,0), anchorLeft = 1) | |
117 | name = Entry(20, device.name) | |
118 | grid.setField(name, 1, 0, anchorRight = 1, growx = 1) | |
119 | return (grid, name) | |
13e6891b MT |
120 | |
121 | def newCb(self): | |
122 | choices = [_("Partition"), _("RAID"), _("Logical Volume Group")] | |
123 | ||
124 | if self.storage.vgs: | |
125 | choices.append(_("Logical Volume Device")) | |
126 | ||
127 | (button, choice) = ListboxChoiceWindow(self.installer.intf.screen, | |
128 | _("New device"), | |
129 | _("Which type of device do you want to create?\n\n"), | |
130 | choices, buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], | |
131 | width = 35, height = len(choices)) | |
132 | ||
133 | if button == TEXT_BACK_CHECK: | |
134 | return | |
135 | ||
136 | choice = choices[choice] | |
137 | if choice == _("Partition"): | |
2a4aeefe | 138 | self.newPart() |
13e6891b | 139 | elif choice == _("RAID"): |
2a4aeefe | 140 | pass # XXX self.newRaid() |
13e6891b | 141 | elif choice == _("Logical Volume Group"): |
2a4aeefe | 142 | self.newVG() |
13e6891b | 143 | elif choice == _("Logical Volume Device"): |
2a4aeefe MT |
144 | self.newLV() |
145 | ||
146 | def newPart(self): | |
147 | device = self.storage.newPartition() | |
148 | self.editPart(device=device) | |
13e6891b | 149 | |
2a4aeefe MT |
150 | def newVG(self): |
151 | device = self.storage.newVG() | |
152 | self.storage.createDevice(device) | |
153 | self.editVG(device=device) | |
154 | ||
155 | def newLV(self): | |
156 | vg = logicalVolumeGroupList(self.installer) | |
157 | if vg: | |
158 | device = self.storage.newLV(vg=vg) | |
159 | self.editLV(device=device) | |
13e6891b | 160 | |
2a4aeefe | 161 | def editPart(self, device): |
13e6891b MT |
162 | if not device: |
163 | return | |
164 | ||
165 | row = 0 | |
099849d4 | 166 | actions = [] |
13e6891b MT |
167 | |
168 | if not device.exists: | |
169 | tstr = _("Add Partition") | |
170 | else: | |
171 | tstr = _("Edit Partition") | |
172 | grid = GridForm(self.screen, tstr, 1, 6) | |
173 | ||
099849d4 MT |
174 | if device.exists: |
175 | if device.format.exists and getattr(device.format, "label", None): | |
176 | lbl = Label("%s %s" % (_("Original File System Label:"), device.format.label)) | |
177 | grid.add(lbl, 0, row) | |
178 | row += 1 | |
179 | ||
13e6891b MT |
180 | (mountgrid, mountpoint) = self.makeMountPoint(device) |
181 | grid.add(mountgrid, 0, row) | |
182 | row += 1 | |
183 | ||
184 | if not device.exists: | |
185 | subgrid1 = Grid(2, 1) | |
2a4aeefe MT |
186 | |
187 | (devgrid, drivelist) = self.makeDriveList(device) | |
099849d4 | 188 | subgrid1.setField(devgrid, 0, 0) |
13e6891b MT |
189 | |
190 | (fsgrid, fstype) = self.makeFileSystemList(device) | |
099849d4 | 191 | subgrid1.setField(fsgrid, 1, 0, (1,0,0,0), growx=1) |
13e6891b MT |
192 | |
193 | grid.add(subgrid1, 0, row, (0,1,0,0), growx=1) | |
194 | row += 1 | |
099849d4 MT |
195 | else: |
196 | pass | |
13e6891b MT |
197 | |
198 | bb = ButtonBar(self.screen, (TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON)) | |
199 | grid.add(bb, 0, row, (0,1,0,0), growx = 1) | |
200 | row += 1 | |
201 | ||
202 | while 1: | |
203 | rc = grid.run() | |
204 | button = bb.buttonPressed(rc) | |
205 | ||
206 | if button == TEXT_CANCEL_CHECK: | |
207 | break | |
208 | ||
209 | if mountpoint.value() and not mountpoint.value().startswith("/"): | |
210 | self.installer.intf.messageWindow(_("Error"), | |
211 | _("Mountpoint must be an absolute path.")) | |
212 | continue | |
213 | ||
214 | if device.format: | |
215 | device.format.mountpoint = mountpoint.value() | |
099849d4 MT |
216 | |
217 | if not device.exists: | |
218 | actions.append(ActionCreateDevice(self.installer, device)) | |
13e6891b MT |
219 | |
220 | break | |
221 | ||
222 | self.screen.popWindow() | |
099849d4 | 223 | return actions |
2a4aeefe MT |
224 | |
225 | def editVG(self, device): | |
226 | if not device.exists: | |
227 | tstr = _("Add Logical Volume Group") | |
228 | else: | |
229 | tstr = _("Edit Logical Volume Group") | |
230 | grid = GridForm(self.screen, tstr, 1, 6) | |
231 | row = 0 | |
232 | ||
233 | (namegrid, name) = self.makeVGName(device) | |
234 | grid.add(namegrid, 0, row) | |
235 | row += 1 | |
236 | ||
237 | # XXX size? | |
238 | ||
239 | bb = ButtonBar(self.screen, (TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON)) | |
240 | grid.add(bb, 0, row, (0,1,0,0), growx = 1) | |
241 | row += 1 | |
242 | ||
243 | while 1: | |
244 | rc = grid.run() | |
245 | button = bb.buttonPressed(rc) | |
246 | ||
247 | if button == TEXT_CANCEL_CHECK: | |
248 | break | |
249 | ||
250 | if not name.value(): | |
251 | self.installer.intf.messageWindow(_("Error"), | |
252 | _("You must enter a name for the " | |
253 | "Logical Volume Group.")) | |
254 | continue | |
255 | device.name = safeLvmName(name.value()) | |
256 | ||
257 | break | |
258 | ||
259 | self.screen.popWindow() | |
260 | ||
261 | editLV = editPart | |
13e6891b MT |
262 | |
263 | def editCb(self): | |
264 | device = self.lb.current() | |
265 | if not device: | |
266 | self.installer.intf.messageWindow(_("Unable To Edit"), | |
267 | _("You must first select a partition to edit.")) | |
268 | return | |
099849d4 MT |
269 | |
270 | reason = self.storage.deviceImmutable(device) | |
271 | if reason: | |
272 | self.installer.intf.messageWindow(_("Unable To Edit"), | |
273 | _("You cannot edit this device:\n\n%s") | |
274 | % reason,) | |
275 | return | |
13e6891b | 276 | |
099849d4 MT |
277 | actions = None |
278 | if device.type == "mdarray": | |
279 | pass #self.editRaidArray(device) | |
280 | elif device.type == "lvmvg": | |
281 | actions = self.editVG(device) | |
282 | elif device.type == "lvmlv": | |
283 | actions = self.editLV(device) | |
284 | elif isinstance(device, storage.devices.PartitionDevice): | |
285 | actions = self.editPart(device) | |
286 | ||
287 | for action in actions: | |
288 | self.storage.devicetree.registerAction(action) | |
13e6891b MT |
289 | |
290 | def deleteCb(self): | |
291 | device = self.lb.current() | |
099849d4 | 292 | |
13e6891b MT |
293 | if not device: |
294 | self.installer.intf.messageWindow(_("Unable To Delete"), | |
295 | _("You must first select a partition to delete.")) | |
296 | return | |
297 | ||
2a4aeefe MT |
298 | if device.type == "lvmvg": |
299 | text = _("Do you really want to delete the selected Logical Volume Group and " | |
300 | "all its Logical Volumes?") | |
301 | else: | |
302 | text = _("Do you really want to delete the selected partition?") | |
303 | ||
304 | if not self.installer.intf.messageWindow(_("Confirm Delete"), text, type="yesno"): | |
13e6891b MT |
305 | return |
306 | ||
307 | self.storage.destroyDevice(device) | |
308 | ||
309 | def __call__(self, installer): | |
310 | self.installer = installer | |
311 | self.screen = self.installer.intf.screen | |
312 | self.storage = self.installer.ds.storage | |
313 | ||
099849d4 | 314 | self.installer.intf.setHelpline(_("F2-New F3-Edit F4-Delete F5-Reset F12-OK")) |
13e6891b MT |
315 | |
316 | self.g = GridForm(self.screen, _("Partitioning"), 1, 5) | |
317 | self.lb = CListbox(height=10, cols=4, | |
318 | col_widths=[22,14,14,10], | |
319 | scroll=1, returnExit = 1, | |
320 | width=70, col_pad=2, | |
321 | col_labels=[_('Device'), _('Mount Point'), _("Filesystem"), _('Size') ], | |
322 | col_label_align=[LEFT, LEFT, LEFT, CENTER]) | |
323 | self.g.add(self.lb, 0, 1) | |
324 | ||
325 | self.bb = ButtonBar(self.screen, ((_("New"), "new", "F2"), | |
326 | (_("Edit"), "edit", "F3"), | |
327 | (_("Delete"), "delete", "F4"), | |
328 | TEXT_OK_BUTTON, TEXT_BACK_BUTTON)) | |
329 | ||
330 | self.g.add(self.bb, 0, 2, (0, 1, 0, 0)) | |
331 | self.g.addHotKey("F5") | |
332 | ||
333 | while 1: | |
334 | self.populate() | |
335 | rc = self.g.run() | |
336 | button = self.bb.buttonPressed(rc) | |
337 | ||
338 | if button == "new": | |
339 | self.newCb() | |
340 | elif button == "edit" or rc == self.lb.listbox: # XXX better way? | |
341 | self.editCb() | |
342 | elif button == "delete": | |
343 | self.deleteCb() | |
344 | elif button == "reset" or rc == "F5": | |
345 | self.storage.reset() | |
346 | elif button == TEXT_BACK_CHECK: | |
347 | self.storage.reset() | |
348 | ||
349 | self.screen.popHelpLine() | |
350 | self.screen.popWindow() | |
351 | return INSTALL_BACK | |
352 | else: | |
353 | #if not self.partitions.getRequestByMountPoint("/"): | |
354 | # self.intf.messageWindow(_("No Root Partition"), | |
355 | # _("Installation requires a / partition.")) | |
356 | # continue | |
357 | ||
358 | #(errors, warnings) = self.partitions.sanityCheckAllRequests(self.diskset) | |
359 | #rc = partitionSanityErrors(self.intf, errors) | |
360 | #if rc != 1: | |
361 | # continue | |
362 | ||
363 | #rc = partitionSanityWarnings(self.intf, warnings) | |
364 | #if rc != 1: | |
365 | # continue | |
366 | ||
367 | #warnings = getPreExistFormatWarnings(self.partitions, | |
368 | # self.diskset) | |
369 | #rc = partitionPreExistFormatWarnings(self.intf, warnings) | |
370 | #if rc != 1: | |
371 | # continue | |
372 | ||
373 | self.screen.popHelpLine() | |
374 | self.screen.popWindow() | |
375 | return INSTALL_OK | |
376 | ||
377 | return INSTALL_OK |