186 lines
6 KiB
Python
186 lines
6 KiB
Python
#
|
|
# Copyright (C) 2020 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.
|
|
#
|
|
from blivet.size import Size
|
|
from dasbus.client.proxy import get_object_path
|
|
from pyanaconda.anaconda_loggers import get_module_logger
|
|
from pyanaconda.core.constants import PAYLOAD_TYPE_DNF
|
|
from pyanaconda.modules.common.constants.objects import DEVICE_TREE
|
|
from pyanaconda.modules.common.constants.services import PAYLOADS, STORAGE
|
|
from pyanaconda.modules.common.structures.storage import DeviceData, DeviceFormatData
|
|
from pyanaconda.modules.common.task import sync_run_task
|
|
|
|
log = get_module_logger(__name__)
|
|
|
|
|
|
def create_payload(payload_type=PAYLOAD_TYPE_DNF, activate=True):
|
|
"""Create a payload module.
|
|
|
|
:param payload_type: a payload type
|
|
:param activate: True to activate the payload, otherwise False
|
|
:return: a proxy of a payload module
|
|
"""
|
|
payloads_proxy = PAYLOADS.get_proxy()
|
|
object_path = payloads_proxy.CreatePayload(payload_type)
|
|
|
|
if activate:
|
|
payloads_proxy.ActivatePayload(object_path)
|
|
|
|
return PAYLOADS.get_proxy(object_path)
|
|
|
|
|
|
def get_payload(payload_type=PAYLOAD_TYPE_DNF):
|
|
"""Get a payload of the specified type.
|
|
|
|
If there is no active payload of the specified type,
|
|
we will create and activate a new payload.
|
|
|
|
:return: a proxy of a payload module
|
|
"""
|
|
payloads_proxy = PAYLOADS.get_proxy()
|
|
object_path = payloads_proxy.ActivePayload
|
|
|
|
# Choose the active payload.
|
|
if object_path:
|
|
object_proxy = PAYLOADS.get_proxy(object_path)
|
|
|
|
# Check the type of the active payload.
|
|
if object_proxy.Type == payload_type:
|
|
return object_proxy
|
|
|
|
# Or create a new payload.
|
|
return create_payload(payload_type)
|
|
|
|
|
|
def create_source(source_type):
|
|
"""Create a source.
|
|
|
|
:param source_type: a source type
|
|
:return: a DBus proxy of a source
|
|
"""
|
|
payloads_proxy = PAYLOADS.get_proxy()
|
|
object_path = payloads_proxy.CreateSource(source_type)
|
|
return PAYLOADS.get_proxy(object_path)
|
|
|
|
|
|
def set_source(payload_proxy, source_proxy):
|
|
"""Attach the source to the payload.
|
|
|
|
:param payload_proxy: a DBus proxy of a payload
|
|
:param source_proxy: a DBus proxy of a source
|
|
"""
|
|
object_path = get_object_path(source_proxy)
|
|
payload_proxy.Sources = [object_path]
|
|
|
|
|
|
def get_source(payload_proxy):
|
|
"""Get a source of the given payload.
|
|
|
|
If the payload has one or more sources, return the first one.
|
|
|
|
If the payload has no sources and the default source type
|
|
is specified, create a default source.
|
|
|
|
If the payload has no sources and the default source type
|
|
is not specified, raise an exception.
|
|
|
|
:param payload_proxy: a DBus proxy of a payload
|
|
:return: a DBus proxy of a source
|
|
:raise: ValueError if there is no source to return
|
|
"""
|
|
sources = payload_proxy.Sources
|
|
|
|
if sources:
|
|
# Return the first source in the list. We don't
|
|
# really support multiple sources at this moment.
|
|
return PAYLOADS.get_proxy(sources[0])
|
|
|
|
# Or create a new source of the specified type
|
|
# and attach it to the given payload.
|
|
source = create_source(payload_proxy.DefaultSourceType)
|
|
set_source(payload_proxy, source)
|
|
|
|
return source
|
|
|
|
|
|
def set_up_sources(payload_proxy):
|
|
"""Set up the sources of the given payload.
|
|
|
|
:param payload_proxy: a DBus proxy of a payload
|
|
"""
|
|
task_path = payload_proxy.SetUpSourcesWithTask()
|
|
task_proxy = PAYLOADS.get_proxy(task_path)
|
|
sync_run_task(task_proxy)
|
|
|
|
|
|
def tear_down_sources(payload_proxy):
|
|
"""Tear down the sources of the given payload.
|
|
|
|
:param payload_proxy: a DBus proxy of a payload
|
|
"""
|
|
task_path = payload_proxy.TearDownSourcesWithTask()
|
|
task_proxy = PAYLOADS.get_proxy(task_path)
|
|
sync_run_task(task_proxy)
|
|
|
|
|
|
def find_potential_hdiso_sources():
|
|
"""Find potential HDISO sources.
|
|
|
|
Return a generator yielding Device instances that may have HDISO install
|
|
media somewhere. Candidate devices are simply any that we can mount.
|
|
|
|
:return: a list of device names
|
|
"""
|
|
device_tree = STORAGE.get_proxy(DEVICE_TREE)
|
|
return device_tree.FindMountablePartitions()
|
|
|
|
|
|
def get_hdiso_source_info(device_tree, device_name):
|
|
"""Get info about a potential HDISO source.
|
|
|
|
:param device_tree: a proxy of a device tree
|
|
:param device_name: a device name
|
|
:return: a dictionary with a device info
|
|
"""
|
|
device_data = DeviceData.from_structure(
|
|
device_tree.GetDeviceData(device_name)
|
|
)
|
|
|
|
format_data = DeviceFormatData.from_structure(
|
|
device_tree.GetFormatData(device_name)
|
|
)
|
|
|
|
disk_data = DeviceData.from_structure(
|
|
device_tree.GetDeviceData(device_data.parents[0])
|
|
)
|
|
|
|
return {
|
|
"model": disk_data.attrs.get("model", "").replace("_", " "),
|
|
"path": device_data.path,
|
|
"size": Size(device_data.size),
|
|
"format": format_data.description,
|
|
"label": format_data.attrs.get("label") or format_data.attrs.get("uuid") or ""
|
|
}
|
|
|
|
|
|
def get_hdiso_source_description(device_info):
|
|
"""Get a description of a potential HDISO source.
|
|
|
|
:param device_info: a dictionary with a device info
|
|
:return: a string with a device description
|
|
"""
|
|
return "{model} {path} ({size}) {format} {label}".format(**device_info)
|