Skip to content

Commit

Permalink
Copy /var/lib/gnome-initial-setup/state to installed system
Browse files Browse the repository at this point in the history
In order to avoid duplicate screens in gnome-initial-setup we need
to let the gnome-initial-setup on the installed system know what
the user did during the live boot.

This commit copies the relevant state file over.

(cherry picked from commit 0d2279a)
  • Loading branch information
halfline authored and VladimirSlavik committed Sep 7, 2023
1 parent 6e5e8f3 commit bfdb4b1
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 6 deletions.
50 changes: 50 additions & 0 deletions pyanaconda/modules/payloads/payload/live_os/installation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# Copyright (C) 2023 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.
#
import os
import shutil

from pyanaconda.anaconda_loggers import get_module_logger
from pyanaconda.core.path import join_paths, make_directories
from pyanaconda.modules.common.task import Task

log = get_module_logger(__name__)


class CopyTransientGnomeInitialSetupStateTask(Task):
"""Task to copy transient gnome-initial-setup configuration from live system to installed system"""

def __init__(self, sysroot):
"""Create a new task."""
super().__init__()
self._sysroot = sysroot
self._paths = ['/var/lib/gnome-initial-setup/state']

@property
def name(self):
"""Name of the task."""
return "Transfer transient gnome-initial-setup live system configuration to installed system"""

def run(self):
"""Run the task."""
for path in self._paths:
destination_path = join_paths(self._sysroot, path.lstrip('/'))
destination_dir = os.path.dirname(destination_path)
make_directories(destination_dir)
log.debug("Copying %s to %s", path, destination_path)
if os.path.exists(path):
shutil.copy2(path, destination_path)
16 changes: 13 additions & 3 deletions pyanaconda/modules/payloads/payload/live_os/live_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
from pyanaconda.modules.common.errors.payload import IncompatibleSourceError
from pyanaconda.modules.payloads.constants import SourceType, PayloadType
from pyanaconda.modules.payloads.payload.live_image.installation import InstallFromImageTask
from pyanaconda.modules.payloads.payload.live_os.installation import \
CopyTransientGnomeInitialSetupStateTask
from pyanaconda.modules.payloads.payload.live_os.utils import get_kernel_version_list
from pyanaconda.modules.payloads.payload.payload_base import PayloadBase
from pyanaconda.modules.payloads.payload.live_os.live_os_interface import LiveOSInterface
Expand Down Expand Up @@ -62,20 +64,28 @@ def install_with_tasks(self):
"""Install the payload with tasks."""
image_source = self._get_source(SourceType.LIVE_OS_IMAGE)

tasks = []

if not image_source:
log.debug("No Live OS image is available.")
return []

task = InstallFromImageTask(
install_task = InstallFromImageTask(
sysroot=conf.target.system_root,
mount_point=image_source.mount_point
)

task.succeeded_signal.connect(
install_task.succeeded_signal.connect(
lambda: self._update_kernel_version_list(image_source)
)

return [task]
tasks += [install_task]

tasks += [CopyTransientGnomeInitialSetupStateTask(
sysroot=conf.target.system_root,
)]

return tasks

def _update_kernel_version_list(self, image_source):
"""Update the kernel versions list."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (C) 2019 Red Hat, Inc.
# Copyright (C) 2023 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
Expand All @@ -22,12 +22,14 @@
import unittest

from pyanaconda.core.constants import SOURCE_TYPE_LIVE_OS_IMAGE, PAYLOAD_TYPE_LIVE_OS
from pyanaconda.core.path import join_paths, touch
from pyanaconda.core.path import join_paths, make_directories, touch
from pyanaconda.modules.common.errors.payload import IncompatibleSourceError
from pyanaconda.modules.payloads.constants import SourceType, SourceState
from pyanaconda.modules.payloads.payload.live_os.live_os import LiveOSModule
from pyanaconda.modules.payloads.payload.live_os.live_os_interface import LiveOSInterface
from pyanaconda.modules.payloads.payload.live_image.installation import InstallFromImageTask
from pyanaconda.modules.payloads.payload.live_os.installation import \
CopyTransientGnomeInitialSetupStateTask

from tests.unit_tests.pyanaconda_tests import patch_dbus_publish_object
from tests.unit_tests.pyanaconda_tests.modules.payloads.payload.module_payload_shared import \
Expand Down Expand Up @@ -106,8 +108,9 @@ def test_install_with_task(self):
self.module.set_sources([source])

tasks = self.module.install_with_tasks()
assert len(tasks) == 1
assert len(tasks) == 2
assert isinstance(tasks[0], InstallFromImageTask)
assert isinstance(tasks[1], CopyTransientGnomeInitialSetupStateTask)

def test_install_with_task_no_source(self):
"""Test Live OS install with tasks with no source fail."""
Expand All @@ -116,3 +119,40 @@ def test_install_with_task_no_source(self):
def test_post_install_with_tasks(self):
"""Test Live OS post installation configuration task."""
assert self.module.post_install_with_tasks() == []


class LiveOSModuleTasksTestCase(unittest.TestCase):
"""Test the Live OS payload module tasks."""

def test_transient_gis_task_present(self):
"""Test copying GIS transient files when present"""
with tempfile.TemporaryDirectory() as oldroot, tempfile.TemporaryDirectory() as newroot:
task = CopyTransientGnomeInitialSetupStateTask(newroot)

mocked_path = join_paths(oldroot, task._paths[0])
make_directories(os.path.dirname(mocked_path))
with open(mocked_path, "w") as f:
f.write("some data to copy over")
assert os.path.isfile(mocked_path)
task._paths = [mocked_path] # HACK: overwrite the files to copy

task.run()

result_path = join_paths(newroot, mocked_path)
assert os.path.isfile(result_path)
with open(result_path, "r") as f:
assert f.readlines() == ["some data to copy over"]

def test_transient_gis_task_missing(self):
"""Test copying GIS transient files when missing"""
with tempfile.TemporaryDirectory() as oldroot, tempfile.TemporaryDirectory() as newroot:
task = CopyTransientGnomeInitialSetupStateTask(newroot)
mocked_path = join_paths(oldroot, task._paths[0])
assert not os.path.exists(mocked_path)
task._paths = [mocked_path] # HACK: overwrite the files to copy

task.run()
# must not fail with missing paths

result_path = join_paths(newroot, mocked_path)
assert not os.path.exists(result_path)

0 comments on commit bfdb4b1

Please sign in to comment.