Skip to content

Commit

Permalink
Mod/acme storage (#1)
Browse files Browse the repository at this point in the history
* Add example actors for ACME Storage

* Update acme/actors/acmestoragemigrator/actor.py

Co-authored-by: Petr Stodůlka <[email protected]>

* Update acme/actors/acmestoragescanner/actor.py

Co-authored-by: Petr Stodůlka <[email protected]>

* Split acme storagescanner to two actors

The whole solution for acme contains now 3 actors, kind of
 - scanner
 - checker
 - migrator

As well, raise an error in case we cannot obtain list of active
kernel modules.

* Create new hierarhy for ISV-repos and link acme to the official one

Previously it was expected that users will link the repository using
snactor. But possibly many solutions could be created just for purpose
of inplace upgrade between specific systems (e.g. RHEL 7 -> 8) and
will not be valid for upgrade (RHEL 8 -> 9).

To make it clear, let's use the el7toel8 directory.

As the ACME repository clearly is now just for inplace upgrade from
RHEL 7 to RHEL 8, link it directly to the official
system_upgrade_el7toel8 repository.

* Update directory hierarchy in the README.md file

* ACME: run acmemigrator in the last phase and fix nitpicks

The ACME probably will not be loaded inside the initrd so nothing
can be migrated there. Instead of that, migrate the ACME storage
during the first boot.

Co-authored-by: Pavel Odvody <[email protected]>
  • Loading branch information
pirat89 and shaded-enmity committed May 6, 2020
1 parent fe35c52 commit 69f05b1
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 3 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ This is a place where ISVs can contribute their [Leapp repositories](https://lea

The directory structure for this repository is as follows:
```
vendor/product/...
upgrade_type/vendor/product/...
```

For example, the ACME Corp. will end up with this structure for their ACME Storage product:
For example, the ACME Corp. will end up with this structure for their ACME Storage product
for inplace upgrade from RHEL 7 to RHEL 8:
```
acme/acme_storage/{actors,models}
el7toel8/acme/acme_storage/{actors,models}
```

If you're interested in contributing, please read the [Contributor Guidelines](https://github.com/oamg/leapp-guidelines/blob/master/contributing-guidelines.rst)
1 change: 1 addition & 0 deletions el7toel8/acme/.leapp/info
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"repos": ["c47fbc3d-ae38-416e-9176-7163d67d94f6"], "name": "acme", "id": "8da1955a-596e-4fcb-a6b7-fe7fbd1c91cc"}
6 changes: 6 additions & 0 deletions el7toel8/acme/.leapp/leapp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

[repositories]
repo_path=${repository:root_dir}

[database]
path=${repository:state_dir}/leapp.db
40 changes: 40 additions & 0 deletions el7toel8/acme/actors/acmestoragechecker/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from leapp import reporting
from leapp.actors import Actor
from leapp.models import Report, AcmeStorageInfo
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


class AcmeStorageChecker(Actor):
"""
Report change in ACME storage on RHEL 8 if ACME storage is used
"""

name = 'acme_storage_checker'
consumes = (AcmeStorageInfo,)
produces = (Report,)
tags = (ChecksPhaseTag, IPUWorkflowTag)

def process(self):
# Check if Acme is installed and used
acme_info = next(self.consume(AcmeStorageInfo), None)
if not acme_info:
return

# Inform the system administrator about the change
if acme_info.has_device and acme_info.has_kernel_module:
reporting.create_report([
reporting.Title('ACME Storage device path migration'),
reporting.Summary('ACME Storage device path is going to change to /dev/acme'),
reporting.Severity(reporting.Severity.INFO),
reporting.Tags([reporting.Tags.OS_FACTS]),
reporting.RelatedResource('device', '/dev/acme0'),
reporting.RelatedResource('device', '/dev/acme'),
reporting.ExternalLink(
url='https://acme.corp/storage-rhel',
title='ACME Storage on RHEL'
)
])
elif acme_info.has_device and not acme_info.has_kernel_module:
self.log.warning(
'Acme storage device detected but kernel module is not loaded.'
)
40 changes: 40 additions & 0 deletions el7toel8/acme/actors/acmestoragemigrator/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from leapp.actors import Actor
from leapp.models import Report, AcmeStorageInfo
from leapp.tags import FirstBootPhaseTag, IPUWorkflowTag

from leapp import reporting


import os


class AcmeStorageMigrator(Actor):
"""
Migrate ACME Storage device from old location to the new one
"""

name = 'acme_storage_migrator'
consumes = (AcmeStorageInfo,)
produces = (Report,)
tags = (FirstBootPhaseTag, IPUWorkflowTag)

def process(self):
acme_storage_info = next(self.consume(AcmeStorageInfo),None)

# Rename the device
if acme_storage_info.has_device and acme_storage_info.has_kernel_module:
os.rename('/dev/acme0', '/dev/acme')

# Emit a report message informing the system administrator that the device
# path has been changed
reporting.create_report([
reporting.Title('ACME Storage device path migrated'),
reporting.Summary('ACME Storage device path has been changed to /dev/acme'),
reporting.Severity(reporting.Severity.INFO),
reporting.Tags([reporting.Tags.OS_FACTS]),
reporting.RelatedResource('device', '/dev/acme'),
reporting.ExternalLink(
url='https://acme.corp/storage-rhel',
title='ACME Storage on RHEL'
)
])
42 changes: 42 additions & 0 deletions el7toel8/acme/actors/acmestoragescanner/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os

from leapp.actors import Actor
from leapp.exceptions import StopActorExecutionError
from leapp.libraries.common.rpms import has_package
from leapp.models import AcmeStorageInfo, ActiveKernelModulesFacts, InstalledRPM
from leapp.tags import FactsPhaseTag, IPUWorkflowTag


class AcmeStorageScanner(Actor):
"""
Scan the system for ACME Storage
"""

name = 'acme_storage_scanner'
consumes = (ActiveKernelModulesFacts, InstalledRPM)
produces = (AcmeStorageInfo,)
tags = (FactsPhaseTag, IPUWorkflowTag)

def process(self):
# Check if our package is installed
if not has_package(InstalledRPM, 'acme-storage'):
return

# Get a list of active kernel modules
kernel_module_facts = next(self.consume(ActiveKernelModulesFacts), None)
if not kernel_module_facts:
# hypothetic error; it should not happen
raise StopActorExecutionError('Unable to obtain list of active kernel modules.')
return

# Detect if our kernel module is installed
has_kernel_module = False
for active_module in kernel_module_facts.kernel_modules:
if active_module.filename == 'acme8xx':
has_kernel_module = True
break

# Is the device installed in the default location?
has_device = os.path.exists('/dev/acme0')

self.produce(AcmeStorageInfo(has_kernel_module=has_kernel_module, has_device=has_device))
9 changes: 9 additions & 0 deletions el7toel8/acme/models/acmestorageinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from leapp.models import Model, fields
from leapp.topics import SystemFactsTopic


class AcmeStorageInfo(Model):
topic = SystemFactsTopic

has_kernel_module = fields.Boolean()
has_device = fields.Boolean()

0 comments on commit 69f05b1

Please sign in to comment.