Skip to content

Commit

Permalink
devicestate: keep log from install-mode on installed system
Browse files Browse the repository at this point in the history
This commit ensures that we capture the full log of the
ephemeral install mode on the writable disk when installing
the system.

This is useful for debugging if install mode worked as expected
or to get logs about why things are different than they should
have been.
  • Loading branch information
mvo5 committed Oct 26, 2020
1 parent 33a200c commit afcef60
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
3 changes: 3 additions & 0 deletions overlord/devicestate/devicestate_install_mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func (s *deviceMgrInstallModeSuite) SetUpTest(c *C) {
s.state.Lock()
defer s.state.Unlock()
s.state.Set("seeded", true)

fakeJournalctl := testutil.MockCommand(c, "journalctl", "")
s.AddCleanup(fakeJournalctl.Restore)
}

func (s *deviceMgrInstallModeSuite) makeMockInstalledPcGadget(c *C, grade, gadgetDefaultsYaml string) *asserts.Model {
Expand Down
29 changes: 29 additions & 0 deletions overlord/devicestate/handlers_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package devicestate
import (
"fmt"
"os"
"os/exec"
"path/filepath"

"gopkg.in/tomb.v2"
Expand Down Expand Up @@ -89,6 +90,28 @@ func writeModel(model *asserts.Model, where string) error {
return asserts.NewEncoder(f).Encode(model)
}

func writeLogs(rootdir string) error {
// XXX: would be great to use native journal format but it's tied
// to machine-id, we could journal -o export but there
// is no systemd-journal-remote on core{,18,20}
//
// XXX: or only log if persistent journal is enabled?
logPath := filepath.Join(rootdir, "var/log/install-mode.log")
if err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil {
return err
}

f, err := os.Create(logPath)
if err != nil {
return err
}
defer f.Close()

cmd := exec.Command("journalctl")
cmd.Stdout = f
return cmd.Run()
}

func (m *DeviceManager) doSetupRunSystem(t *state.Task, _ *tomb.Tomb) error {
st := t.State()
st.Lock()
Expand Down Expand Up @@ -212,6 +235,12 @@ func (m *DeviceManager) doSetupRunSystem(t *state.Task, _ *tomb.Tomb) error {
return fmt.Errorf("cannot make run system bootable: %v", err)
}

// store install-mode log into ubuntu-data partition when
// persistent journal is selected
if err := writeLogs(boot.InstallHostWritableDir); err != nil {
logger.Noticef("cannot write logs: %v", err)
}

// request a restart as the last action after a successful install
logger.Noticef("request system restart")
st.RequestRestart(state.RestartSystemNow)
Expand Down
4 changes: 4 additions & 0 deletions tests/nested/manual/core20-early-config/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ execute: |
check_core20_early_config
# check that we go the install log after the transition to run mode
nested_exec "test -e /var/log/install-mode.log"
xxx
# now transition to recover mode and check it again
boot_id="$(nested_get_boot_id)"
# TODO:UC20: shouldn't need to specify the label here, fix when snap reboot
Expand Down

0 comments on commit afcef60

Please sign in to comment.