From 925700c320bd1db8e4a58d51ba17276d4fcf3141 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 6 Aug 2024 13:56:28 +0200 Subject: [PATCH 01/13] docs: Use sphinx.ext.autosectionlabel instead of a local copy An old local copy of the code of the extension was used instead of directly using the extension. --- docs/source/autosectionlabelext.py | 69 ------------------------------ docs/source/conf.py | 4 +- 2 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 docs/source/autosectionlabelext.py diff --git a/docs/source/autosectionlabelext.py b/docs/source/autosectionlabelext.py deleted file mode 100644 index a28ab7c8c..000000000 --- a/docs/source/autosectionlabelext.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -""" - sphinx.ext.autosectionlabel - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Allow reference sections by :ref: role using its title. - - :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -from docutils import nodes - -# from sphinx.locale import __ -import logging -from sphinx.util.nodes import clean_astext - - -def __(x): - return x - - -if False: - # For type annotation - from typing import Any, Dict # NOQA - from sphinx.application import Sphinx # NOQA - - -logger = logging.getLogger(__name__) - -if False: - # For type annotation - from typing import Any, Dict # NOQA - from sphinx.application import Sphinx # NOQA - - -def register_sections_as_label(app, document): - # type: (Sphinx, nodes.Node) -> None - labels = app.env.domaindata['std']['labels'] - anonlabels = app.env.domaindata['std']['anonlabels'] - for node in document.traverse(nodes.section): - labelid = node['ids'][0] - docname = app.env.docname - ref_name = getattr(node[0], 'rawsource', node[0].astext()) - if app.config.autosectionlabel_prefix_document: - name = nodes.fully_normalize_name(docname + ':' + ref_name) - print('{} + {} => {}'.format(docname, ref_name, name)) - else: - name = nodes.fully_normalize_name(ref_name) - sectname = clean_astext(node[0]) - - if name in labels: - logger.warning(__('duplicate label %s, other instance in %s'), - name, app.env.doc2path(labels[name][0])) - - anonlabels[name] = docname, labelid - labels[name] = docname, labelid, sectname - - -def setup(app): - # type: (Sphinx) -> Dict[unicode, Any] - app.add_config_value('autosectionlabel_prefix_document', True, 'env') - app.connect('doctree-read', register_sections_as_label) - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/docs/source/conf.py b/docs/source/conf.py index d8551f42c..722a402de 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,7 +20,6 @@ import os import sys -sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))) import sphinx_rtd_theme # noqa @@ -38,9 +37,10 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.githubpages', - 'autosectionlabelext', + 'sphinx.ext.autosectionlabel', 'myst_parser', ] +autosectionlabel_prefix_document = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] From c139ece99bad5bf230c808e11a4ce6299b4b118c Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 12:45:22 +0200 Subject: [PATCH 02/13] docs: Move tutorials to separate dir The the leapp-repository related (in el7toel8) are intentionally left out and therefore removed from the documentation. --- docs/source/best-practices.md | 4 ++-- docs/source/faq.md | 6 +++--- docs/source/index.rst | 2 +- docs/source/test-actors.md | 2 +- docs/source/{ => tutorials}/create-repository.md | 2 +- docs/source/{ => tutorials}/debugging.md | 0 docs/source/{ => tutorials}/deprecation.md | 2 +- docs/source/{ => tutorials}/devenv-install.md | 0 docs/source/{ => tutorials}/dialogs.md | 0 docs/source/{ => tutorials}/first-actor.md | 0 docs/source/{tutorials.rst => tutorials/index.rst} | 2 -- docs/source/{ => tutorials}/messaging.md | 0 docs/source/{ => tutorials}/repo-linking.md | 0 docs/source/{ => tutorials}/unit-testing.md | 4 ++-- docs/source/{ => tutorials}/workflow-apis.md | 0 docs/source/{ => tutorials}/working-with-workflows.md | 0 16 files changed, 11 insertions(+), 13 deletions(-) rename docs/source/{ => tutorials}/create-repository.md (87%) rename docs/source/{ => tutorials}/debugging.md (100%) rename docs/source/{ => tutorials}/deprecation.md (99%) rename docs/source/{ => tutorials}/devenv-install.md (100%) rename docs/source/{ => tutorials}/dialogs.md (100%) rename docs/source/{ => tutorials}/first-actor.md (100%) rename docs/source/{tutorials.rst => tutorials/index.rst} (78%) rename docs/source/{ => tutorials}/messaging.md (100%) rename docs/source/{ => tutorials}/repo-linking.md (100%) rename docs/source/{ => tutorials}/unit-testing.md (98%) rename docs/source/{ => tutorials}/workflow-apis.md (100%) rename docs/source/{ => tutorials}/working-with-workflows.md (100%) diff --git a/docs/source/best-practices.md b/docs/source/best-practices.md index 7951290f7..a46691ae3 100644 --- a/docs/source/best-practices.md +++ b/docs/source/best-practices.md @@ -23,7 +23,7 @@ The snactor tool helps you with creating the base layout of a new Leapp reposito the repository artifacts like actors, models, tags, topics, and workflows. It also helps you with debugging as it is able to execute individual actors. -See the [tutorial on basic usage of snactor](first-actor). +See the [tutorial on basic usage of snactor](tutorials/first-actor). ## Move generic functionality to libraries @@ -118,7 +118,7 @@ def do_the_actor_thingy(actor): actor.log.debug("All the actor’s logic shall be outside actor.py") ``` -For more about unit testing, see the [tutorial](unit-testing). +For more about unit testing, see the [tutorial](tutorials/unit-testing). ## Do not introduce new dependencies diff --git a/docs/source/faq.md b/docs/source/faq.md index 4e00583de..2e7d37d4d 100644 --- a/docs/source/faq.md +++ b/docs/source/faq.md @@ -42,14 +42,14 @@ Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhe ## What do I have to do in order to execute actor I just wrote? -If you want to execute just a single actor when developing it, then use the snactor tool. [Here's a tutorial](first-actor) on how to use it. +If you want to execute just a single actor when developing it, then use the snactor tool. [Here's a tutorial](tutorials/first-actor) on how to use it. If you want to add your actor to an existing workflow, for example the RHEL 7 to 8 upgrade workflow, then tag your actor with appropriate workflow and phase tags. Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhel7-to-rhel8) ## What should I do if I need to execute multiple actors? Can I somehow ensure the dependencies between them? To be sure that your ActorA runs before your ActorB, produce a specific message in ActorA and let ActorB consume it. By doing this you create a dependency of ActorB on ActorA. -To run just your actors during development, use snactor run --save-output ActorA to save the message of ActorA to the Leapp repository database and then snactor run ActorB. This way, the ActorB will be able to consume the ActorA's saved message. Read more about that in the [tutorial about messaging](messaging.md). +To run just your actors during development, use snactor run --save-output ActorA to save the message of ActorA to the Leapp repository database and then snactor run ActorB. This way, the ActorB will be able to consume the ActorA's saved message. Read more about that in the [tutorial about messaging](tutorials/messaging.md). ## How can I specify what run time dependencies will my actor have? @@ -79,7 +79,7 @@ It should follow the [Contribution guidelines](contributing) and the [Best pract ## How can I debug my actor? Is there a standard/supported way how to log and get logs from actors/channels? -You can run your actor using the snactor tool and printing the output. [See the tutorial](first-actor) on how to use snactor. +You can run your actor using the snactor tool and printing the output. [See the tutorial](tutorials/first-actor) on how to use snactor. Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhel7-to-rhel8) ## Are there some technical limitations for an actor? E.g. maximum time execution, size of the input/output, libraries I can use... In case there are, is it possible to specify that the actor needs e.g. longer time for execution? diff --git a/docs/source/index.rst b/docs/source/index.rst index 87df57277..c228d1855 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,7 +9,7 @@ Welcome to developer documentation for Leapp! :glob: terminology - tutorials + tutorials/index leapp-repositories infrastructure best-practices diff --git a/docs/source/test-actors.md b/docs/source/test-actors.md index 967c2ad14..45f5cb73b 100644 --- a/docs/source/test-actors.md +++ b/docs/source/test-actors.md @@ -6,7 +6,7 @@ The Leapp actors are covered by three types of tests - unit, component and e2e. - Both unit and component tests are to be placed in the actor's _tests_ folder. - Unit and component tests modules should have unique names -- Tutorial on [How to write unit and component tests](unit-testing) +- Tutorial on [How to write unit and component tests](tutorials/unit-testing) ## Naming conventions diff --git a/docs/source/create-repository.md b/docs/source/tutorials/create-repository.md similarity index 87% rename from docs/source/create-repository.md rename to docs/source/tutorials/create-repository.md index 351065f9c..f6351d686 100644 --- a/docs/source/create-repository.md +++ b/docs/source/tutorials/create-repository.md @@ -1,6 +1,6 @@ # Creating a new repository for actor development -Leapp uses repositories with a defined [filesystem layout](repository-dir-layout). +Leapp uses repositories with a defined [filesystem layout](../repository-dir-layout). The snactor tool helps you to create a repository repository, in which you can develop and test your actors, tags, models, and topics. diff --git a/docs/source/debugging.md b/docs/source/tutorials/debugging.md similarity index 100% rename from docs/source/debugging.md rename to docs/source/tutorials/debugging.md diff --git a/docs/source/deprecation.md b/docs/source/tutorials/deprecation.md similarity index 99% rename from docs/source/deprecation.md rename to docs/source/tutorials/deprecation.md index 142d884fb..c97767d59 100644 --- a/docs/source/deprecation.md +++ b/docs/source/tutorials/deprecation.md @@ -11,7 +11,7 @@ impact on your code, we introduce the deprecation process described below. The following lists cover deprecated functionality in the leapp utility, snactor, the leapp standard library, etc. But don't cover deprecated functionalities from particular leapp repositories (e.g. the [elt7toel8](https://github.com/oamg/leapp-repository/tree/main/repos/system_upgrade/el7toel8) leapp repository). For -such information, see [Deprecated functionality in the el7toel8 repository](el7toel8/deprecation.md#deprecated-functionality-in-the-el7toel8-repository). +such information, see [Deprecated functionality in the el7toel8 repository](../el7toel8/deprecation.md#deprecated-functionality-in-the-el7toel8-repository). ## current upstream development (till the next release + 6months) diff --git a/docs/source/devenv-install.md b/docs/source/tutorials/devenv-install.md similarity index 100% rename from docs/source/devenv-install.md rename to docs/source/tutorials/devenv-install.md diff --git a/docs/source/dialogs.md b/docs/source/tutorials/dialogs.md similarity index 100% rename from docs/source/dialogs.md rename to docs/source/tutorials/dialogs.md diff --git a/docs/source/first-actor.md b/docs/source/tutorials/first-actor.md similarity index 100% rename from docs/source/first-actor.md rename to docs/source/tutorials/first-actor.md diff --git a/docs/source/tutorials.rst b/docs/source/tutorials/index.rst similarity index 78% rename from docs/source/tutorials.rst rename to docs/source/tutorials/index.rst index 1af89f7bf..82e04f685 100644 --- a/docs/source/tutorials.rst +++ b/docs/source/tutorials/index.rst @@ -7,8 +7,6 @@ Tutorials devenv-install create-repository first-actor - el7toel8/actor-rhel7-to-rhel8 - el7toel8/inhibit-rhel7-to-rhel8 messaging dialogs repo-linking diff --git a/docs/source/messaging.md b/docs/source/tutorials/messaging.md similarity index 100% rename from docs/source/messaging.md rename to docs/source/tutorials/messaging.md diff --git a/docs/source/repo-linking.md b/docs/source/tutorials/repo-linking.md similarity index 100% rename from docs/source/repo-linking.md rename to docs/source/tutorials/repo-linking.md diff --git a/docs/source/unit-testing.md b/docs/source/tutorials/unit-testing.md similarity index 98% rename from docs/source/unit-testing.md rename to docs/source/tutorials/unit-testing.md index f721d5553..1571ba182 100644 --- a/docs/source/unit-testing.md +++ b/docs/source/tutorials/unit-testing.md @@ -2,7 +2,7 @@ The Leapp framework provides support for easily writing unit and component tests for actors and also allows easy execution of the whole actors within -those tests. See [this document](test-actors) +those tests. See [this document](../test-actors) to find out what is the difference between unit and component tests. ## Getting started with writing tests @@ -161,7 +161,7 @@ shared libraries, models, etc. ### Actors's test dependencies If your **actor's tests** require a special package for their execution, create a -Makefile in the [actor's root directory](repository-dir-layout) with an +Makefile in the [actor's root directory](../repository-dir-layout) with an `install-deps` target calling `yum install -y`. ```sh diff --git a/docs/source/workflow-apis.md b/docs/source/tutorials/workflow-apis.md similarity index 100% rename from docs/source/workflow-apis.md rename to docs/source/tutorials/workflow-apis.md diff --git a/docs/source/working-with-workflows.md b/docs/source/tutorials/working-with-workflows.md similarity index 100% rename from docs/source/working-with-workflows.md rename to docs/source/tutorials/working-with-workflows.md From b7129fee2c61c0244dd3fb73a1708807e441fc5f Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 14:19:45 +0200 Subject: [PATCH 03/13] docs: Merge terminology and architecture into one section --- docs/source/architecture.md | 16 --- .../building-blocks-and-architecture.md | 99 +++++++++++++++++++ docs/source/index.rst | 3 +- docs/source/terminology.md | 66 ------------- leapp/actors/__init__.py | 15 +-- leapp/topics/__init__.py | 2 +- leapp/workflows/__init__.py | 2 +- 7 files changed, 111 insertions(+), 92 deletions(-) delete mode 100644 docs/source/architecture.md create mode 100644 docs/source/building-blocks-and-architecture.md delete mode 100644 docs/source/terminology.md diff --git a/docs/source/architecture.md b/docs/source/architecture.md deleted file mode 100644 index c4df42d15..000000000 --- a/docs/source/architecture.md +++ /dev/null @@ -1,16 +0,0 @@ -# Architecture overview - -![Architecture overview](/_static/images/framework-arch-overview.png) - -There are two tools for working with the framework, the end user application `leapp` and the development utility `snactor`. The `leapp` tool is designed to run specific workflows, while the `snactor` tool can run arbitrary workflows, but also individual actors. - -A *workflow* describes what work is going to be done and when. Each workflow is made of a sequence of *phases*, which contain *actors* split into three stages - before, main, and after. Workflows, actors, and all the parts necessary for the execution are loaded from repositories. - -Each actor is executed in a forked child process to prevent the modification of the application state. All messages and logs produced by the actors are stored in the *audit database*. - -For more information about each part of the architecture, check the [terminology](terminology). - -### How is this different from Ansible? - -Leapp is message-driven. The execution of actors is dependent on the data produced by other actors running before them. This data is passed around in the form of *messages*. -This is in a contrast with Ansible where everything has to be specified up front. diff --git a/docs/source/building-blocks-and-architecture.md b/docs/source/building-blocks-and-architecture.md new file mode 100644 index 000000000..5de56ee3e --- /dev/null +++ b/docs/source/building-blocks-and-architecture.md @@ -0,0 +1,99 @@ +# Building blocks and architecture TODO + +## Overview + +### Architecture overview TODO +![Architecture overview](/_static/images/framework-arch-overview.png) + +There are two tools for working with the framework, the end user application +`leapp` and the development utility `snactor`. The `leapp` tool is designed to +run specific workflows, while the `snactor` tool can run arbitrary workflows, +but also individual actors. + +A *workflow* describes what work is going to be done and when. Each workflow is +made of a sequence of *phases*, which contain *actors* split into three stages +- before, main, and after. Workflows, actors, and all the parts necessary for +the execution are loaded from repositories. + +Each actor is executed in a forked child process to prevent the modification of +the application state. All messages and logs produced by the actors are stored +in the *audit database*. + +For more information about each of the building blocks, read +[](#entities-in-leapp). + +### How is this different from Ansible? + +Leapp is message-driven. The execution of actors is dependent on the data produced by other actors running before them. This data is passed around in the form of *messages*. +This is in a contrast with Ansible where everything has to be specified up front. + +## Entities in Leapp + +### Actor + +An actor in terms of the Leapp project is a step that is executed within a workflow. +Actors define what kind of data they expect, and what they produce. Actors also +provide a list of tags, with which actors mark their use cases. + +Actors scan the system and produce the information found as messages. Other +actors consume those messages to make decisions, or process the data to produce +new messages. Some actors might apply changes to the system based on the +information gathered earlier. + +### Message + +A message is produced by an actor, and the payload follows the definition of +the [Model](#model) it is named after. Messaging is a term used to describe the +data exchange between [actors](#actor). + +### Model + +Models are the definition of the data model used in [message](#message) payloads. + +### Phase + +Phases are sections in a workflow dedicated to some specific area of execution. +A phase consists of three [stages](#stage): Before, Main, and After. +Phases are defined by assigning one or more tags to them, which will be used +to find actors in the [repositories](#repository) loaded. + +### Repository + +A repository is the place where all actors, models, tags, topics, and workflows +are defined. Additionally to that shared files, libraries and tools can be put +into the repository. + +### Stage + +Stage is a part of a [phase](#phase). There are three defined stages: +- Before +- Main +- After + +Before and After stages can be used to allow an actor to be run before or after any +other actors in the phase. This should be useful in some hooking scenarios, where +an action is supposed to be happening before or after another action. This way, other +actors could be influenced. + +### Tag + +A tag allows the framework to find [actors](#actor) in the [repository](#repository) +and group their execution based on that tag. + +### Topic + +Topics are assigned to models and are used for grouping the data into areas of interest. + +### Workflow + +Workflows describe what work is going to be done and when. A workflow is +describing a sequence of phases, where one phase has assigned filters with +which the framework selects actors that should be executed from the +repositories on the system. + +### Workflow APIs + +Workflow APIs are custom API classes that actors can use and automatically +inherit their consumed and produced messages. This way one can write a stable +API for third party actor writers, without being affected by changes of message +model layout, name changes etc. diff --git a/docs/source/index.rst b/docs/source/index.rst index c228d1855..7737e7cf3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -8,13 +8,12 @@ Welcome to developer documentation for Leapp! :caption: Contents: :glob: - terminology + building-blocks-and-architecture tutorials/index leapp-repositories infrastructure best-practices test-actors - architecture inplace-upgrade-workflow contributing python-coding-guidelines diff --git a/docs/source/terminology.md b/docs/source/terminology.md deleted file mode 100644 index b1754dc58..000000000 --- a/docs/source/terminology.md +++ /dev/null @@ -1,66 +0,0 @@ -# Terminology - -### Actor - -An actor in terms of the Leapp project is a step that is executed within a workflow. -Actors define what kind of data they expect, and what they produce. Actors also -provide a list of tags, with which actors mark their use cases. - -Actors scan the system and produce the information found as messages. -Other actors consume those messages to make decisions, or process the data -to produce new messages. -Some actors might apply changes to the system based on the information gathered earlier. - -### Message - -A message is produced by an actor, and the payload follows the definition of the [Model](#model) -it is named after. Messaging is a term used to describe the data exchange between [actors](#actor). - -### Model - -Models are the definition of the data model used in [message](#message) payloads. - -### Phase - -Phases are sections in a workflow dedicated to some specific area of execution. -A phase consists of three [stages](#stage): Before, Main, and After. -Phases are defined by assigning one or more tags to them, which will be used -to find actors in the [repositories](#repository) loaded. - -### Repository - -A repository is the place where all actors, models, tags, topics, and workflows are defined. -Additionally to that shared files, libraries and tools can be put into the repository. - -### Stage - -Stage is a part of a [phase](#phase). There are three defined stages: -- Before -- Main -- After - -Before and After stages can be used to allow an actor to be run before or after any -other actors in the phase. This should be useful in some hooking scenarios, where -an action is supposed to be happening before or after another action. This way, other -actors could be influenced. - -### Tag - -A tag allows the framework to find [actors](#actor) in the [repository](#repository) -and group their execution based on that tag. - -### Topic - -Topics are assigned to models and are used for grouping the data into areas of interest. - -### Workflow - -Workflows describe what work is going to be done and when. A workflow is describing a sequence of phases, -where one phase has assigned filters with which the framework selects actors that should be executed from -the repositories on the system. - -### Workflow APIs - -Workflow APIs are custom API classes that actors can use and automatically inherit their consumed and produced -messages. This way one can write a stable API for third party actor writers, without being affected by changes of -message model layout, name changes etc. diff --git a/leapp/actors/__init__.py b/leapp/actors/__init__.py index 9d83bf105..7dbc4246e 100644 --- a/leapp/actors/__init__.py +++ b/leapp/actors/__init__.py @@ -43,20 +43,23 @@ class Actor(object): consumes = () """ - Tuple of :py:class:`leapp.models.Model` derived classes defined in the :ref:`repositories ` - that define :ref:`messages ` the actor consumes. + Tuple of :py:class:`leapp.models.Model` derived classes defined in the + :ref:`repositories ` + that define :ref:`messages ` the actor consumes. """ produces = () """ - Tuple of :py:class:`leapp.models.Model` derived classes defined in the :ref:`repositories ` - that define :ref:`messages ` the actor produces. + Tuple of :py:class:`leapp.models.Model` derived classes defined in the + :ref:`repositories ` + that define :ref:`messages ` the actor produces. """ tags = () """ - Tuple of :py:class:`leapp.tags.Tag` derived classes by which :ref:`workflow ` - :ref:`phases ` select actors for execution. + Tuple of :py:class:`leapp.tags.Tag` derived classes by which + :ref:`workflow ` + :ref:`phases ` select actors for execution. """ dialogs = () diff --git a/leapp/topics/__init__.py b/leapp/topics/__init__.py index 90acef44f..7db95d427 100644 --- a/leapp/topics/__init__.py +++ b/leapp/topics/__init__.py @@ -17,7 +17,7 @@ def __new__(mcs, name, bases, attrs): class Topic(with_metaclass(TopicMeta)): - """ Base class for all :ref:`topics `""" + """ Base class for all :ref:`topics `""" name = None """ Name of the topic in snake case """ diff --git a/leapp/workflows/__init__.py b/leapp/workflows/__init__.py index 1b6fc9804..78aab0be7 100644 --- a/leapp/workflows/__init__.py +++ b/leapp/workflows/__init__.py @@ -68,7 +68,7 @@ class _ConfigPhase(Phase): class Workflow(with_metaclass(WorkflowMeta)): """ - Workflow is the base class for all :ref:`workflow ` definitions. + Workflow is the base class for all :ref:`workflow ` definitions. """ name = None From 7eba29b0b53993040ecc45e55fbed39f7d6f2bf6 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 14:32:41 +0200 Subject: [PATCH 04/13] docs: Infrastructure - remove section about leapp-repository --- docs/source/infrastructure.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/infrastructure.rst b/docs/source/infrastructure.rst index c2001519b..382e56188 100644 --- a/docs/source/infrastructure.rst +++ b/docs/source/infrastructure.rst @@ -7,6 +7,5 @@ Here you can find documentation related to our CI/CD, packaging, etc. :caption: Contents: dependencies - dependencies-leapp-repository compatibility-with-leapp-repository build-schema From 0fe8c9fd394cadb1115ffe1c9dc8d2be9d182369 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 14:51:26 +0200 Subject: [PATCH 05/13] docs: Rename Infrastructure to Packaging and dependencies The location in index.rst tree is also changed. --- docs/source/index.rst | 2 +- .../{infrastructure.rst => packaging-and-dependencies.rst} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename docs/source/{infrastructure.rst => packaging-and-dependencies.rst} (77%) diff --git a/docs/source/index.rst b/docs/source/index.rst index 7737e7cf3..8507a0540 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -11,10 +11,10 @@ Welcome to developer documentation for Leapp! building-blocks-and-architecture tutorials/index leapp-repositories - infrastructure best-practices test-actors inplace-upgrade-workflow + packaging-and-dependencies contributing python-coding-guidelines faq diff --git a/docs/source/infrastructure.rst b/docs/source/packaging-and-dependencies.rst similarity index 77% rename from docs/source/infrastructure.rst rename to docs/source/packaging-and-dependencies.rst index 382e56188..2c0a70c9c 100644 --- a/docs/source/infrastructure.rst +++ b/docs/source/packaging-and-dependencies.rst @@ -1,5 +1,5 @@ -Infrastructure -============== +Packaging and dependencies +========================== Here you can find documentation related to our CI/CD, packaging, etc. From 316741f9158d5b406a6f12b5e6ec35dddd4a1cee Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 14:55:34 +0200 Subject: [PATCH 06/13] docs: Packaging and deps - don't directly reference leapp-repo --- docs/source/build-schema.md | 12 ++++---- .../compatibility-with-leapp-repository.md | 8 ++--- docs/source/dependencies.md | 29 ++++++++++--------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/source/build-schema.md b/docs/source/build-schema.md index 79199646f..7f6869a56 100644 --- a/docs/source/build-schema.md +++ b/docs/source/build-schema.md @@ -1,8 +1,8 @@ # Naming schema of Leapp-related packages -All projects under the OAMG should use the same schema for names of RPM builds, -to be able to simply and fast find specific builds. The schema itself looks -like that (NVR without %{dist}): +All projects under OAMG should use the same schema for names of RPM builds, +to be able to simply and quickly find specific builds. The schema itself looks +like this (NVR without %{dist}): - for builds made from the main branch: ``` @@ -17,12 +17,12 @@ Where: - **name** is name of the project - **version** is current version of the application - **timestamp** in format: `+%Y%m%d%H%MZ`, e.g. "201812211407Z" -- **short-hash** is shortened hash of the commit from which the build has been +- **short-hash** is a shortened hash of the commit from which the build has been created -- **branch** is name of the branch from which the builds has been created; +- **branch** is name of the branch from which the builds have been created; in case the name of the branch contains dashes (`-`), these are automatically replaced by underscore (`_`) because dash is used as a separator in the name - of a (S)RPM file; so it is suggested (not required) to to avoid dashes + of a (S)RPM file; it is suggested (not required) to avoid dashes in names of branches - **number** is number of a pull-request (alternatively merge-request) to which builds are related diff --git a/docs/source/compatibility-with-leapp-repository.md b/docs/source/compatibility-with-leapp-repository.md index 13c61233e..f95f27209 100644 --- a/docs/source/compatibility-with-leapp-repository.md +++ b/docs/source/compatibility-with-leapp-repository.md @@ -2,7 +2,7 @@ There is a hidden dragon in the split of leapp framework and leapp repositories projects. The development of features and incompatible changes has different -speed in both projects. We want to release our projects using semantic +pace in both projects. We want to release our projects using semantic versioning and, at the same time, we do not want to release a new version of the project after each merge of a new feature or incompatible change. We rather prefer releasing new versions with changelogs and everything @@ -13,13 +13,13 @@ provide new functionality in the upstream (main) branch without the need of immediate release of the new version of leapp. For these purposes the `leapp-framework` capability is provided in the framework (python[23]-leapp) rpms. -## When and how change the capability +## When and how to change the capability The `leapp-framework` capability has to be changed in case of any change of provided API (e.g. change in the leapp standard library) or functionality that could affect actors in leapp repositories. That includes new features as well -as an actor may depend on that in future, and the leapp-repository package -should be able to specify correct framework version that is needed. +as an actor may depend on that in future, and packages providing leapp repositories +should be able to specify correct framework version that is required. The `leapp-framework` capability uses just `X.Y` versioning: diff --git a/docs/source/dependencies.md b/docs/source/dependencies.md index 9d0fdcace..27f7c0d95 100644 --- a/docs/source/dependencies.md +++ b/docs/source/dependencies.md @@ -18,22 +18,22 @@ changed, the value of the capability has to be incremented by one - so the information about the change is provided to other leapp-related packages. This metapackage can be simply replaced by a metapackage that would handle -outer dependencies of the target system. That means, that the metapackage -with dependencies for the target system is not part of this git repository -and the actors of the leapp-repository are responsible for providing -such package in case it is needed. +outer dependencies of the target system. That means, that the metapackage with +dependencies for the target system is not part of the [Leapp git repository +](https://github.com/oamg/leapp) and packages containing Leapp repositories are +responsible for providing such package in case it is needed. ## Why do I need to have a special way to define a dependency -One possible use of the Leapp framework is to do the in-place upgrade (IPU). -In that case, it is necessary to execute Leapp on two different -versions of the system - it starts with the source system and then continues -with the target (upgraded) system. It is quite common that some packages are -renamed between those two systems (or in case of leapp-repository, you would -like to use technology on the new system that is not provided on the original -one). -In such cases, it is hard to satisfy dependencies on both systems - when you -want to proceed with the upgrade process with the same Leapp packages. +One of the usages of the Leapp framework is to perform an in-place upgrade +(IPU) of a Linux operating system, RHEL in particular. In that case, it is +necessary to execute Leapp on two different versions of the system - it starts +with the source system and then continues with the target (upgraded) system. It +is quite common that some packages are renamed between those two systems. Or +maybe you would like to use technology on the new system that is not provided +on the original one). In such cases, it is hard to satisfy dependencies on both +systems - when you want to proceed with the upgrade process with the same Leapp +packages. As a solution, we are using the metapackage that contains those dependencies. @@ -67,7 +67,8 @@ is consistent across the SPEC file. ### Some more unusual steps There is an official -[Leapp repository](https://github.com/oamg/leapp-repository) that we manage +[Leapp repository](https://github.com/oamg/leapp-repository) providing Leapp +repositories for RHEL in-place upgrades that we manage and it is already affected by such change. If you modify the *outer dependencies*, inform the repository developers about the change (e.g. [issue](https://github.com/oamg/leapp-repository/issues/new)) From 399f9066895f9415cf79e4c9248b733401b0b2f1 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 30 Jul 2024 11:55:01 +0200 Subject: [PATCH 07/13] docs: Move deprecations list and process to libraries-and-api --- docs/source/deprecation.md | 86 +++++++++++++++++++++++++ docs/source/index.rst | 3 +- docs/source/libraries-and-api.md | 8 +++ docs/source/tutorials/deprecation.md | 96 ++-------------------------- 4 files changed, 99 insertions(+), 94 deletions(-) create mode 100644 docs/source/deprecation.md create mode 100644 docs/source/libraries-and-api.md diff --git a/docs/source/deprecation.md b/docs/source/deprecation.md new file mode 100644 index 000000000..afc8e8e5a --- /dev/null +++ b/docs/source/deprecation.md @@ -0,0 +1,86 @@ +# Deprecation + +The deprecation process is here to make (your) life of developers easier. +It's not possible to write perfect solution for everything and as the project +is evolving, it happens that some functionality needs to be changed, replaced +or dropped completely. Such situations are inevitable. To reduce negative +impact on your code, we introduce the deprecation process described below. + +## List of the deprecated functionality in leapp + +The following lists cover deprecated functionality in the leapp utility, snactor, +the leapp standard library, etc. But don't cover deprecated functionalities +from particular leapp repositories (e.g. the [elt7toel8](https://github.com/oamg/leapp-repository/tree/master/repos/system_upgrade/el7toel8) leapp repository). For +such information, see [Deprecated functionality in the el7toel8 repository](../el7toel8/deprecation.md#deprecated-functionality-in-the-el7toel8-repository). + +### current upstream development (till the next release + 6months) + +- nothing yet... + +### v0.15.0 (till Mar 2023) + +- Reporting primitives + - **`leapp.reporting.Flags`** - The `Flags` report primitive has been deprecated in favor of the more general `Groups` one. + - **`leapp.reporting.Tags`** - The `Tags` report primitive has been deprecated in favor of the more general `Groups` one. + +## What is covered by deprecation process in leapp? + +In short, leapp entities that are supposed to be used by other developers. +That means e.g.: + +1. Models +1. Shared library classes and functions in leapp repository +1. Public APIs +1. Actors providing functionality that could be used by any developer (produce + or consume messages) + +In other words, private classes, private functions or anything in private +libraries, may be modified or removed without the deprecation process. As well, +it's possible we will need to change something (e.g. a behaviour of a function) +that will not be possible to cover reasonably by the deprecation process (e.g. +change output of the function...). We'll try our best to prevent it, but it may +happen. To limit such problems, we recommend people to use APIs as much +as possible. + +## What does it mean that something is deprecated? + +When you deprecate something, the only thing that changes is that the +deprecated entity is marked in the code as deprecated which can have +additional impact, like messages produced on the user's terminal, +in the report, ... But the rest of the functionality is the same as before, +until the entity is removed completely. + +## What is the deprecation process for leapp? + + +In case a leapp entity covered by the deprecation process is to be removed for +any reason, it needs to be marked as deprecated before the removal (if +possible). The deprecation will be applied only for leapp entities that have +been introduced in an official release in RHEL (IOW, a functionality +that has been merged into the upstream, but has been removed before the release +or was marked as experimental all the time, is going to be removed without +the deprecation state). The time period during which the deprecated entity +won't be removed is at least 6 months. That doesn't mean we will remove +everything deprecated immediately after the 6 months, but it's to be expected +that it will be dropped anytime between 6 and 12 months since the deprecation. + +In case of issues, deprecated entities are not going to be fixed since +they are deprecated (unless they are fixed e.g. as a side-effect of another +problem fix). + +## How do I find out what is deprecated? + +Mainly via release notes and changelogs. In the official leapp related projects +(especially leapp and leapp-repository) the OAMG team takes care of release +notes to ensure they inform about the dropped and deprecated functionality. + +Additionally, when using leapp or snactor, user is notified via messages about +deprecated entities in **limited cases** (see below). In case of the leapp +utility, such messages are presented inside the generated reports. In case +of the snactor utility, the information message is printed in the console +output at the end of the snactor execution. See examples in this page for +detail. + +Please note, that the Deprecation warning is emitted only if: +- the deprecated class is instantiated +- the deprecated function is called diff --git a/docs/source/index.rst b/docs/source/index.rst index 8507a0540..86c41befc 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,10 +10,9 @@ Welcome to developer documentation for Leapp! building-blocks-and-architecture tutorials/index - leapp-repositories best-practices test-actors - inplace-upgrade-workflow + libraries-and-api packaging-and-dependencies contributing python-coding-guidelines diff --git a/docs/source/libraries-and-api.md b/docs/source/libraries-and-api.md new file mode 100644 index 000000000..105eada80 --- /dev/null +++ b/docs/source/libraries-and-api.md @@ -0,0 +1,8 @@ +# Libraries and API + +```{toctree} +:maxdepth: 2 +:caption: Contents: + +deprecation +``` diff --git a/docs/source/tutorials/deprecation.md b/docs/source/tutorials/deprecation.md index c97767d59..b90a53ac8 100644 --- a/docs/source/tutorials/deprecation.md +++ b/docs/source/tutorials/deprecation.md @@ -1,92 +1,4 @@ -# Deprecation - -The deprecation process is here to make (your) life of developers easier. -It's not possible to write perfect solution for everything and as the project -is evolving, it happens that some functionality needs to be changed, replaced -or dropped completely. Such situations are inevitable. To reduce negative -impact on your code, we introduce the deprecation process described below. - -## List of the deprecated functionality in leapp - -The following lists cover deprecated functionality in the leapp utility, snactor, -the leapp standard library, etc. But don't cover deprecated functionalities -from particular leapp repositories (e.g. the [elt7toel8](https://github.com/oamg/leapp-repository/tree/main/repos/system_upgrade/el7toel8) leapp repository). For -such information, see [Deprecated functionality in the el7toel8 repository](../el7toel8/deprecation.md#deprecated-functionality-in-the-el7toel8-repository). - -## current upstream development (till the next release + 6months) - -- nothing yet... - -## v0.15.0 (till Mar 2023) - -- Reporting primitives - - **`leapp.reporting.Flags`** - The `Flags` report primitive has been deprecated in favor of the more general `Groups` one. - - **`leapp.reporting.Tags`** - The `Tags` report primitive has been deprecated in favor of the more general `Groups` one. - -## What is covered by deprecation process in leapp? - -In short, leapp entities that are supposed to be used by other developers. -That means e.g.: - -1. Models -1. Shared library classes and functions in leapp repository -1. Public APIs -1. Actors providing functionality that could be used by any developer (produce - or consume messages) - -In other words, private classes, private functions or anything in private -libraries, may be modified or removed without the deprecation process. As well, -it's possible we will need to change something (e.g. a behaviour of a function) -that will not be possible to cover reasonably by the deprecation process (e.g. -change output of the function...). We'll try our best to prevent it, but it may -happen. To limit such problems, we recommend people to use APIs as much -as possible. - -## What does it mean that something is deprecated? - -When you deprecate something, the only thing that changes is that the -deprecated entity is marked in the code as deprecated which can have -additional impact, like messages produced on the user's terminal, -in the report, ... But the rest of the functionality is the same as before, -until the entity is removed completely. - -## What is the deprecation process for leapp? - - -In case a leapp entity covered by the deprecation process is to be removed for -any reason, it needs to be marked as deprecated before the removal (if -possible). The deprecation will be applied only for leapp entities that have -been introduced in an official release in RHEL (IOW, a functionality -that has been merged into the upstream, but has been removed before the release -or was marked as experimental all the time, is going to be removed without -the deprecation state). The time period during which the deprecated entity -won't be removed is at least 6 months. That doesn't mean we will remove -everything deprecated immediately after the 6 months, but it's to be expected -that it will be dropped anytime between 6 and 12 months since the deprecation. - -In case of issues, deprecated entities are not going to be fixed since -they are deprecated (unless they are fixed e.g. as a side-effect of another -problem fix). - -## How do I find out what is deprecated? - -Mainly via release notes and changelogs. In the official leapp related projects -(especially leapp and leapp-repository) the OAMG team takes care of release -notes to ensure they inform about the dropped and deprecated functionality. - -Additionally, when using leapp or snactor, user is notified via messages about -deprecated entities in **limited cases** (see below). In case of the leapp -utility, such messages are presented inside the generated reports. In case -of the snactor utility, the information message is printed in the console -output at the end of the snactor execution. See examples in this page for -detail. - -Please note, that the Deprecation warning is emitted only if: -- the deprecated class is instantiated -- the deprecated function is called - - -## How to deprecate entities in leapp? +# How to deprecate entities in leapp? When you want to deprecate an entity in leapp projects, use the `deprecated` decorator from `leapp.utils.deprecation` above the definition of the entity. @@ -126,7 +38,7 @@ the deprecation protection period. If you see the message and you are not the *provider* of the functionality, you have to update your code to be independent on it. -### Examples of a model deprecation +## Examples of a model deprecation Imagine we want to deprecate a *Foo* model that is produced in an actor called *FooProducer* and consumed in an actor called *FooConsumer*. Let's keep this @@ -349,7 +261,7 @@ we need to treat the `FooConsumer` actor. You could notice that all imports of the `Foo` model are commented. It's a good practice as it is more visible to all developers that a deprecated entity is present. -### Example of a model replacement +## Example of a model replacement This is analogous to the previous case. Take the same scenario, but extend it with the case in which we want to replace the `Foo` model by the `Bar` model. What @@ -407,7 +319,7 @@ class FooProducer(Actor): As you can see, the only thing that have been changed is the added production of the `Bar` message. The original functionality is still present. -### Example of a derived model deprecation +## Example of a derived model deprecation **Warning: Known issue**: *The deprecation of a derived model is currently buggy and the documented solution will end probably with traceback right now. The fix will be delivered From 36c2c76a448f65aaea3558b926e813b3d3b89f62 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 30 Jul 2024 12:07:18 +0200 Subject: [PATCH 08/13] docs: Move coding guidelines to contributing.md The python-coding-guidelines.md file is kept for now. --- docs/source/contributing.md | 212 +++++++++++++++++++++++++++++++++--- docs/source/index.rst | 1 - 2 files changed, 196 insertions(+), 17 deletions(-) diff --git a/docs/source/contributing.md b/docs/source/contributing.md index 65f94a550..2cfde5d75 100644 --- a/docs/source/contributing.md +++ b/docs/source/contributing.md @@ -1,17 +1,197 @@ # Contributing to the Leapp project - First, thank you for taking your time to contribute to the project. -The following is a set of guidelines for contributing effectively to the Leapp-related repositories -hosted under the [OS and Application Modernization Group organization](https://github.com/oamg/) -on GitHub. +The following is a set of guidelines for contributing effectively to the +Leapp-related repositories hosted under the [OS and Application Modernization +Group organization](https://github.com/oamg/) on GitHub. + +## Follow Python coding guidelines +While code stylistics (naming, whitespace, structure) is mostly handled by the famous PEP8 - https://www.python.org/dev/peps/pep-0008/ +there's still much to be defined and codified in terms of code semantics, which is equally important as the overall style. +Purpose of these guidelines is to reduce the *cognitive load* necessary to read through & understand the code base. + +### 1. Avoid Inheriting from Multiple Classes + +Python uses something called C3 Linearization (https://en.wikipedia.org/wiki/C3_linearization) +to figure out the method resolution order and, as you can see, the logic behind the algorithm is non-trivial - dragging +that context in your head all the time is, costly and unnecessary, given the particularly *little benefit* of using +multiple inheritance in the first place. + +### 2. Avoid Operator Overloading + +With the exception of mathematics there's usually very little reason for succumbing to the mysterious and +arcane arts of operator overloading. Why is math OK? Because operator overloading makes it consistent +with how *everybody* assumes the given operator works given how it works in math itself. +There's little benefit in operator overloading otherwise, because different people have different assumptions +and while you think that it's pretty clear that invalid state should make the object equal to `None`, well, pretty +much everyone else is going to find this behavior confusing (http://stackoverflow.com/questions/371266/checking-c-sharp-new-initialisation-for-null/371286), +because it's just not how the rest of the ecosystem works. Going back to math, for the same reason you wouldn't like `3 + 3 = 7` because +someone decided that the symbols for addition now should return `a + b + 1`, don't put such constructs in code. +The situation is much worse because Python isn't statically typed, so even if you knew that `SomeCrazyClass` overloads +some particular operator, you might have no idea that `some_var` even *is* an instance of `SomeCrazyClass`. + +### 3. Avoid 'In-Your-Face' error/exception messages + +Exceptions or terminal error messages should *always* give you enough context to either fix the problem on the OS level, if applicable, or +know the exact location and reason why the error was raised, given you need to fix it in code. +Even some shady corners of Python base library will sometimes simply tell you `Permission denied` when you're trying to access +a resource for which you don't have sufficient permission, which makes the message exceptionally unhelpful in case your application +manages multiple resources in a loop. All you end up doing is catch and re-raise the exception with more helpful message. + +#### 3.1. Type Your Exceptions + +Raise `ValueError` or `TypeError` when validating input parameters. Use custom exception hierarchy with `Exception` at its root for +raising errors related to application logic itself. Callers of your code then have fine grained control over various +failure modes, which will always help at making the code more robust. + +### 4. Avoid `**kwargs` like a plague + +Probably apart from function decorators, there's no legitimate reason for including `**kwargs` in your function signatures, ever. +Think of function signatures in terms of binding contracts between *caller* and *callee*, the caller knows how to invoke +the particular function (callee) simply by looking at the signature. In the context of contracts, `**kwargs` essentially +feels like "whatever, dude", because in the best case scenario the valid kwargs are documented in the function's doc string +(which is still going to stop code completion tools to a grinding halt), in the worst case you are going on a chase and will need +to inspect the code of at least one function body - granted the `**kwargs` are not passed around like a hot potato, in which case +your best bet is to resurrect the long forgotten art of "printf debugging" and sprinkle the code with a bunch of `print` calls +here and there. + +### 5. Import things the right way + +Avoid wildcard * imports. So called "Star" imports import every module member that's name doesn't start with `_` into the current scope, +which can quickly lead to name clashes and funny errors. + +Do not make relative imports. + +Imported modules should be divided into 3 groups stdlib/third-party/project in the following order separated +by a single newline; each group should be sorted alphabetically by full module/object name. + +If you need to use plenty of members from some module, use the `import module` syntax rather than `from module import foo`. +Always use `import module` syntax for python standard library, specifically instead of `from os.path import join` use `import os`. + +Sort imported modules as well as all imported functions by name, alphabetically. Our brains are very good at bi-secting names +in alphabetical order. + +Unless you have a really good reason, don't make local imports in function body. + +### 6. Avoid Using Assertions For Control Flow & Mutating Operations + +Assertions are, idiomatically, used to verify very basic assumptions about the code. It is assumed that once the code has been +stressed enough without triggering any assertion errors the code should be just fine. In C, for example, assertions are not +evaluated in non-debug builds. In Python, assertions are ignored if you execute your code with `-O` flag. +This also means that if the right-hand side of the assertion mutates certain state, the action *is not* carried out. + +### 7. Avoid Map, Reduce and Too Complex Comprehensions + +While one might say that writing out for loops makes the code look dumb and uninteresting, it also makes it +obvious and easy to understand, which are qualities, not defects. Code that uses map/reduce or several levels +of nested dictionary and list comprehensions almost always looks scary and it's very hard to deduce the +data flow of that particular piece of code. + +### 8. Avoid Deeply Nested Block Scopes + +In other words, high cyclomatic complexity is bad (https://en.wikipedia.org/wiki/Cyclomatic_complexity). Reasoning about code +with so much noise around is difficult, however, there are several ways how to avoid this situation. Instead of `if someCond:` +followed a by a huge chunk of code, consider the pattern of *eager returns* and simply return as soon as possible +`if not someCond: return` so that the following block doesn't need to be nested. This is of course not applicable for all +dark corners of cyclomatic complexity, for nested loops you might want to consider refactoring each loop into it's own +function or method. While the code will get a little more verbose, and you might face other difficulties like having to pass +around variables or even promoting some to instance variables, the resulting code is still much simpler to read then +condensed web of loops mutating maybe tens of local variables. + +### 9. Write Docstrings That Work Well With Tools + +The preferable way of writing docstrings for functions and methods is to use the first style mentioned at +(https://pythonhosted.org/an_example_pypi_project/sphinx.html#function-definitions). Plenty of editors or plugins are able +to parse these docstrings and provide targeted code completion and rudimentary validation. For consistency all docstrings +should start and end with `"""`. + +### 10. Avoid Shadowing Python Builtins + +type, file, id, map, filter, etc. have already been taken, be creative and invent your own object names. + +### 11. String Formatting + +#### 11.1 Prefer [new style](https://docs.python.org/3/library/string.html#string-formatting) String Formatting To [old style](https://docs.python.org/2/library/stdtypes.html#string-formatting) + +Though there is still a mixture of formatting styles remaining in leapp code base, this rule stands for +all new contributions. +Please use + +``` +new_style = "{}! {} is coming".format("Brace yourself", "Winter") +``` -## Code style guidelines +instead of -Your code should follow our -[Python Coding Guidelines](python-coding-guidelines) +``` +old_style_refactor_me = "%s! %s is coming!" % ("Brace yourself", "Winter") +old_style_refactor_me = "%(msg)s! %(obj)s is coming!" % {"msg": "Brace yourself", "obj": "Winter"} +``` -## Best practices in actor development +#### 11.2 Use Keyword Arguments To Increase Readability + +If you pass more than 2 arguments to format function, please invoke format with keyword arguments. +``` +msg_many_args = "{who} {when} {what}".format(who="A Lanister", when="always", what="pays his debts") +``` + +### 12. Docstrings + +Follow [PEP 257 - Docstring Conventions](https://www.python.org/dev/peps/pep-0257) + - with the exception, that the summary line of a multi-line docstring shall be on a new line, not on the same line as the opening quotes. + +There are some minimal requirements for the information that actor docstrings should provide, to learn more about the specifics please +consult the [contribution guidelines](contributing). + +This is example how to write docstrings: + +```python +class MyActor(Actor): + """ + Start with a single-line brief summary of the actor (under the triple quotes). + + Leave a blank line below the summary and then describe the actor's behaviour + here in detail. + """ + name = 'my_actor' + + def process(self): + """This is a simple method.""" + complicated_method(True) + + def complicated_method(switch): + """ + This is a summary line of a more complicated method. + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc porta sed + urna venenatis faucibus. Phasellus at bibendum ligula, a posuere metus. + + :param switch: Description of the parameter. + :type switch: Expected type of the parameter. + :return: Description of what the method returns + """ + mutliline_string = ( + 'I am a multiline string.\n' + 'This is my second line.' + ) + return mutliline_string +``` + +### 13. Underscore usage + +For leapp and leapp-repository the `_` and `P_` is reserved for localization. Please don't use it for anything else like +variable-to-be-discarded. Instead, use a variable name prefixed with `dummy_`. What comes after +the prefix should describe the data that is being discarded, like so: + +``` python +dummy_scheme, netloc, path, dummy_params, query, fragment = urlparse("scheme://netloc/path;parameters?query#fragment") +``` + +Using an informative variable name for discarded values is helpful when a future developer modifies +the code and needs the discarded information. They can quickly see that the information is already +available; they just need to rename the variable and start using it. + +## Follow best practices * Actor development: [Best practices for actor development](best-practices) * Actor directory layout is to be found at [Repository directory layout](repository-dir-layout) (under `actorname/`) @@ -22,6 +202,14 @@ Your code should follow our 1. New folders and/or Python files shall use lowercase without underscores. 1. The actor's main file shall be named `actor.py`. +## Git Commit Messages + +* Write a descriptive commit message +* Use the present tense ("Add feature" not "Added feature") +* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") +* If you are fixing a GitHub issue, include something like 'Closes issue #xyz' +* For more best practices, read [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) + ## Submitting a Pull Request Before you submit your pull request, consider the following guidelines: @@ -59,14 +247,6 @@ Before you submit your pull request, consider the following guidelines: * Every PR should have at least one code review before merging * All CI tests should pass -## Git Commit Messages - -* Write a descriptive commit message -* Use the present tense ("Add feature" not "Added feature") -* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") -* If you are fixing a GitHub issue, include something like 'Closes issue #xyz' -* For more best practices, read [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) - ## Contact In case of any question, contact us at `#leapp` on Libera.Chat IRC network, or write the question as an issue on diff --git a/docs/source/index.rst b/docs/source/index.rst index 86c41befc..3f47147c3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,7 +15,6 @@ Welcome to developer documentation for Leapp! libraries-and-api packaging-and-dependencies contributing - python-coding-guidelines faq pydoc/leapp From d97adfa5fb384c871fba45512372ee4243984c0f Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 30 Jul 2024 12:15:07 +0200 Subject: [PATCH 09/13] Move installation instructions to the top level Previously it resided in tutorials, but it's more relevant here. --- docs/source/{tutorials => }/devenv-install.md | 2 +- docs/source/index.rst | 1 + docs/source/tutorials/index.rst | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) rename docs/source/{tutorials => }/devenv-install.md (98%) diff --git a/docs/source/tutorials/devenv-install.md b/docs/source/devenv-install.md similarity index 98% rename from docs/source/tutorials/devenv-install.md rename to docs/source/devenv-install.md index 210e48f4e..07bf946c5 100644 --- a/docs/source/tutorials/devenv-install.md +++ b/docs/source/devenv-install.md @@ -1,4 +1,4 @@ -# Installing the development environment +# Installation ## RPM packages installation diff --git a/docs/source/index.rst b/docs/source/index.rst index 3f47147c3..596c97456 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,6 +9,7 @@ Welcome to developer documentation for Leapp! :glob: building-blocks-and-architecture + devenv-install tutorials/index best-practices test-actors diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst index 82e04f685..7d0301194 100644 --- a/docs/source/tutorials/index.rst +++ b/docs/source/tutorials/index.rst @@ -4,7 +4,6 @@ Tutorials .. toctree:: :caption: Contents: - devenv-install create-repository first-actor messaging From 4cdb2fe0e22b67808c40ba4452309cc9947e1c89 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 29 Jul 2024 15:03:18 +0200 Subject: [PATCH 10/13] docs: Remove leapp-repository related documents --- .../images/inplace-upgrade-workflow.svg | 2578 ----------------- docs/source/dependencies-leapp-repository.md | 56 - docs/source/deprecation.md | 6 +- docs/source/el7toel8/actor-rhel7-to-rhel8.md | 469 --- docs/source/el7toel8/deprecation.md | 49 - docs/source/el7toel8/envars.md | 194 -- .../source/el7toel8/inhibit-rhel7-to-rhel8.md | 162 -- .../el7toel8/leapp-repository-el7toel8.rst | 11 - docs/source/faq.md | 10 +- docs/source/inplace-upgrade-workflow.md | 3 - docs/source/leapp-repositories.rst | 14 - 11 files changed, 5 insertions(+), 3547 deletions(-) delete mode 100644 docs/source/_static/images/inplace-upgrade-workflow.svg delete mode 100644 docs/source/dependencies-leapp-repository.md delete mode 100644 docs/source/el7toel8/actor-rhel7-to-rhel8.md delete mode 100644 docs/source/el7toel8/deprecation.md delete mode 100644 docs/source/el7toel8/envars.md delete mode 100644 docs/source/el7toel8/inhibit-rhel7-to-rhel8.md delete mode 100644 docs/source/el7toel8/leapp-repository-el7toel8.rst delete mode 100644 docs/source/inplace-upgrade-workflow.md delete mode 100644 docs/source/leapp-repositories.rst diff --git a/docs/source/_static/images/inplace-upgrade-workflow.svg b/docs/source/_static/images/inplace-upgrade-workflow.svg deleted file mode 100644 index d4704497f..000000000 --- a/docs/source/_static/images/inplace-upgrade-workflow.svg +++ /dev/null @@ -1,2578 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - Main Phases - - Inplace Upgrade Flow - - - Pre-FactsCollection - - - - Facts Collection - - - - Post-FactsCollection - - - - Pre-Checks - - - - Checks - - - - Post-Checks - - - - - - - - - - - - - - - - - - - - - - - - - - - Start - - - - Pre-Report - - - - Report - - - - Post-Report - - - - Pre-Download - - - - Download - - - - Post-Download - - - - Pre-InterimPreparation - - - - InterimPreparation - - - - Post-InterimPreparation - - - - Pre-InitramReboot - - - - Initram Start - - - - Post-InitramStart - - - - Pre-LateTests - - - - Late Tests - - - - Post-LateTests - - - - PrePreparation - - - - Preparation - - - - PostPreparation - - - - Pre-RPMUpgrade - - - - RPM Upgrade - - - - Post-RPMUpgrade - - - - PreApplications - - - - Applications - - - - PostApplications - - - - Pre-Third PartyApplications - - - - Third PartyApplications - - - - Post-Third PartyApplications - - - - PreFinalization - - - - Finalization - - - - PostFinalization - - - - PreReboot - - - - Reboot - - - - PostReboot - - - - Pre-FirstBoot - - - - First Boot - - - - Post-FirstBoot - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Report - - User Interaction - - - - - - - - - - - - - - - - - - - New System - Interim System (Initrd) - Old System - - - - - - - - - Pre-Target TransactionFactsCollection - - - - Target TransactionFacts Collection - - - - Post-Target TransactionFacts Collection - - - - - - - - - - - - - - - - - Pre-Target TransactionCheck - - - Target TransactionCheck - - - Post-Target TransactionCheck - - - - - - - - - - - - - - - - diff --git a/docs/source/dependencies-leapp-repository.md b/docs/source/dependencies-leapp-repository.md deleted file mode 100644 index cbefca016..000000000 --- a/docs/source/dependencies-leapp-repository.md +++ /dev/null @@ -1,56 +0,0 @@ -# How to deal with dependencies in leapp-repository - -First, read this -[document](dependencies) -to better understand the difficulties related to package dependencies in the -Leapp project. - -When talking about RHEL 7 to RHEL 8 upgrade, the goal is to cover dependencies -of all Leapp project-related packages, including the leapp-repository packages, -for both RHEL 7 and RHEL 8. Since the situation with dependencies of the leapp -packages is similar to the situation with the leapp-repository dependencies, -this document focuses on the leapp-repository specifics only. - -Currently there are two SPEC files for leapp-repository: - -- The -[leapp-repository.spec](https://github.com/oamg/leapp-repository/blob/main/packaging/leapp-repository.spec) -file is used to build leapp-repository packages and their dependency -metapackage _leapp-repository-deps_ **for RHEL 7**. -- The -[leapp-el7toel8-deps.spec](https://github.com/oamg/leapp-repository/blob/main/packaging/leapp-el7toel8-deps.spec) -file is used to build dependency metapackages _leapp-deps-el8_ and -_leapp-repository-deps-el8_ **for RHEL 8** whose purpose is to replace the -RHEL 7 dependency metapackages _leapp-deps_ and _leapp-repository-deps_ during -the upgrade. - -## What to do in leapp-repository when dependencies of leapp change? - -Go to the section below the line `%package -n %{ldname}` in the -[leapp-el7toel8-deps.spec](https://github.com/oamg/leapp-repository/blob/main/packaging/leapp-el7toel8-deps.spec). -This section creates the RHEL 8 _leapp-deps-el8_ metapackage that replaces the -RHEL7 _leapp-deps_ metapackage. So when the leapp package dependencies change -in the [leapp.spec](https://github.com/oamg/leapp/blob/main/packaging/leapp.spec) -together with incrementing version of the **leapp-framework-dependencies** -capability, it's necessary to: - -- provide the same **leapp-framework-dependencies** capability version - by _leapp-deps-el8_ - -- decide if this dependency change also applies to RHEL 8 and if so, update - the dependencies of the _leapp-deps-el8_ metapackage accordingly. - -There can be another case when we need to modify dependencies of leapp on -RHEL 8, e.g. when a RHEL 7 package is renamed or split on RHEL 8. In such case -we don't need to modify the capability value, just update dependencies of the -_leapp-deps-el8_ metapackage, commenting it properly. Nothing else. - -## What to do when leapp-repository dependencies need to change? - -When you want to modify *outer dependencies* of leapp-repository packages, do -that similarly to instructions related to Leapp packages, following the same -rules. Just take care of the **leapp-repository-dependencies** capability -instead of the *leapp-framework-dependencies* capability. Everything else is -the same. Interesting parts of the SPEC files are highlighted in the same way -as described in the -[leapp dependencies document](dependencies). diff --git a/docs/source/deprecation.md b/docs/source/deprecation.md index afc8e8e5a..0b038ce3f 100644 --- a/docs/source/deprecation.md +++ b/docs/source/deprecation.md @@ -10,8 +10,10 @@ impact on your code, we introduce the deprecation process described below. The following lists cover deprecated functionality in the leapp utility, snactor, the leapp standard library, etc. But don't cover deprecated functionalities -from particular leapp repositories (e.g. the [elt7toel8](https://github.com/oamg/leapp-repository/tree/master/repos/system_upgrade/el7toel8) leapp repository). For -such information, see [Deprecated functionality in the el7toel8 repository](../el7toel8/deprecation.md#deprecated-functionality-in-the-el7toel8-repository). +from particular leapp repositories (e.g. the [RHEL in-place +upgrade](https://github.com/oamg/leapp-repository/tree/master/repos/system_upgrade/) +leapp repositories), these should be covered by the documentation of the +repositories. ### current upstream development (till the next release + 6months) diff --git a/docs/source/el7toel8/actor-rhel7-to-rhel8.md b/docs/source/el7toel8/actor-rhel7-to-rhel8.md deleted file mode 100644 index 32b371f74..000000000 --- a/docs/source/el7toel8/actor-rhel7-to-rhel8.md +++ /dev/null @@ -1,469 +0,0 @@ -# How to create a Leapp actor for RHEL 7 to 8 upgrade - -## Introduction - -This document is intended for all people who want to contribute to the process of upgrading Red Hat Enterprise Linux (RHEL) 7 to RHEL 8 using Leapp tool. The upgrade is performed in place meaning that the RHEL 7 installation is replaced by RHEL 8 on the same storage. -After reading through this document, you will be able to transform your expertise in certain parts of RHEL into improvements of the RHEL 7 to 8 upgrade tooling. - -## Setting up the development environment - -Leapp actors are written in Python 2.7+/3.6+ (the resulting code has to be both py2 and py3 compatible), so your usual Python development setup can be used during the process of creating a new actor. - -## Tools - -The main tools you will use for the actor development are listed below. - -### leapp - -The leapp framework provides the libraries required to be imported by any actor and also a binary tool used to control the execution of actors within a workflow. - -### snactor - -Separate tool provided by Leapp to help the process of creating and executing an actor. - -You can see _snactor_ source code [here](https://github.com/oamg/leapp/tree/main/leapp/snactor). - -## Creating an actor - -Every actor needs to be inside a so-called “Leapp repository”, otherwise it won’t be visible to Leapp. A Leapp repository groups actors and many other things which will be discussed later, like models, workflows, tags and topics. You can find all Leapp repositories under /usr/share/leapp-repository/repositories. A Leapp repository can be recognized by containing .leapp folder: - -```shell -$ find -L /etc/leapp/repos.d/ -name ".leapp" -type d | xargs dirname -/etc/leapp/repos.d/common -/etc/leapp/repos.d/system_upgrade/el7toel8 -``` - -First, you need to register repositories with snactor: - -```shell -$ snactor repo find --path /etc/leapp/repos.d/ -Registering /etc/leapp/repos.d/system_upgrade/el7toel8 -Registering /etc/leapp/repos.d/common -``` - -After registering the repositories, you can move inside any of these repositories and use snactor to create a boilerplate of a new actor: - -```shell -# cd /etc/leapp/repos.d/system_upgrade/el7toel8 -# snactor new-actor MyNewActor -New actor MyNewActor has been created at /usr/share/leapp-repository/repositories/system_upgrade/el7toel8/actors/mynewactor/actor.py -# cd /usr/share/leapp-repository/repositories/system_upgrade/el7toel8/actors/mynewactor/ -# tree -. -├── actor.py -└── tests -``` - -The main file of the actor is the actor.py in which you’ll write code for logic of the actor. - -For further information about how create an actor read this [document](../first-actor). - -## Including an actor in the RHEL 7 to 8 upgrade process - -Until now, you have created boilerplate of a new actor and made it visible to Leapp. But, Leapp needs some more information about what to do with the actor. Specifically, in which **“workflow”** and in which **“phase”** the actor should be executed. A workflow is a sequence of phases. The only workflow available now is the one solving the upgrade of RHEL 7 to RHEL 8. Each phase is a set of actors that will be executed one after another before the next phase starts. To find out in which workflow and phase should the actor be executed, Leapp looks for **“tags”**. To be part of RHEL 7 to RHEL 8 upgrade workflow, an actor needs to be tagged with **IPUWorkflowTag**. - -The phases of the IPUWorkflow (in order) are: **Facts Collection, Checks, Report, Download, Upgrade RamDisk Preparation, Upgrade RamDisk Start, Late Tests, Preparation, RPM Upgrade, Application Upgrade, Third Party Applications, Finalization** and **First Boot**. Each phase has a specific tag that marks an actor as being part of that phase. You can find descriptions of all the phases and their tags [here](https://github.com/oamg/leapp-repository/blob/main/repos/system_upgrade/common/workflows/inplace_upgrade.py) and workflow diagram [here](../inplace-upgrade-workflow). - -For example, if an actor is to be executed within the Checks phase, it needs to be tagged both with IPUWorkflowTag and ChecksPhaseTag. The result after updating the boilerplate would be: - -```python -from leapp.actors import Actor -from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - -class MyNewActor(Actor): - """ No description has been provided for the my_new_actor actor. """ - - name = 'my_new_actor' - consumes = () - produces = () - tags = (ChecksPhaseTag, IPUWorkflowTag) - - def process(self): - pass -``` - -## Inter-actor communication - -### Receiving data from other actors - -All communication between actors in Leapp is carried out using **“messages”**. An actor can consume or produce messages. A message may contain any data, but the data needs to be in a specific format defined by a **“model”**. If an actor wants to consume a message produced by another actor, it needs to specify the specific model of the consumed messages. Leapp will make sure to execute such an actor only after some message of the specified model was produced by another actor. If no message of the specified model was produced in previous phases or in the current phase, the consuming actor will get no messages of that kind. - -For further information about messaging see [document](../messaging). - -One of the existing models in Leapp is [ActiveKernelModulesFacts](https://github.com/oamg/leapp-repository/blob/main/repos/system_upgrade/el7toel8/models/activekernelmodulesfacts.py). Messages from this model contain data about the system on which Leapp has been started. For example, it contains installed kernel modules. If an actor wants to perform some action based on existing kernel modules on the system, the actor can get list of these modules by consuming the _ActiveKernelModulesFacts_ messages. By extending the boilerplate, the code could look like this: - -```python -from leapp.actors import Actor -from leapp.models import ActiveKernelModulesFacts - -from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - - -class MyNewActor(Actor): - """ No description has been provided for the my_new_actor actor. """ - - name = 'my_new_actor' - consumes = (ActiveKernelModulesFacts,) - produces = () - tags = (ChecksPhaseTag, IPUWorkflowTag) - - def process(self): - for fact in self.consume(ActiveKernelModulesFacts): - for active_module in fact.kernel_modules: - self.log.info(active_module.filename) -``` - -By executing the above actor, all active kernel modules would be logged on output using log utilities inherited from the Actor class. - -### Asking user questions - -In rare cases the actor can't choose a proper scenario of execution and leaves the final decision of how to proceed -to the user. That's where dialogs come into play. - -Please mind that using dialogs should be considered as last resort, when the situation absolutely can't resolve itself -automatically. The rule of a thumb is to make upgrade procedure require as little user input as possible. But if you -feel that there is no way to write a proper safe rhel7->rhel8 conversion logic and you need human to make a decision - -you can go with dialogs. - -The following restrictions apply: - -- At the time only Yes/No questions can be asked. Effectively only leapp.dialogs.components.BooleanComponent can be used. -- Dialogs can't be codependent. Any question asked should be independent of previous question's answer and should not - change the behavior of any other dialog that any actor might create. -- Dialogs can be used only at certain stages of the workflow - ChecksPhase and TargetTransactionChecksPhase. - -For more information and real examples please check [dialogs](../dialogs). - -### Producing data for other actors and reporting - -An actor can produce some data interesting enough for other actors to consume. It could be some parsed data, or content that will be displayed to the user in a report or even shared info between a subset of actors. - -The process is very similar to the one used to consume messages, but now the new actor will produce them. Similar to ActiveKernelModulesFacts, Leapp has a Report model. Messages from this model contain data that will be displayed to the user during ReportsPhase. For example, an actor can warn the user in case a btrfs kernel module is active on the system. Then, the actor could look like this: - -```python -from leapp import reporting -from leapp.actors import Actor -from leapp.models import ActiveKernelModulesFacts -from leapp.reporting import Report, create_report -from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - -class MyNewActor(Actor): - """ No description has been provided for the my_new_actor actor. """ - - name = 'my_new_actor' - consumes = (ActiveKernelModulesFacts,) - produces = (Report,) - tags = (ChecksPhaseTag, IPUWorkflowTag) - - def process(self): - for fact in self.consume(ActiveKernelModulesFacts): - for active_module in fact.kernel_modules: - if active_module.filename == 'btrfs': - create_report([ - reporting.Title('Btrfs has been removed from RHEL8'), - reporting.Summary( - 'The Btrfs file system was introduced as Technology Preview with the initial release' - ' of Red Hat Enterprise Linux 6 and Red Hat Enterprise Linux 7. As of versions 6.6' - ' and 7.4 this technology has been deprecated and removed in RHEL8.'), - reporting.ExternalLink( - title='Considerations in adopting RHEL 8 - btrfs has been removed.', - url='https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/' - 'considerations_in_adopting_rhel_8file-systems-and-storage_considerations-in-' - 'adopting-rhel-8#btrfs-has-been-removed_file-systems-and-storage' - ), - reporting.Severity(reporting.Severity.HIGH), - reporting.Groups([reporting.Groups.INHIBITOR, reporting.Groups.FILESYSTEM]), - reporting.RelatedResource('driver', 'btrfs') - ]) - break - -``` - -Final report is generated in **"txt"** and **"json"** format in `/var/log/leapp` directory at the end of either leapp preupgrade or leapp upgrade execution. - -### Reporting tips and good practices - -**Same type reports share the same title** - -To make your reports easier to read and aggregate please use same report title for checks that have the same semantics. -For example, if your actor is checking for deprecated modules and creating a report entry each time one is found, -the way to represent it in the report will be - -```diff -create_report([ - reporting.Title( -- 'Upgrade process was interrupted because a deprecated module {0} is enabled'.format(module), -+ 'Upgrade process was interrupted because a deprecated module is enabled', - reporting.Summary( - 'Module {0} was surpassed by shiny-new-{0} and therefore it was ' - 'removed from RHEL-8. Keeping it in the configuration may ' - 'lock out the system thus it is necessary to disable it ' - 'before the upgrade process can continue.'.format(module) - ), - ... - ]) -``` - -A better way, if applicable, would be to first collect all deprecated modules with their descendants and produce one -report entry with a list of mappings, like - -``` - -modules_map = {'moduleA': 'shiny-new-moduleA', 'moduleB': 'shiny-new-moduleB'} -... - -create_report([ - reporting.Title( - 'Upgrade process was interrupted because deprecated modules are enabled', - reporting.Summary( - 'Modules below were surpassed by new modules and ' - 'removed from RHEL-8. Keeping them in the configuration may ' - 'lock out the system thus it is necessary to disable them ' - 'before the upgrade process can continue.\n{}'.format( - '\n'.join(" - {0} -> {1}".format(old, new) for old, new in modules_map.iteritems())) - ), - ... - ]) -``` - -**Remediations** - -Apart from the above example you can also suggest a remediation, which is a procedure intended to fix the discovered -issue. Currently remediation can come in 3 flavors: a bash command to execute, a hint for manual action and a playbook. - -``` -reporting.Remediation(commands=[['alternatives', '--set', 'python', '/usr/bin/python3']]) -reporting.Remediation(hint='Please remove the dropped options from your scripts.') -reporting.Remediation(playbook=) -``` - -**Available Groups** - -The following groups were originally known as **Tags**: -``` -'accessibility', 'authentication', 'boot', 'communication', 'drivers', 'email', 'encryption', -'filesystem', 'firewall', 'high availability', 'kernel', 'monitoring', 'network', 'OS facts', -'post', 'python', 'repository', 'sanity', 'security', 'selinux', 'services', 'time management', -'tools', 'upgrade process' -``` - -The following groups were originally known as **Flags**: -``` -'failure', 'inhibitor' -``` - -The **failure** Group is recommended to be used when the report is related to -a command or other action failure. - -If you need additional report groups, please open a GH issue or a PR, -with the description why new required groups are needed. - -**Related resources** - -We recognize the following 6 types of resources: - -``` -reporting.RelatedResource('package', 'memcached') -reporting.RelatedResource('file', '/etc/passwd') -reporting.RelatedResource('service', 'postfix') -reporting.RelatedResource('directory', '/boot') -reporting.RelatedResource('repository', 'RHEL 7 Base') -reporting.RelatedResource('kernel-driver', 'vmxnet3') -reporting.RelatedResource('pam', 'pam_securetty') -``` - -The related resources are especially useful when you have a lot of accompanied objects like files or directories by your report and you would like to present it to the user in a specific way. - -## Testing your new actor - -During development of your new actor, it is expected that you will test your work to verify that results match your expectations. You can do that by manually executing your actor, or writing tests on various levels (i.e unit tests, component tests, E2E tests). - -### Executing a single actor - -You should use snactor tool to run a single actor and verify its output. Assuming that there are no errors, the actor was placed inside a valid leapp repository and snactor tool is aware of such repository, you can call snactor run to execute it. Below we are executing the existing [OSReleaseCollector](https://github.com/oamg/leapp-repository/tree/main/repos/system_upgrade/el7toel8/actors/osreleasecollector) actor that provides information about operating system release from target system. For the `snactor run` command you can use either the actor’s folder name (osreleasecollector), the actor’s class name (OSReleaseCollector) or the value of the name attribute of the actor’s class (os_release_collector). - -```shell -# pwd -/usr/share/leapp-repository/repositories/system_upgrade/el7toel8 -# snactor run --verbose OSReleaseCollector -2018-11-23 11:16:25.126 INFO PID: 4293 leapp: Logging has been initialized -2018-11-23 11:16:25.163 INFO PID: 4293 leapp.repository.system_upgrade_el7toel8: A new repository 'system_upgrade_el7toel8' is initialized at /usr/share/leapp-repository/repositories/system_upgrade/el7toel8 -2018-11-23 11:16:25.212 INFO PID: 4293 leapp.repository.common: A new repository 'common' is initialized at /usr/share/leapp-repository/repositories/common -``` - -As you can see the actor is executed without errors. But, by default, snactor does only display data logged by the actor. In order to display messages generated by the actor you can re-run the above command with _--print-output_ option. - -```shell -# snactor run --verbose --print-output OSReleaseCollector -2018-11-23 11:32:42.193 INFO PID: 4433 leapp: Logging has been initialized -2018-11-23 11:32:42.218 INFO PID: 4433 leapp.repository.system_upgrade_el7toel8: A new repository 'system_upgrade_el7toel8' is initialized at /usr/share/leapp-repository/repositories/system_upgrade/el7toel8 -2018-11-23 11:32:42.265 INFO PID: 4433 leapp.repository.common: A new repository 'common' is initialized at /usr/share/leapp-repository/repositories/common -[ - { - "stamp": "2019-04-30T13:00:13.836063Z", - "hostname": "leapp-20190429150826", - "actor": "os_release_collector", - "topic": "system_info", - "context": "0ac49430-1b29-4940-92bb-3e81da85f8af", - "phase": "NON-WORKFLOW-EXECUTION", - "message": { - "hash": "8305f6a38dcd266ea02bbd2e7c0b799e871d7dbe8734ea4138da53f4779b993e", - "data": "{\"id\": \"rhel\", \"name\": \"Red Hat Enterprise Linux Server\", \"pretty_name\": \"Red Hat Enterprise Linux\", \"variant\": \"Server\", \"variant_id\": \"server\", \"version\": \"7.6 (Maipo)\", \"version_id\": \"7.5\"}" - }, - "type": "OSReleaseFacts" - } -] -``` - -Now we can see that the _OSReleaseCollector_ actor produced a message of the _OSReleaseFacts_ model, containing data like OS Release name and version. - -### Executing a single actor that uses the workflow config - -If you need to execute an actor on its own that requires the `IPUConfig` model you can execute the actor with the -following command: - -```shell -snactor run --actor-config IPUConfig ActorName -``` - -In order for this to work you have to run the `IPUWorkflowConfig` actor before and save its output, so that the config -data is stored in the database for the current session: - -```shell -snactor run --save-output IPUWorkflowConfig -``` -Since the leapp upgrade repositories support several upgrade paths, the `snactor` needs to get additional data for the correct execution, like the release of the target system, the flavor specification, etc. -If you see similar errors when running `snactor` -``` -leapp.models.fields.ModelViolationError: The value of "target" field is None, but this is not allowed -``` -please, set the following environment variables (adjust the `LEAPP_UPGRADE_PATH_TARGET_RELEASE` as needed): -``` -export LEAPP_UPGRADE_PATH_TARGET_RELEASE=8.6 -export LEAPP_UPGRADE_PATH_FLAVOUR=default -snactor run --save-output IPUWorkflowConfig -``` - -### Executing the whole upgrade workflow with the new actor - -Finally, you can make your actor part of the “leapp upgrade” process and check how it behaves when executed together with all the other actors in the workflow. Assuming that your new actor is tagged properly, being part of _IPUWorkflow_, and part of an existing phase, you can place it inside an existing leapp repository on a testing RHEL 7 system. All Leapp components (i.e actors, models, tags) placed inside **/etc/leapp/repos.d/system_upgrade/el7toel8/** will be used by the “leapp upgrade” command during upgrade process. - -### Verifying correct communication between actors - -Leapp provides another actor, named [CheckOSRelease](https://github.com/oamg/leapp-repository/tree/main/repos/system_upgrade/el7toel8/actors/checkosrelease), that consumes messages from model _OSReleaseFacts_ and produces an error message in case system OS Release is not supported by Leapp upgrade process. In order to consume such message, _OSReleaseCollector_ actor needs to be executed before _CheckOSRelease_ and its message needs to be stored inside Leapp database. This process is controlled by the framework during the execution of “leapp upgrade” command. - -But, if you want to execute it manually, for test purposes, you can also use snactor for it. First we need to make sure that all messages that will be consumed are generated and stored. For this example, this means running _OSReleaseCollector_ actor with the _--save-output_ option of snactor: - -```shell -# snactor run --verbose --save-output OSReleaseCollector -2018-11-23 13:06:30.706 INFO PID: 17996 leapp: Logging has been initialized -2018-11-23 13:06:30.753 INFO PID: 17996 leapp.repository.system_upgrade_el7toel8: A new repository 'system_upgrade_el7toel8' is initialized at /usr/share/leapp-repository/repositories/system_upgrade/el7toel8 -2018-11-23 13:06:30.803 INFO PID: 17996 leapp.repository.common: A new repository 'common' is initialized at /usr/share/leapp-repository/repositories/common -``` - -Now, you can execute _CheckOSRelease_ actor and verify that it consumes the previously generated message and produces a message saying that the target system is not supported by Leapp upgrade process. You don’t need to specify which message will be consumed, snactor will take care of it. - -```shell -# snactor run --verbose --print-output CheckOSRelease -2018-11-23 13:11:15.549 INFO PID: 18126 leapp: Logging has been initialized -2018-11-23 13:11:15.578 INFO PID: 18126 leapp.repository.system_upgrade_el7toel8: A new repository 'system_upgrade_el7toel8' is initialized at /usr/share/leapp-repository/repositories/system_upgrade/el7toel8 -2018-11-23 13:11:15.617 INFO PID: 18126 leapp.repository.common: A new repository 'common' is initialized at /usr/share/leapp-repository/repositories/common -[ - { - "stamp": "2019-04-30T13:12:05.706317Z", - "hostname": "leapp-20190429150826", - "actor": "check_os_release", - "topic": "report_topic", - "context": "0ac49430-1b29-4940-92bb-3e81da85f8af", - "phase": "NON-WORKFLOW-EXECUTION", - "message": { - "hash": "ceaf419907ec78a894334b2a331a9ebb0c5a7847c18afc6d7546ba6656959e0d", - "data": "{\"report\": \"{\\\"audience\\\": \\\"sysadmin\\\", \\\"detail\\\": {\\\"related_resources\\\": [{\\\"scheme\\\": \\\"file\\\", \\\"title\\\": \\\"/etc/os-release\\\"}]}, \\\"flags\\\": [\\\"inhibitor\\\"], \\\"severity\\\": \\\"high\\\", \\\"summary\\\": \\\"The supported OS versions for the upgrade process: 7.6\\\", \\\"tags\\\": [\\\"sanity\\\"], \\\"title\\\": \\\"Unsupported OS version\\\"}\"}" - }, - "type": "Report" - } -] - -``` - -To flush all saved messages from the repository database, run `snactor messages clear`. - -## Writing tests for an actor - -[Read the tutorial](../unit-testing) for writing and running unit and component tests - -## Best practices - -Read the best practices [document](../best-practices) and [Python guidelines](https://github.com/oamg/leapp-guidelines/blob/master/python-coding-guidelines.md). - -## Contributing actors to the Leapp project - -Currently all Leapp elements (i.e. actors, models, tags) are stored under a public [GitHub repository](https://github.com/oamg/leapp-repository). - -All new content that needs to be part of Leapp release distributed to all users should be proposed as a Pull Request in this repository. - -**Before submitting your work for review, make sure you have read and followed the contribution guidelines:** - -[Contribution guidelines for writing actors](../contributing) - -This [pull request](https://github.com/oamg/leapp-repository/pull/186) gives a good example of both guidelines-driven actor implementation and thorough test coverage. - -## FAQ - -### In which existing workflow phase should I place my new actor? - -You can decide that based on the description of the phases this information is available in the [code](https://github.com/oamg/leapp-repository/blob/main/repos/system_upgrade/el7toel8/workflows/inplace_upgrade.py) and diagram [here](../inplace-upgrade-workflow). Please note that if your actor depends on some message generated by another actor, it cannot be executed in a phase before the phase of such actor. In a similar way, if your actor produces data, it needs to be executed before the actor consuming the data. - -### How to stop the upgrade in case my actor finds a problem with the system setup? - -The process of inhibiting the upgrade is done by the VerifyCheckResult actor, executed during the ReportPhase. This actor consumes messages from the _Report_ model and if any message with the flag “inhibitor” was generated it will inhibit the upgrade process. So, your actor needs to produce a _Report_ message with the flag “inhibitor” before the upgrade process gets to the ReportPhase. Read more about inhibiting the upgrade process [here](inhibit-rhel7-to-rhel8). - -### How to stop execution of my actor in case of an unexpected error? - -It’s good practice to code defensively so the code is robust. The actor should detect unexpected input or result of some operation and exit gracefully instead of tracebacking. In case you detect an unexpected behavior, let the framework know about it by raising [StopActorExecutionError](leapp.exceptions.StopActorExecutionError). Framework will act based on the [setting of the upgrade workflow](leapp.workflows.policies) in one of the following three ways: - -- end the upgrade process right away, or -- end the upgrade process after finishing the current phase, or -- do not end the upgrade process at all and continue with logging the issue only. - -### How does the logging work? - -For logging of messages not to be visible to the user by default but rather for issue investigation purposes, use simply `self.log.(msg)` within the actor. Or, within the actor’s library this way: - -```python -from leapp.libraries.stdlib import api -api.current_logger().(msg) -``` - -The usual logging practice of [Python’s logger library](https://docs.python.org/2/library/logging.html#logger-objects) applies, i.e. the `` can be for example _debug, warning, error, critical_, etc. Leapp framework will take care of these messages and provide them through appropriate channels (stdout/stderr, log files, journalctl, audit table in /var/lib/leapp/leapp.db). - -### What Python version my actor/tests code should be compatible with? - -Python 2.7+/3.6+, but keep in mind that the resulting code has to be both py2 and py3 compatible. - -### How to add tests to my new actor? - -Under “tests” folder, an actor can have Python files containing tests that will be executed using PyTest. Leapp provide tests utilities to simulate actor consuming and checking actor production. Please, refer to detailed Leapp documentation about how to write tests. - -For further information read: [Writing tests for actors](../unit-testing). - -### How to use libraries or data files in my new actor? - -An actor can have data files under the “files” folder and Python libraries under the “libraries” folder. Leapp does provide utilities to help an actor to access the files and libraries in these folders. Please, refer to detailed Leapp documentation about this. - -### Where can I report an issue or RFE related to the framework or other actors? - -You can open a GitHub issues: - -- [Leapp framework](https://github.com/oamg/leapp/issues/new) -- [Leapp actors](https://github.com/oamg/leapp-repository/issues/new) - -When filing an issue, include: - -- How to reproduce it -- All files in `/var/log/leapp`. -- The `/var/lib/leapp/leapp.db` file. - -## Where can I seek help? - -We’ll gladly answer your questions and lead you to through any troubles with the actor development. You can reach us, the OS and Application Modernization Group, at Libera.Chat IRC server in channel **#leapp**. diff --git a/docs/source/el7toel8/deprecation.md b/docs/source/el7toel8/deprecation.md deleted file mode 100644 index 243972f86..000000000 --- a/docs/source/el7toel8/deprecation.md +++ /dev/null @@ -1,49 +0,0 @@ -# Deprecated functionality in the el7toel8 repository - -Deprecated functionality is listed under the first version that the functionality -is deprecated in. Note that functionality may be deprecated in later versions -but are not listed again. -The dates in brackets correspond to the end of the deprecation protection period, -after which the related functionality can be removed at any time. - -*Note* The lists cover just the functionality provided inside the el7toel8 -repository only. For the functionality deprecated in the leapp -framework, see [List of deprecated functionality in leapp](../deprecation.md#list-of-the-deprecated-functionality-in-leapp) - -## current upstream development (till the next release + 6months) - -- nothing yet... - -## v0.19.0 (till March 2024) - -- Models - - **InstalledTargetKernelVersion** - Deprecated as the new solution has been designed to be able to handle new changes in RHEL 9.3+ system. Use the `InstalledTargetKernelInfo` message instead. - - **GrubInfo.orig_device_name** - The `GrubInfo` message is still valid, but the `orig_device_name` field has been deprecated as multiple devices can exist on a system. Use `GrubInfo.orig_devices` instead. -- Shared libraries - - **leapp.libraries.common.config.version.is_rhel_realtime()** - The function has been deprecated as the information cannot be easily determined based on the information inside `IPUConfig`. Use data in the `KernelInfo` message instead, the field `type`. - - **leapp.libraries.common.grub.get_grub_device()** - The function has been deprecated as multiple grub devices can exists on a system. Use the `leapp.libraries.common.grub.get_grub_devices()` function instead. - -## v0.16.0 (till September 2022) - -- Shared libraries - - **`leapp.libraries.common.utils.apply_yum_workaround`** - The `apply_yum_workaround` function has been deprecated, use `DNFWorkaround` message as used in the successing `RegisterYumAdjustment` actor. - -## v0.15.0 (till April 2022) -- Models - - **RequiredTargetUserspacePackages** - Deprecated because the new solution has been designed. Use the `TargetUserspacePreupgradeTasks` instead (see the `install_rpms` field). - - **RequiredUpgradeInitramPackages** - Deprecated because the new solution around the upgrade initramfs has been designed. Use the `TargetUserspaceUpgradeTasks` instead (see the `install_rpms` field). - - **UpgradeDracutModule** - Replaced by `UpgradeInitramfsTasks` (see the `include_dracut_modules` field). - - **InitrdIncludes** - Deprecated because the new solution around the target initramfs (read: initramfs created for the upgraded system) has been designed. Use the `TargetInitramfsTasks` instead (see the `include_files` field). - -## v0.12.0 (till April 2021) -- Models - - **GrubDevice** - Deprecated because the current implementation is not reliable. GRUB device detection is now in the shared grub library. Use the `leapp.libraries.common.grub.get_grub_device()` function instead. - - **UpdateGrub** - Deprecated because the current implementation is not reliable. GRUB device detection is now in the shared grub library. Use the `leapp.libraries.common.grub.get_grub_device()` function instead. -- Shared libraries - - **`leapp.libraries.common.testutils.logger_mocked.warn()`** - The logging.warn method has been deprecated in Python since version 3.3. Use the warning method instead. - -## v0.11.0 (till April 2021) -- Models - - **TMPTargetRepositoriesFacts** - Deprecated because this model was not intended for customer use. - - diff --git a/docs/source/el7toel8/envars.md b/docs/source/el7toel8/envars.md deleted file mode 100644 index 6eeb81f87..000000000 --- a/docs/source/el7toel8/envars.md +++ /dev/null @@ -1,194 +0,0 @@ -# Environment variables for the el7toel8 repository - -Actors in the el7toel8 repository use environment variables specified below. -All these envars use the suggested prefixes specified in -[the best practices document](../best-practices.md#use-the-leapp-and-leapp_devel-prefixes-for-new-envars) -for the leapp project to distinguish their purpose: _production_ or _devel_ use. - -If the argument for envars below is not specified, it is expected to set `0` -(false) or `1` (true). - -## LEAPP_GRUB_DEVICE - -Overrides the automatically detected storage device with GRUB core (e.g. -/dev/sda). - -## LEAPP_NO_RHSM - -If set to 1, Leapp does not use Red Hat Subscription Management for the upgrade. -It's equivalent to the `--no-rhsm` leapp option. - - -## LEAPP_OVL_SIZE - -For any partition that uses XFS with the ftype option set to 0, Leapp is -creating a file of a specific size in order to proceed with the upgrade. -By default, the size of that file is 2048 MB. In case the size needs to be -increased, Leapp informs you in the pre-upgrade report that the environment -variable needs to be specified. - -## LEAPP_DEBUG - -Enables debug logging. Equivalent to `--debug`, which takes precedence. - -## LEAPP_VERBOSE - -Enables debug logging. Equivalent to `--verbose`, which takes precedence. - -## LEAPP_CONFIG - -Overrides the default location of `leapp.conf`. If not specified, -`leapp/leapp.conf` is used when the command is executed inside a leapp -repository, otherwise the default `/etc/leapp/leapp.conf` is used. - -## LEAPP_LOGGER_CONFIG - -Overrides the default location of `logger.conf`. If not specified, the default -`/etc/leapp/logger.conf` is used. - -## LEAPP_ENABLE_REPOS - -Specify repositories (repoids) split by comma, that should be used during the -in-place upgrade to the target system. It's overwritten automatically in case -the `--enablerepo` option of the leapp utility is used. It's recommended to use -the `--enablerepo` option instead of the envar. - -## LEAPP_SERVICE_HOST - -Overrides the host of the service to which leapp connects to fetch necessary -data files in case they are missing. The used protocol (`http://` or -`https://`) must be specified. Defaults to `https://cert.cloud.redhat.com`. - -## LEAPP_PROXY_HOST - -If set, leapp will use this proxy to fetch necessary data files in case they -are missing. The used protocol (`http://` or `https://`) must be specified. - -## LEAPP_TARGET_PRODUCT_CHANNEL - -The alternative to the `--channel` leapp option. As a parameter accepts -a channel acronym. E.g. `eus` or `e4s`. For more info, see the -`leapp preupgrade --help`. -In case the beta channel is required, use the LEAPP_DEVEL_TARGET_PRODUCT_TYPE -envar instead. - -## LEAPP_NO_NETWORK_RENAMING - -If set to 1, the actor responsible to handle NICs names ends without doing -anything. The actor usually creates UDEV rules to preserve original NICs in -case they are changed. However, in some cases it's not wanted and it leads -in malfunction network configuration (e.g. in case the bonding is configured -on the system). It's expected that NICs have to be handled manually if needed. - -## LEAPP_DATABASE_FORCE_SYNC_ON - -If set to 1, Leapp will explicitly enable synchronization on the SQLite database. -Enabling the synchronization has negative impact on the performance -(sometimes very negative). However, it is more reliable in case of extreme -situations (e.g. lost power). -Note the synchronization is nowadays switched off by default only during the phases -executed before the reboot of the system to the upgrade environment, which we consider -safe. As a result, we do not expect that someone would want to use this option now. - -## LEAPP_NO_INSIGHTS_REGISTER - -If set to 1, Leapp does not register the system into Red Hat Insights automatically. -It's equivalent to the `--no-insights-register` leapp option. - -## LEAPP_NO_RHSM_FACTS -If set to 1, Leapp does not store migration information using Red Hat Subscription Manager. -It's equivalent to the `--no-rhsm-facts` leapp option. - -## LEAPP_NOGPGCHECK -Set to 1 to disable RPM GPG checks (same as yum/dnf --nogpgckeck option). -It's equivalent to the `--nogpgcheck` leapp option. - -## LEAPP_TARGET_ISO -Set the path to the target OS ISO image that should be used for the IPU. -It's equivalent to the `--iso` leapp option. - - -## LEAPP_UNSUPPORTED - -Necessary to use in case you use any envar with the LEAPP_DEVEL prefix -(see the list below). And in case you use the --whitelist-experimental option -for the Leapp tool. - -# Development environment variables for the el7toel8 repository - -## LEAPP_DEVEL_RPMS_ALL_SIGNED - -Leapp will consider all installed pkgs to be signed by RH - that affects -the upgrade process as by default Leapp upgrades only pkgs signed by RH. -Leapp takes care of the RPM transaction (and behaviour of applications) -related to only pkgs signed by Red Hat. What happens with the non-RH signed -RPMs is undefined. - -## LEAPP_DEVEL_TARGET_RELEASE - -Change the default target RHEL 8 minor version. - -## LEAPP_DEVEL_SKIP_CHECK_OS_RELEASE - -Do not check whether the source RHEL 7 version is the supported one. -E.g. right now Leapp does not allow you to proceed with the upgrade -when you’re not on RHEL 7.9. - -## LEAPP_DEVEL_DM_DISABLE_UDEV - -Setting the environment variable provides a more convenient -way of disabling udev support in libdevmapper, dmsetup and LVM2 tools globally -without a need to modify any existing configuration settings. -This is mostly useful if the system environment does not use udev. - -## LEAPP_DEVEL_SOURCE_PRODUCT_TYPE - -By default the upgrade is processed from the GA (general availability) system -using GA repositories. In case you need to do the in-place upgrade from -a Beta system, use the variable to tell which of those you would like -to use. The value is case insensitive and the default value is `ga`. -Expected values: `ga`, `beta`. - -## LEAPP_DEVEL_TARGET_PRODUCT_TYPE - -`LEAPP_DEVEL_TARGET_PRODUCT_TYPE` is an analogy to -`LEAPP_DEVEL_SOURCE_PRODUCT_TYPE` for the target system and an extension to -`LEAPP_TARGET_PRODUCT_CHANNEL`. If used, it replaces any value set via the -`--channel` option or through the `LEAPP_TARGET_PRODUCT_CHANNEL` environment -variable . It consumes the same set of values as the `--channel` option, and -can be extended with the value `beta`. This is the only way how to perform the -inplace upgrade to a beta version of the target system using the -subscription-manager. - -## LEAPP_DEVEL_USE_PERSISTENT_PACKAGE_CACHE - -Caches downloaded packages when equal to 1. This will reduce the time needed -by leapp, when executed multiple times, because it will not have to download -already downloaded packages. However, this can lead to a random issues in case -the data is not fresh or changes of settings and repositories. The environment -variable is meant to be used only for the part before the reboot and has no -effect or use otherwise. - -## LEAPP_DEVEL_DATABASE_SYNC_OFF - -If set to 1, leapp will disable explicit synchronization on the SQLite -database. The positive effect is significant speed up of the leapp execution, -however it comes at the cost of risking a corrupted database, so it is -currently used for testing / development purposes, only. - -## LEAPP_DEVEL_INITRAM_NETWORK -You can specify one of the following values: 'network-manager', 'scripts'. -The 'scripts' value is used for a legacy dracut module when the network is not -handled by NetworkManager. -Using the option allows experimental upgrades, bringing up the networking inside -the upgrade initramfs environment (upgrade phases after the first reboot). -It also allows the upgrade e.g. when a network based storage is used -on the system. Currently it works only for the most simple configurations -(e.g. when only 1 NIC is present, no rdma, no bonding, ...). Network based -storage is not handled anyhow during the upgrade, so it's possible that the network -based storage will not be correctly initialized and usable as expected). - -## LEAPP_DEVEL_KEEP_DISK_IMGS -If set to 1, leapp will skip removal of disk images created for source OVLs. -This is handy for debugging and investigations related to created containers -(the scratch one and the target userspace container). diff --git a/docs/source/el7toel8/inhibit-rhel7-to-rhel8.md b/docs/source/el7toel8/inhibit-rhel7-to-rhel8.md deleted file mode 100644 index c2c592fdc..000000000 --- a/docs/source/el7toel8/inhibit-rhel7-to-rhel8.md +++ /dev/null @@ -1,162 +0,0 @@ -# How to properly inhibit the RHEL 7 to 8 upgrade process - -## Process Inhibition - -With latest changes on Leapp and with new actors added to the el7toel8 Leapp -repository, any actor can inhibit the upgrade process by producing a specific -message when a problem is found. The message model to use in this case is -[Report](leapp.reporting.Report). -If there is at least one Report message with the `'inhibitor'` group produced before -the Report phase, the upgrade will be stopped in the Reports phase, in which the -messages are being collected. It means that any Report message produced -**after** the Report phase will **not** have inhibiting effect. The details -mentioned in the Report messages will be part of the report available to the -user to review. - -### Sample Actor - -Let’s start with a very simple actor that will verify if system architecture is -supported (this actor may be removed in the future as more archs will be supported): - -```python -import platform - -from leapp.actors import Actor -from leapp.tags import ChecksPhaseTag - - -class CheckSystemArch(Actor): - """ - Check if system is running at a supported architecture. If no, inhibit the upgrade process. - - Base on collected system facts, verify if current architecture is supported, otherwise produces - a message to inhibit upgrade process - """ - - name = 'check_system_arch' - consumes = () - produces = () - tags = (ChecksPhaseTag,) - - def process(self): - if platform.machine() != 'x86_64': - self.log.info("Unsupported arch!") -``` - -If this actor is executed using `snactor` tool in a system with unsupported -architecture, we will see the following output on log: - -```sh -$ snactor run CheckSystemArch --verbose -2019-04-16 15:08:59.622 INFO PID: 1996 leapp: Logging has been initialized -2019-04-16 15:08:59.638 INFO PID: 1996 leapp.repository.sandbox: A new repository 'sandbox' is initialized at /home/leapp/sandbox -2019-04-16 15:08:59.695 INFO PID: 2021 leapp.actors.check_system_arch: Unsupported arch! -``` - -If, instead of only adding a message to the log, the actor writer wants to make -sure that the upgrade process will be stopped in case of unsupported arch, the -actor needs to produce a [Report](leapp.reporting.Report) -message using one of the `report_*` functions from the [reporting](https://github.com/oamg/leapp-repository/blob/main/repos/system_upgrade/el7toel8/libraries/reporting.py) -shared library with the `'inhibitor'` group. - -```python -import platform - -from leapp.actors import Actor -from leapp.reporting import Report, create_report -from leapp import reporting -from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - - -class CheckSystemArch(Actor): - """ - Check if system is running at a supported architecture. If no, inhibit the upgrade process. - - Base on collected system facts, verify if current architecture is supported, otherwise produces - a message to inhibit upgrade process - """ - - name = 'check_system_arch' - consumes = () - produces = (Report,) - tags = (ChecksPhaseTag, IPUWorkflowTag) - - def process(self): - if platform.machine() != 'x86_64': - create_report([ - reporting.Title('Unsupported architecture'), - reporting.Summary('Upgrade process is only supported on x86_64 systems.'), - reporting.Severity(reporting.Severity.HIGH), - reporting.Groups([reporting.Groups.INHIBITOR, reporting.Groups.SANITY]), - ]) -``` - -Running the actor again, it is possible to verify that a new message was -generated. We will still use `snactor` tool to run the actor, but passing -`--print-output` this time to output all generated messages by the actor: - -```sh -$ snactor run CheckSystemArch --verbose --print-output -2019-04-16 15:20:32.74 INFO PID: 2621 leapp: Logging has been initialized -2019-04-16 15:20:32.94 INFO PID: 2621 leapp.repository.sandbox: A new repository 'sandbox' is initialized at /home/leapp/sandbox -[ - { - "stamp": "2019-09-05T12:58:56.342095Z", - "hostname": "leapp-20190904152934", - "actor": "check_system_arch", - "topic": "report_topic", - "context": "9a064a30-5d16-44ba-a807-b7f08b3c4215", - "phase": "NON-WORKFLOW-EXECUTION", - "message": { - "hash": "dc95adcfca56eae62b7fcceeb0477a6d8257c3dddd1b05b879ebdcf05f59d504", - "data": "{\"report\": \"{\\\"audience\\\": \\\"sysadmin\\\", \\\"groups\\\": [\\\"inhibitor\\\", \\\"sanity\\\"], \\\"severity\\\": \\\"high\\\", \\\"summary\\\": \\\"Upgrade process is only supported on x86_64 systems.\\\", \\\"title\\\": \\\"Unsupported architecture\\\"}\"}" - }, - "type": "Report" - } -] - -``` - -Or to inspect closely the message.data field, we could use `jq` tool: - -```sh -snactor run CheckSystemArch --verbose --print-output | jq '.[] | .message.data | fromjson' -{ - "report": "{\"audience\": \"sysadmin\", \"groups\": [\"inhibitor\", \"sanity\"], \"severity\": \"high\", \"summary\": \"Upgrade process is only supported on x86_64 systems.\", \"title\": \"Unsupported architecture\"}" -} - -``` - -This is all that an actor needs to do in order to verify if some condition is -present on the system and inhibit the upgrade process based on that check. - -After all the system checks are executed by different actors, an existing actor -==== BASE ==== -named [VerifyCheckResults](https://github.com/oamg/leapp-repository/tree/master/repos/system_upgrade/el7toel8/actors/verifycheckresults) -is scheduled to run in the Leapp upgrade workflow. If some [Report](/pydoc/leapp.reporting.html#leapp.reporting.Report) -==== BASE ==== -message with the `'inhibitor'` group was generated by some previous execution of -another actor in any previous phase of the workflow, like the sample one we just -wrote, the following output will be displayed to the user: - -```sh -$ leapp upgrade -(...) -2019-04-16 15:36:54.696 INFO PID: 7455 leapp.workflow: Starting phase Reports -2019-04-16 15:36:54.715 INFO PID: 7455 leapp.workflow.Reports: Starting stage Before of phase Reports -2019-04-16 15:36:54.764 INFO PID: 7455 leapp.workflow.Reports: Starting stage Main of phase Reports -2019-04-16 15:36:54.788 INFO PID: 7455 leapp.workflow.Reports: Executing actor verify_check_results -2019-04-16 15:36:54.923 INFO PID: 7455 leapp.workflow.Reports: Starting stage After of phase Reports -2019-04-16 15:36:54.970 INFO PID: 7455 leapp.workflow: Workflow interrupted due to the FailPhase error policy - -============================================================ - ERRORS -============================================================ - -2019-04-16 15:36:54.871634 [ERROR] Actor: verify_check_results Message: Unsupported arch -2019-04-16 15:36:54.888818 [ERROR] Actor: verify_check_results Message: Ending process due to errors found during checks, see /var/log/leapp-report.txt for detailed report. - -============================================================ - END OF ERRORS -============================================================ -``` diff --git a/docs/source/el7toel8/leapp-repository-el7toel8.rst b/docs/source/el7toel8/leapp-repository-el7toel8.rst deleted file mode 100644 index 036c6c9c3..000000000 --- a/docs/source/el7toel8/leapp-repository-el7toel8.rst +++ /dev/null @@ -1,11 +0,0 @@ -Leapp repository for RHEL 7 to RHEL 8 upgrade -============================================= -This is the official upstream documentation for the leapp repository for in-place upgrade (IPU) from RHEL 7 to RHEL 8. The homepage of the project is `here `_. - -.. toctree:: - :caption: Contents: - - actor-rhel7-to-rhel8 - inhibit-rhel7-to-rhel8 - envars - deprecation diff --git a/docs/source/faq.md b/docs/source/faq.md index 2e7d37d4d..a8f9e752b 100644 --- a/docs/source/faq.md +++ b/docs/source/faq.md @@ -1,7 +1,6 @@ # Frequently Asked Questions - [What is Leapp?](#what-is-leapp) -- [How can I get on board with contributing to Leapp?](#how-can-i-get-on-board-with-contributing-to-leapp) - [What is an actor and what does it do?](#what-is-an-actor-and-what-does-it-do) - [When and why do I need to write an actor?](#when-and-why-do-i-need-to-write-an-actor) - [How can I exchange any data between actors?](#how-can-i-exchange-any-data-between-actors) @@ -21,10 +20,6 @@ Leapp project aims to enable users to modernize their existing workloads without disrupting them in three different ways: upgrading them in place, migrating them to a different place or containerize them. Currently, the in-place upgrade functionality is being worked on only. -## How can I get on board with contributing to Leapp? - -For the Leapp framework we are currently developing the functionality for the in-place upgrade of RHEL 7 to RHEL 8. You can improve the user experience of the upgrade by creating so called actors for the Leapp framework. We've written a quick guide on how to create such actors for the RHEL 7 to RHEL 8 upgrades: [How to create a Leapp actor for RHEL 7 to 8 upgrade.](el7toel8/actor-rhel7-to-rhel8) - ## What is an actor and what does it do? An actor in the realm of the Leapp project is a step that is executed within a workflow. Actors define what kind of data they expect and what kind of data they produce. @@ -38,13 +33,11 @@ In regards to the upgrades of RHEL 7 to RHEL 8, Leapp should be able to upgrade ## How can I exchange any data between actors? All communication between actors in Leapp is carried out using " messages". An actor can consume or produce messages. A message may contain any data, but the data needs to be in a specific format defined by a "model". If an actor wants to consume a message produced by another actor, it needs to specify the specific model of the consumed messages. Leapp will make sure to execute such an actor only after some message of the specified model was produced by another actor. If no message of the specified model was produced in previous phases or in the current phase, the consuming actor will get no messages of that kind. -Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhel7-to-rhel8) ## What do I have to do in order to execute actor I just wrote? If you want to execute just a single actor when developing it, then use the snactor tool. [Here's a tutorial](tutorials/first-actor) on how to use it. -If you want to add your actor to an existing workflow, for example the RHEL 7 to 8 upgrade workflow, then tag your actor with appropriate workflow and phase tags. -Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhel7-to-rhel8) +If you want to add your actor to an existing workflow, for example the RHEL in-upgrade workflow, then tag your actor with appropriate workflow and phase tags. ## What should I do if I need to execute multiple actors? Can I somehow ensure the dependencies between them? @@ -80,7 +73,6 @@ It should follow the [Contribution guidelines](contributing) and the [Best pract ## How can I debug my actor? Is there a standard/supported way how to log and get logs from actors/channels? You can run your actor using the snactor tool and printing the output. [See the tutorial](tutorials/first-actor) on how to use snactor. -Source: [How to create a Leapp actor for RHEL 7 to 8 upgrade](el7toel8/actor-rhel7-to-rhel8) ## Are there some technical limitations for an actor? E.g. maximum time execution, size of the input/output, libraries I can use... In case there are, is it possible to specify that the actor needs e.g. longer time for execution? diff --git a/docs/source/inplace-upgrade-workflow.md b/docs/source/inplace-upgrade-workflow.md deleted file mode 100644 index 2b65c3864..000000000 --- a/docs/source/inplace-upgrade-workflow.md +++ /dev/null @@ -1,3 +0,0 @@ -# Inplace Upgrade Workflow - -[![In Place Upgrade Workflow](_static/images/inplace-upgrade-workflow.svg)](_static/images/inplace-upgrade-workflow.svg) diff --git a/docs/source/leapp-repositories.rst b/docs/source/leapp-repositories.rst deleted file mode 100644 index 8db98569a..000000000 --- a/docs/source/leapp-repositories.rst +++ /dev/null @@ -1,14 +0,0 @@ -Leapp repositories -================== - -Here you can find all the information related to -`leapp repositories `_, including the documentation -for existing leapp repositories managed by the OS and Application -Modernization Group (`OAMG `_) - - -.. toctree:: - :caption: Contents: - - repository-dir-layout - el7toel8/leapp-repository-el7toel8 From 7153974c7e0671f85d3ee52fcc8e0f4b31872e6b Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 30 Jul 2024 12:44:52 +0200 Subject: [PATCH 11/13] docs: Fix non-consecutive and incorrect header levels --- docs/source/tutorials/debugging.md | 6 +++--- docs/source/tutorials/dialogs.md | 6 +++--- docs/source/tutorials/messaging.md | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/source/tutorials/debugging.md b/docs/source/tutorials/debugging.md index b1e222ec1..7222f6e82 100644 --- a/docs/source/tutorials/debugging.md +++ b/docs/source/tutorials/debugging.md @@ -1,6 +1,6 @@ -## Debugging actors +# Debugging actors -### Snactor +## Snactor The snactor tool is used to debug your actors. You can execute actors and save their output, so that it can be consumed by other actors. @@ -11,7 +11,7 @@ the --debug parameter which sets the environment variable to '1' when it is used. In that case, it enables the debug logging, so that any actor that logs to self.log.debug gets its output printed on the commandline. -### PyCharm / rpdb +## PyCharm / rpdb You can configure PyCharm to debug by pointing it to the snactor path and passing the arguments on the command line. The PyCharm debugger will also follow the child processes that are created by the snactor tool to execute the actor diff --git a/docs/source/tutorials/dialogs.md b/docs/source/tutorials/dialogs.md index d863fabce..2ae7e3812 100644 --- a/docs/source/tutorials/dialogs.md +++ b/docs/source/tutorials/dialogs.md @@ -10,7 +10,7 @@ As an example we will change [IpResolver](messaging.md#creating-a-message-consum will decide which hostnames will be resolved. -### Creating the dialog +## Creating the dialog Import Dialog and MultipleChoiceComponent from leapp.dialog and leapp.dialog.components respectively. Create an instance of Dialog, specifying scope which is used to identify data in the answer file, @@ -38,7 +38,7 @@ class IpResolver(Actor): description='No description'),)),) ``` -### Using the dialog and the answers +## Using the dialog and the answers To pose a question that needs to be answered use get_answers method and pass the dialog containing the question. @@ -70,7 +70,7 @@ def process(self): self.produce(ResolvedHostname(name=hostname, ips=ips)) ``` -### Explaining the dialogs processing mechanism during the upgrade +## Explaining the dialogs processing mechanism during the upgrade The upgrade itself, from the operator's point of view, consists of 3 distinct stages: preupgrade, remediate and upgrade. diff --git a/docs/source/tutorials/messaging.md b/docs/source/tutorials/messaging.md index f1f56368c..6472fd516 100644 --- a/docs/source/tutorials/messaging.md +++ b/docs/source/tutorials/messaging.md @@ -1,4 +1,4 @@ -## Using messaging to send data between actors +# Using messaging to send data between actors The Leapp framework uses messages to send data to other actors that are executed afterward. Messages are defined through the models declared [earlier](first-actor.md#creating-a-model). Actors can consume these messages and produce data based on their input. @@ -6,7 +6,7 @@ Messages are defined through the models declared [earlier](first-actor.md#creati As an example, the actors consume Hostname messages, resolve IPs for those hostnames, and create the ResolvedHostname model to send a new type of message. -### Creating the ResolvedHostname model +## Creating the ResolvedHostname model Create the ResolvedHostname model by using the snactor tool. @@ -39,7 +39,7 @@ fields.Nullable(fields.String()) are required. -### Creating a message consuming actor +## Creating a message consuming actor Create a new actor that resolves the IPs for the hostnames: @@ -96,7 +96,7 @@ class IpResolver(Actor): self.produce(ResolvedHostname(name=hostname.name, ips=ips)) ``` -### Storing messages in the repository data for reuse +## Storing messages in the repository data for reuse The `snactor` framework tool saves the output of actors as locally stored messages, so that they can be consumed by other actors that are being developed. @@ -110,7 +110,7 @@ $ snactor run --save-output HostnameScanner The output of the actor is stored in the local repository data file, and it can be used by other actors. To flush all saved messages from the repository database, run `snactor messages clear`. -### Testing the new actor +## Testing the new actor With the input messages available and stored, the actor can be tested. @@ -136,6 +136,6 @@ $ snactor run --print-output IpResolver ] ``` -#### Screencast +### Screencast From 493b1d21f485284ee9e72a432a46e925930f2ff6 Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Tue, 10 Sep 2024 17:17:11 +0200 Subject: [PATCH 12/13] docs: Add make rule to prepare venv similar to RTD build env --- docs/Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index 709c35b80..c3b8cc03a 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,9 +17,19 @@ help: livehtml: @$(SPHINXAUTOBUILD) --watch ../leapp "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(0) +# Prepare virtualenv similar to the environment used during build on Read The Docs and install required packages +env: + PY_VER=$$(sed -n -e 's/^\s*python:\s"\(.*\)"/\1/p' ../.readthedocs.yaml); \ + echo $$PY_VER; \ + rm -fr ./venv; \ + virtualenv venv --python=python$$PY_VER; \ + source venv/bin/activate; \ + # pip install -r doesn't really work with relative paths :), so keeping it in the project root + pushd .. && pip install -r requirements-docs.txt; popd + # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -.PHONY: all help Makefile +.PHONY: all help Makefile env From a6d75a781f9f88247d91fa448af9c7849803c75d Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Wed, 11 Sep 2024 07:38:13 +0200 Subject: [PATCH 13/13] fixup! docs: Add make rule to prepare venv similar to RTD build env --- docs/Makefile | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index c3b8cc03a..6e7d4f607 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -13,23 +13,27 @@ BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @source venv/bin/activate && \ + $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + livehtml: - @$(SPHINXAUTOBUILD) --watch ../leapp "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(0) + @source venv/bin/activate && \ + $(SPHINXAUTOBUILD) --watch ../leapp "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(0) # Prepare virtualenv similar to the environment used during build on Read The Docs and install required packages env: - PY_VER=$$(sed -n -e 's/^\s*python:\s"\(.*\)"/\1/p' ../.readthedocs.yaml); \ + # ad. pip install -r doesn't really work with relative paths :), so keeping it in the project root + @PY_VER=$$(sed -n -e 's/^\s*python:\s"\(.*\)"/\1/p' ../.readthedocs.yaml); \ echo $$PY_VER; \ rm -fr ./venv; \ - virtualenv venv --python=python$$PY_VER; \ - source venv/bin/activate; \ - # pip install -r doesn't really work with relative paths :), so keeping it in the project root + virtualenv venv --python=python$$PY_VER && \ + source venv/bin/activate && \ pushd .. && pip install -r requirements-docs.txt; popd # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @source venv/bin/activate && \ + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: all help Makefile env