show entire log, incrementally
need to figure out how to scroll to end on each update
This commit is contained in:
parent
fcd5163101
commit
b5eb76b985
|
@ -13,6 +13,7 @@
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import fcntl
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -54,6 +55,7 @@ class InstallProgressController(BaseController):
|
||||||
self.progress_view = None
|
self.progress_view = None
|
||||||
self.install_state = InstallState.NOT_STARTED
|
self.install_state = InstallState.NOT_STARTED
|
||||||
self.postinstall_written = False
|
self.postinstall_written = False
|
||||||
|
self.tail_proc = None
|
||||||
|
|
||||||
def curtin_wrote_install(self):
|
def curtin_wrote_install(self):
|
||||||
pass
|
pass
|
||||||
|
@ -149,7 +151,12 @@ class InstallProgressController(BaseController):
|
||||||
|
|
||||||
self.install_state = InstallState.RUNNING_POSTINSTALL
|
self.install_state = InstallState.RUNNING_POSTINSTALL
|
||||||
if self.progress_view is not None:
|
if self.progress_view is not None:
|
||||||
|
self.progress_view.clear_log_tail()
|
||||||
self.progress_view.set_status("Running postinstall step.")
|
self.progress_view.set_status("Running postinstall step.")
|
||||||
|
if self.tail_proc is not None:
|
||||||
|
self.loop.remove_watch_file(self.tail_watcher_handle)
|
||||||
|
self.tail_proc.terminate()
|
||||||
|
self.tail_proc = None
|
||||||
if self.opts.dry_run:
|
if self.opts.dry_run:
|
||||||
log.debug("Installprogress: this is a dry-run")
|
log.debug("Installprogress: this is a dry-run")
|
||||||
curtin_cmd = [
|
curtin_cmd = [
|
||||||
|
@ -177,6 +184,31 @@ class InstallProgressController(BaseController):
|
||||||
log.debug('After curtin postinstall OK')
|
log.debug('After curtin postinstall OK')
|
||||||
self.install_state = InstallState.DONE_POSTINSTALL
|
self.install_state = InstallState.DONE_POSTINSTALL
|
||||||
|
|
||||||
|
def update_log_tail(self):
|
||||||
|
if self.tail_proc is None:
|
||||||
|
return
|
||||||
|
tail = self.tail_proc.stdout.read().decode('utf-8', 'replace')
|
||||||
|
self.progress_view.add_log_tail(tail)
|
||||||
|
|
||||||
|
def maybe_start_tail_proc(self):
|
||||||
|
if self.install_state < InstallState.RUNNING_POSTINSTALL:
|
||||||
|
install_log = CURTIN_INSTALL_LOG
|
||||||
|
else:
|
||||||
|
install_log = CURTIN_POSTINSTALL_LOG
|
||||||
|
if os.path.exists(install_log):
|
||||||
|
self.progress_view.clear_log_tail()
|
||||||
|
tail_cmd = ['tail', '-n', '1000', '-f', install_log]
|
||||||
|
log.debug('tail cmd: {}'.format(" ".join(tail_cmd)))
|
||||||
|
self.tail_proc = utils.run_command_start(tail_cmd)
|
||||||
|
stdout_fileno = self.tail_proc.stdout.fileno()
|
||||||
|
fcntl.fcntl(
|
||||||
|
stdout_fileno, fcntl.F_SETFL,
|
||||||
|
fcntl.fcntl(stdout_fileno, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||||
|
self.tail_watcher_handle = self.loop.watch_file(stdout_fileno, self.update_log_tail)
|
||||||
|
else:
|
||||||
|
log.debug(('Install log not yet present:') +
|
||||||
|
'{}'.format(install_log))
|
||||||
|
|
||||||
def progress_indicator(self, *args, **kwargs):
|
def progress_indicator(self, *args, **kwargs):
|
||||||
if self.install_state == InstallState.ERROR:
|
if self.install_state == InstallState.ERROR:
|
||||||
log.debug('progress_indicator: error detected')
|
log.debug('progress_indicator: error detected')
|
||||||
|
@ -185,10 +217,10 @@ class InstallProgressController(BaseController):
|
||||||
log.debug('progress_indicator: complete!')
|
log.debug('progress_indicator: complete!')
|
||||||
self.ui.set_footer("", 100)
|
self.ui.set_footer("", 100)
|
||||||
self.progress_view.show_complete()
|
self.progress_view.show_complete()
|
||||||
|
elif self.tail_proc is None:
|
||||||
|
self.maybe_start_tail_proc()
|
||||||
|
self.loop.set_alarm_in(0.3, self.progress_indicator)
|
||||||
else:
|
else:
|
||||||
log.debug('progress_indicator: looping')
|
|
||||||
install_tail = self.curtin_tail_install_log()
|
|
||||||
self.progress_view.set_log_tail(install_tail)
|
|
||||||
self.loop.set_alarm_in(0.3, self.progress_indicator)
|
self.loop.set_alarm_in(0.3, self.progress_indicator)
|
||||||
|
|
||||||
def reboot(self):
|
def reboot(self):
|
||||||
|
|
|
@ -34,19 +34,25 @@ class ProgressView(BaseView):
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.error = Text("")
|
self.error = Text("")
|
||||||
self.status = Text("Running install step.")
|
self.status = Text("Running install step.")
|
||||||
self.log = Text("<log goes here>")
|
self.listbox = ListBox([Text("<log goes here>")])
|
||||||
body = [
|
body = [
|
||||||
('pack', Padding.center_79(self.error)),
|
('pack', Padding.center_79(self.error)),
|
||||||
('pack', Padding.center_79(self.status)),
|
('pack', Padding.center_79(self.status)),
|
||||||
('pack', Text("")),
|
('pack', Text("")),
|
||||||
('weight', 1, Padding.center_79(LineBox(ListBox([self.log]), title="Installation logs"))),
|
('weight', 1, Padding.center_79(LineBox(self.listbox, title="Installation logs"))),
|
||||||
('pack', Text("")),
|
('pack', Text("")),
|
||||||
]
|
]
|
||||||
self.pile = Pile(body)
|
self.pile = Pile(body)
|
||||||
super().__init__(self.pile)
|
super().__init__(self.pile)
|
||||||
|
|
||||||
def set_log_tail(self, text):
|
def add_log_tail(self, text):
|
||||||
self.log.set_text(text)
|
if text.endswith('\n'):
|
||||||
|
text = text[:-1]
|
||||||
|
self.listbox.body.contents.append(Text(text))
|
||||||
|
self.listbox.set_focus_valign('bottom')
|
||||||
|
|
||||||
|
def clear_log_tail(self):
|
||||||
|
self.listbox.body.contents[:] = []
|
||||||
|
|
||||||
def set_status(self, text):
|
def set_status(self, text):
|
||||||
self.status.set_text(text)
|
self.status.set_text(text)
|
||||||
|
|
Loading…
Reference in New Issue