[pykickstart 1/3] return parsed object from assert_parse
by Brian C. Lane
From: "Brian C. Lane" <bcl(a)redhat.com>
This allows us to create tests that inspect the resulting object instead
of just testing to see if it parses.
---
tests/baseclass.py | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/tests/baseclass.py b/tests/baseclass.py
index 5efd4d2..9d9e8c3 100644
--- a/tests/baseclass.py
+++ b/tests/baseclass.py
@@ -86,21 +86,23 @@ class CommandTest(unittest.TestCase):
# If expectedStr supplied, we want to ensure the parsed result matches
if expectedStr is not None:
- result = parser.parse(args[1:])
+ obj = parser.parse(args[1:])
+ result = str(obj)
# Strip any comment lines ... we only match on non-comments
if ignoreComments:
- result = re.sub("^#[^\n]*\n", "", str(result))
+ result = re.sub("^#[^\n]*\n", "", result)
# Ensure we parsed as expected
- self.assertEqual(str(result), expectedStr)
+ self.assertEqual(result, expectedStr)
# No expectedStr supplied, just make sure it does not raise an
# exception
else:
try:
- result = parser.parse(args[1:])
+ obj = parser.parse(args[1:])
except Exception, e:
self.fail("Failed while parsing: %s" % e)
+ return obj
def assert_parse_error(self, inputStr, exception=KickstartParseError):
'''Assert that parsing the supplied string raises a
--
1.7.7.6
11 years, 9 months
[newui]
by David Lehman
This is just various things that ended up in my working tree
around another set that isn't ready yet.
11 years, 9 months
[PATCH 1/2] Fix GPT code to allocate space for /2/ tables.
by Peter Jones
17408 is the size of the table being made, but there's one at the
beginning and one at the end.
---
src/sbin/mkefiboot | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/sbin/mkefiboot b/src/sbin/mkefiboot
index fb695ed..a50cb5b 100755
--- a/src/sbin/mkefiboot
+++ b/src/sbin/mkefiboot
@@ -92,15 +92,16 @@ def macmunge(imgfile, product):
def mkefidisk(efiboot, outfile):
'''Make a bootable EFI disk image out of the given EFI boot image.'''
- # pjones sez: "17408 is the size of the GPT tables parted creates"
- partsize = os.path.getsize(efiboot) + 17408
- disksize = round_to_blocks(17408 + partsize, 512)
+ # pjones sez: "17408 is the size of the GPT tables parted creates,
+ # but there are two of them."
+ partsize = os.path.getsize(efiboot) + 17408 * 2
+ disksize = round_to_blocks(2 * 17408 + partsize, 512)
with LoopDev(outfile, disksize) as loopdev:
with DMDev(loopdev, disksize) as dmdev:
check_call(["parted", "--script", "/dev/mapper/%s" % dmdev,
"mklabel", "gpt",
"unit", "b",
- "mkpart", "'EFI System Partition'", "fat32", "17408", str(partsize),
+ "mkpart", "'EFI System Partition'", "fat32", "34816", str(partsize),
"set", "1", "boot", "on"], stdout=PIPE, stderr=PIPE)
partdev = "/dev/mapper/{0}p1".format(dmdev)
with open(efiboot, "rb") as infile:
--
1.7.10.4
11 years, 9 months
[PATCH 1/2] Fix GPT code to allocate space for /2/ tables.
by Peter Jones
17408 is the size of the table being made, but there's one at the
beginning and one at the end.
---
src/sbin/mkefiboot | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/sbin/mkefiboot b/src/sbin/mkefiboot
index fb695ed..f008e19 100755
--- a/src/sbin/mkefiboot
+++ b/src/sbin/mkefiboot
@@ -92,15 +92,16 @@ def macmunge(imgfile, product):
def mkefidisk(efiboot, outfile):
'''Make a bootable EFI disk image out of the given EFI boot image.'''
- # pjones sez: "17408 is the size of the GPT tables parted creates"
- partsize = os.path.getsize(efiboot) + 17408
- disksize = round_to_blocks(17408 + partsize, 512)
+ # pjones sez: "17408 is the size of the GPT tables parted creates,
+ # but there are two of them."
+ partsize = os.path.getsize(efiboot) * 3 + 17408 * 2
+ disksize = round_to_blocks(2 * 17408 + partsize, 512)
with LoopDev(outfile, disksize) as loopdev:
with DMDev(loopdev, disksize) as dmdev:
check_call(["parted", "--script", "/dev/mapper/%s" % dmdev,
"mklabel", "gpt",
"unit", "b",
- "mkpart", "'EFI System Partition'", "fat32", "17408", str(partsize),
+ "mkpart", "'EFI System Partition'", "fat32", "34816", str(partsize),
"set", "1", "boot", "on"], stdout=PIPE, stderr=PIPE)
partdev = "/dev/mapper/{0}p1".format(dmdev)
with open(efiboot, "rb") as infile:
--
1.7.10.4
11 years, 9 months
[RFC] [PATCH newui] Rework software selection to be driven by comps metadata
by Bill Nottingham
This series of patches changes how the software selection in anaconda works so
that it is completely driven by new metadata in comps.
HOW IT'S SUPPOSED TO WORK
-------------------------
The metadata in comps is of the form:
<installclass>
<id>gnome-desktop</id>
<name>GNOME Desktop</name>
<description>GNOME is a desktop.</description>
<display_order>10</display_order>
<grouplist>
<groupid>base-x</groupid>
<groupid>base</groupid>
<groupid>core</groupid>
<groupid>fonts</groupid>
...
</grouplist>
<optionlist>
<groupid>sound-and-video</groupid>
<groupid>office</groupid>
<groupid>eclipse</groupid>
<groupid>games</groupid>
<groupid>design-suite</groupid>
<groupid>electronic-lab</groupid>
</optionlist>
</installclass>
<installclass>
<id>minimal</id>
<name>Minimal installation</name>
<description>A bare-bones shell environment, useful for building your own custom system.</description>
<display_order>05</display_order>
<grouplist>
<groupid>core</groupid>
</grouplist>
<optionlist>
<groupid>cloud-infrastructure</groupid>
<groupid>clustering</groupid>
<groupid>directory-server</groupid>
<groupid>dns-server</groupid>
...
</optionlist>
</installclass>
For any interactive installation, the user will first pick an installclass
from the left column. Once they've done that, the right column will populate
with the combination of:
1) any groupids from the 'optionlist' for that install class
2) any groups in comps that are marked as 'uservisible'
and the user can select any of these to add onto their installation.
The second of these is for some level of backwards compatibility with existing
third-party repositories.
TESTING/FUTURE WORK
-------------------
Tested via qemu via a test repository with a modified comps file:
(http://notting.fedorapeople.org/foorepo)
This repo has no packages, so not tested for full installation, but should work
as a demonstration. Full deployment of this feature would likely involve some
more drastic changes to the comps file once this format is agreed upon.
This has not been wired into:
- pykickstart/kickstart files
Should be doable; need to pick a reasonable character to use as a signifier. ('^'?
'$'?)
- yum via commands (there is no 'yum installclass-install minimal', for example.)
CAVEATS
-------
If we go this route, we would need to land, in order:
- yum changes
- comps changes
- anaconda changes
Derived distributions would have to adopt the new metadata in comps to work with
anaconda.
COMMENTS?
---------
Please, comment away.
yum changes:
comps.py | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 197 insertions(+)
anaconda changes:
packaging/__init__.py | 21 +++++++++
packaging/yumpayload.py | 102 +++++++++++++++++++++++++++++++++++++++++++++-
ui/gui/spokes/software.py | 93 ++++++++++++++++++++---------------------
ui/gui/spokes/software.ui | 22 +++++----
4 files changed, 178 insertions(+), 60 deletions(-)
11 years, 9 months
[PATCH] Text based UI framework core
by Martin Sivak
Hi,
this is an attempt to implement basic line only textual
UI framework for us to use.
It is condeptualy designed as stack of screens, where
the screen at the top is visible.
Individual screens can be implemented using the UIScreen parent
class and two methods: show and input
Active screens can (according to user input) be changed in four
ways:
- new screen is put onto the stack and the old one is
replaced (Next button equivalent)
- new screen is put onto the stack (Hub wants to show
Spoke with the possibility of direct return)
- new screen is displayed and the call returns to the
caller after it is closed (Dialog with data)
- screen is closed (and the next item from the stack is
displayed)
This means that the leaves (Spokes) do not have to know which
screen they should return back to.
There is no global dispatcher list in this architecture. If you
want to setup inital list of linear progression screens, use the
App.schedule_screen call.
I also included two "widgets" for us to structure the screen space
without using scrolling or curses. Text and Column. Widgets first
render to their internal buffers to determine size and the parent
then copies the "image" to it's own buffer space.
You can see the very simple examples of use at the ends of
individual files.
---
pyanaconda/ui/tui/simpleline/__init__.py | 23 ++
pyanaconda/ui/tui/simpleline/base.py | 337 ++++++++++++++++++++++++++++++
pyanaconda/ui/tui/simpleline/widgets.py | 78 +++++++
3 files changed, 438 insertions(+)
create mode 100644 pyanaconda/ui/tui/simpleline/__init__.py
create mode 100644 pyanaconda/ui/tui/simpleline/base.py
create mode 100644 pyanaconda/ui/tui/simpleline/widgets.py
diff --git a/pyanaconda/ui/tui/simpleline/__init__.py b/pyanaconda/ui/tui/simpleline/__init__.py
new file mode 100644
index 0000000..e290e4a
--- /dev/null
+++ b/pyanaconda/ui/tui/simpleline/__init__.py
@@ -0,0 +1,23 @@
+# Library containing the TUI framework for Anaconda installer.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Martin Sivak <msivak(a)redhat.com>
+#
+
+from base import *
+from widgets import *
diff --git a/pyanaconda/ui/tui/simpleline/base.py b/pyanaconda/ui/tui/simpleline/base.py
new file mode 100644
index 0000000..acabb81
--- /dev/null
+++ b/pyanaconda/ui/tui/simpleline/base.py
@@ -0,0 +1,337 @@
+# Base classes for the Anaconda TUI framework.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Martin Sivak <msivak(a)redhat.com>
+#
+
+__all__ = ["ExitMainLoop", "App", "UIScreen", "Widget"]
+
+class ExitMainLoop(Exception):
+ pass
+
+class App(object):
+ def __init__(self, title):
+ self._header = title
+ self._spacer = "\n".join(2*[80*"="])
+
+ # screen stack contains triplets
+ # UIScreen to show
+ # arguments for it's show method
+ # value indicating whether new mainloop is needed - None = do nothing, True = execute, False = already running, exit when window closes
+ self._screens = []
+
+ def switch_screen(self, ui, args = None):
+ """Schedules a screen to replace the current one."""
+ self._screens.pop()
+ self._screens.append((ui, args, None))
+ self.redraw()
+
+ def switch_screen_with_return(self, ui, args = None):
+ """Schedules a screen to show, but keeps the current one in stack to return to, when the new one is closed."""
+ self._screens.append((ui, args, None))
+ self.redraw()
+
+ def switch_screen_modal(self, ui, args = None):
+ """Starts a new screen right away, so the caller can collect data back. When the new screen is closed, the caller is redisplayed."""
+ self._screens.append((ui, args, True))
+ self.redraw()
+
+ def schedule_screen(self, ui, args = None):
+ """Add screen to the bottom of the stack."""
+ self._screens.insert(0, (ui, args, False))
+
+ def close_screen(self, scr = None):
+ oldscr, oldattr, oldloop = self._screens.pop()
+ if scr is not None:
+ assert oldscr == scr
+
+ # we are in modal window, end it's loop
+ assert oldloop != True # this cannot happen, if we are closing the window, the loop must be running or not there
+ if oldloop == False:
+ raise ExitMainLoop()
+
+ if self._screens:
+ self.redraw()
+ else:
+ raise ExitMainLoop()
+
+ def _do_redraw(self):
+ """Draws the current screen and returns True if user input is requested.
+ If modal screen is requested, starts a new loop and initiates redraw after it ends."""
+ if not self._screens:
+ raise ExitMainLoop()
+
+ screen, args, newloop = self._screens[-1]
+ input_needed = screen.show(args)
+
+ if newloop == True:
+ self._screens.pop()
+ self._screens.append((screen, args, False))
+ self.run()
+ self.redraw()
+ input_needed = False # we have to skip input once, to redisplay the screen first
+
+ self._redraw = False
+
+ return input_needed
+
+ def run(self):
+ self._redraw = True
+ last_screen = None
+ error_counter = 0
+ while self._screens:
+ try:
+ if self._redraw or last_screen != self._screens[-1]:
+ if not self._do_redraw():
+ continue
+
+ last_screen = self._screens[-1]
+
+ c = raw_input("\tPlease make your choice from above: ")
+ if not self.input(c):
+ error_counter += 1
+
+ if error_counter >= 5:
+ self.redraw()
+
+ if self._redraw:
+ error_counter = 0
+ print self._spacer
+ except ExitMainLoop:
+ break
+
+ def input(self, key):
+ """Method called to process unhandled input key presses."""
+ if self._screens:
+ key = self._screens[-1][0].input(key)
+ if key is None:
+ return True
+
+ if self._screens and (key == 'quit'):
+ self.close_screen()
+ return True
+
+ return False
+
+ def redraw(self):
+ self._redraw = True
+
+ @property
+ def header(self):
+ return self._header
+
+ @property
+ def store(self):
+ return self._store
+
+
+class UIScreen(object):
+ def __init__(self, app, data):
+ self._app = app
+ self._data = data
+
+ def show(self, args = None):
+ """Method which displays the screen. If user input is requested, return True."""
+ pass
+
+ def input(self, key):
+ """Method called to process input. If the input is not handled here, return it."""
+ return key
+
+ @property
+ def data(self):
+ return self._data
+
+ @property
+ def app(self):
+ return self._app
+
+ def close(self):
+ self.app.close_screen(self)
+
+class Widget(object):
+ def __init__(self, max_width = None, default = None):
+ """Initializes base Widgets buffer.
+
+ @param max_width server as a hint about screen size to write method with default arguments
+ @type max_width int
+
+ @param default string containing the default content to fill the buffer with
+ @type default string
+ """
+
+ self._buffer = []
+ if default:
+ self._buffer = [[c for c in l] for l in default.split("\n")]
+ self._max_width = max_width
+ self._cursor = (0, 0) # row, col
+
+ @property
+ def height(self):
+ return len(self._buffer)
+
+ @property
+ def width(self):
+ return reduce(lambda acc,l: max(acc, len(l)), self._buffer, 0)
+
+ def clear(self):
+ """Clears this widgets buffer and resets cursor."""
+ self._buffer = list()
+ self._cursor = (0, 0)
+
+ @property
+ def content(self):
+ """This has to return list (rows) of lists (columns) with one character elements."""
+ return self._buffer
+
+ def render(self, width = None):
+ """This method has to redraw the widget's self._buffer.
+
+ @param width the width of buffer requested by the caller
+ @type width int
+
+ This method will commonly call render of child widgets and then draw and write
+ methods to copy their contents to self._buffer
+ """
+ pass
+
+ def __unicode__(self):
+ return u"\n".join([u"".join(l) for l in self._buffer])
+
+ def setxy(self, row, col):
+ """Sets cursor position."""
+ self._cursor = (row, col)
+
+ def setend(self):
+ """Sets the cursor to first column in new line at the end."""
+ self._cursor = (self.height, 0)
+
+ def draw(self, w, row = None, col = None, block = False):
+ """This method copies w widget's content to this widget's buffer at row, col position.
+
+ @param w widget to take content from
+ @type w class Widget
+
+ @param row row number to start at (default is at the cursor position)
+ @type row int
+
+ @param col column number to start at (default is at the cursor position)
+ @type col int
+
+ @param block when printing newline, start at column col (True) or at column 0 (False)
+ @type boolean
+ """
+
+
+ if row is None:
+ row, col = self._cursor
+ elif col is None:
+ col = self._cursor[1]
+
+ # fill up rows
+ if self.height < row + w.height:
+ for i in range(row + w.height - self.height):
+ self._buffer.append(list())
+
+ # append columns
+ for l in range(row, row + w.height):
+ l_len = len(self._buffer[l])
+ w_len = len(w.content[l - row])
+ if l_len < col + w_len:
+ self._buffer[l] += ((col + w_len - l_len) * list(u" "))
+ self._buffer[l][col:col + w_len] = w.content[l - row][:]
+
+ if block:
+ self._cursor = (row + w.height, col)
+ else:
+ self._cursor = (row + w.height, 0)
+
+ def write(self, text, row = None, col = None, width = None, block = False):
+ """This method emulates typing machine writing to this widget's buffer.
+
+ @param text text to type
+ @type text unicode
+
+ @param row row number to start at (default is at the cursor position)
+ @type row int
+
+ @param col column number to start at (default is at the cursor position)
+ @type col int
+
+ @param width wrap at "col" + "width" column (default is at self._max_width)
+ @type width int
+
+ @param block when printing newline, start at column col (True) or at column 0 (False)
+ @type boolean
+ """
+
+ if row is None:
+ row, col = self._cursor
+ elif col is None:
+ col = self._cursor[1]
+
+ if width is None:
+ width = self._max_width - col
+
+ x = row
+ y = col
+
+ # emulate typing machine
+ for c in text:
+ # if the line is not in buffer, create it
+ if x >= len(self._buffer):
+ for i in range(x - len(self._buffer) + 1):
+ self._buffer.append(list())
+
+ # if the line's length is not enough, fill it with spaces
+ if y >= len(self._buffer[x]):
+ self._buffer[x] += ((y - len(self._buffer[x]) + 1) * list(u" "))
+
+ # process newline
+ if c == "\n":
+ x += 1
+ if block:
+ y = col
+ else:
+ y = 0
+ continue
+
+ # "type" character
+ self._buffer[x][y] = c
+
+ # shift to the next char
+ y += 1
+ if y >= col + width:
+ x += 1
+ if block:
+ y = col
+ else:
+ y = 0
+
+ self._cursor = (x, y)
+
+class HelloWorld(UIScreen):
+ def show(self, args = None):
+ print """Hello World\nquit by typing 'quit'"""
+ return True
+
+if __name__ == "__main__":
+ a = App("Hello World")
+ s = HelloWorld(a, None)
+ a.schedule_screen(s)
+ a.run()
diff --git a/pyanaconda/ui/tui/simpleline/widgets.py b/pyanaconda/ui/tui/simpleline/widgets.py
new file mode 100644
index 0000000..0e134f1
--- /dev/null
+++ b/pyanaconda/ui/tui/simpleline/widgets.py
@@ -0,0 +1,78 @@
+# encoding: utf-8
+#
+# Widgets for Anaconda TUI.
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Martin Sivak <msivak(a)redhat.com>
+#
+
+__all__ = ["TextWidget", "ColumnWidget"]
+
+import base
+
+class TextWidget(base.Widget):
+ def __init__(self, text):
+ base.Widget.__init__(self)
+ self._text = text
+
+ def render(self, width):
+ self.clear()
+ self.write(self._text, width = width)
+
+class ColumnWidget(base.Widget):
+ def __init__(self, columns, spacing = 0):
+ """Create text columns
+
+ @param columns list containing (column width, [list of widgets to put into this column])
+ @type columns [(int, [...]), ...]
+
+ @param spacing number of spaces to use between columns
+ @type int
+ """
+
+ base.Widget.__init__(self)
+ self._spacing = spacing
+ self._columns = columns
+
+ def render(self, width):
+ self.clear()
+
+ for col_width,col in self._columns:
+ for item in col:
+ item.render(col_width)
+ self.draw(item, block = True)
+
+ self.setxy(0, self.width + self._spacing)
+
+
+if __name__ == "__main__":
+ t1 = TextWidget(u"Můj krásný dlouhý text")
+ t2 = TextWidget(u"Test")
+ t3 = TextWidget(u"Test 2")
+ t4 = TextWidget(u"Krásný dlouhý text podruhé")
+ t5 = TextWidget(u"Test 3")
+
+ c = ColumnWidget([(15, [t1, t2, t3]), (10, [t4, t5])], spacing = 1)
+ c.render(80)
+ print unicode(c)
+
+ print 80*"-"
+
+ c = ColumnWidget([(20, [t1, t2, t3]), (25, [t4, t5]), (15, [t1, t2, t3])], spacing = 3)
+ c.render(80)
+ print unicode(c)
--
1.7.10.4
11 years, 9 months
[PATCH] reboot after kickstart
by Brian C. Lane
From: "Brian C. Lane" <bcl(a)redhat.com>
Modify the continueButton to exit (allowing the anaconda exitHandler to
take control) if it is the last action. The button is expected to be
setup so that it is clear to the user what will happen (eg. REBOOT).
This also fixes the display of the quitDialog when rebooting.
Add a click of the final button when kickstarting with reboot or
shutdown.
halt also works, but requires a new version of pykickstart. Previously
the halt command was not working, it would set action to KS_SHUTDOWN and
there was no way for KS_WAIT to be set.
---
pyanaconda/ui/gui/__init__.py | 4 ++--
pyanaconda/ui/gui/hubs/progress.py | 9 ++++++++-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index 3d2fff9..253de02 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -136,9 +136,9 @@ class GraphicalUserInterface(UserInterface):
### SIGNAL HANDLING METHODS
###
def _on_continue_clicked(self):
- # If we're on the last screen, clicking Continue is the same as clicking Quit.
+ # If we're on the last screen, clicking Continue quits.
if len(self._actions) == 1:
- self._on_quit_clicked()
+ sys.exit(0)
return
# If the current action wants us to jump to an arbitrary point ahead,
diff --git a/pyanaconda/ui/gui/hubs/progress.py b/pyanaconda/ui/gui/hubs/progress.py
index 2eb1b75..bc0fad1 100644
--- a/pyanaconda/ui/gui/hubs/progress.py
+++ b/pyanaconda/ui/gui/hubs/progress.py
@@ -31,6 +31,8 @@ import os
from pyanaconda.localeinfo import expandLangs
from pyanaconda.product import productName
+from pyanaconda.flags import flags
+from pykickstart.constants import KS_WAIT, KS_SHUTDOWN, KS_REBOOT
from pyanaconda.ui.gui.hubs import Hub
from pyanaconda.ui.gui.utils import gdk_threaded
@@ -81,6 +83,11 @@ class ProgressHub(Hub):
GLib.source_remove(self._rnotes_id)
self._progressNotebook.next_page()
+
+ # kickstart install, continue automatically if reboot or shutdown selected
+ if flags.automatedInstall and self.data.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
+ self.continueButton.emit("clicked")
+
return False
q.task_done()
@@ -145,7 +152,7 @@ class ProgressHub(Hub):
args=(self.storage, self.payload, self.data, self.instclass)))
@property
- def quitButton(self):
+ def continueButton(self):
return self.builder.get_object("rebootButton")
def _init_progress_bar(self, steps):
--
1.7.7.6
11 years, 9 months
[PATCH] Disable dracut debug shell when password protected (#752966)
by Jesse Keating
Dracut debug shell gives users root like access, without a password.
This is not a good thing if the admin has decided that the system should
have a password protected boot loader. So for boot loaders that support
password protection, we should also add the rd.shell=0 flag to the boot
arguments to prevent the user from gaining root level access.
---
pyanaconda/bootloader.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index f375f5b..b10c25b 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -1682,6 +1682,10 @@ class GRUB2(GRUB):
def write_config(self):
self.write_config_console(None)
+ # See if we have a password and if so update the boot args before we
+ # write out the defaults file.
+ if self.password or self.encrypted_password:
+ self.boot_args.add("rd.shell=0")
self.write_defaults()
# if we fail to setup password auth we should complete the
@@ -1865,6 +1869,8 @@ class YabootSILOBase(BootLoader):
continue
args = Arguments()
+ if self.password or self.encrypted_password:
+ args.add("rd.shell=0")
if image.initrd:
initrd_line = "\tinitrd=%s/%s\n" % (self.boot_prefix,
image.initrd)
--
1.7.10.4
11 years, 9 months
[PATCH] encrypted AutoPart
by Brian C. Lane
From: "Brian C. Lane" <bcl(a)redhat.com>
This fixes using kickstart to run encrypted autopart.
What it does not do is handle missing passphases. That should, I think, be
handled in the storage spoke. It should not let the install continue until they
have been entered.
Brian C. Lane (1):
add encryption passphrase when doing encrypted autopart
pyanaconda/storage/partitioning.py | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
--
1.7.7.6
11 years, 9 months
[RHEL6] change missing boot partition error (#821336)
by Brian C. Lane
From: "Brian C. Lane" <bcl(a)redhat.com>
X86 is a subclass of EFI, so the error message may apply to non EFI
systems.
Resolves: rhbz#821336
---
platform.py | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/platform.py b/platform.py
index 3cd9116..31552ab 100644
--- a/platform.py
+++ b/platform.py
@@ -272,8 +272,10 @@ class EFI(Platform):
NOTE: X86 does not have a separate checkBootRequest method,
so this one must work for x86 as well as EFI.
"""
- if not req:
+ if not req and self.isEfi:
return [_("You have not created a /boot/efi partition.")]
+ elif not req:
+ return [_("You have not created a bootable partition.")]
errors = Platform.checkBootRequest(self, req)
--
1.7.7.6
11 years, 9 months