-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Per request this patch adds support for rerunning leapp from a certain point. As for now it only supports the FirstBoot phase to be re-run. In order to accomplish the re-run functionality leapp clones the context of the last upgrade execution and removes all checkpoints and errors from it. Cloning means it will duplicate all the context aware data in the database in order to allow a post mortem inspection of what has happened. So it will not blindly delete data but remove the errors and checkpoints only from the cloned part of the data. Additionally it allows to select only actors which have a certain tag specified during the re-run. This will help users that want to re-run their own set of actors only during the FirstBoot phase without having to create a complicated workaround using snactor and somehow getting it to use the data from the upgrade. This allows the actors that are re-run to consume messages that have been generated during the upgrade before this phase has been run. Signed-off-by: Vinzenz Feenstra <[email protected]>
- Loading branch information
Showing
21 changed files
with
465 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
|
||
from leapp.cli import main | ||
import leapp.utils.i18n # noqa: F401; pylint: disable=unused-import | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
from leapp.utils.audit import dict_factory, get_connection | ||
|
||
|
||
def _fetch_table_for_context(db, table, context): | ||
cursor = db.execute(''' | ||
SELECT * FROM {table} WHERE context = ? | ||
'''.format(table=table), (context,)) | ||
cursor.row_factory = dict_factory | ||
while True: | ||
row = cursor.fetchone() | ||
if not row: | ||
break | ||
yield row | ||
del cursor | ||
|
||
|
||
def _row_tuple(row, *fields): | ||
return tuple([row[name] for name in fields or row.keys()]) | ||
|
||
|
||
def _dup_host(db, newcontext, oldcontext): | ||
lookup = {} | ||
for row in _fetch_table_for_context(db, 'host', oldcontext): | ||
# id, context, hostname | ||
row_id, hostname = _row_tuple(row, 'id', 'hostname') | ||
cursor = db.execute('INSERT INTO host (context, hostname) VALUES(?, ?)', | ||
(newcontext, hostname)) | ||
lookup[row_id] = cursor.lastrowid | ||
return lookup | ||
|
||
|
||
def _dup_data_source(db, host, newcontext, oldcontext): | ||
lookup = {} | ||
for row in _fetch_table_for_context(db, 'data_source', oldcontext): | ||
# id, context, hostname | ||
row_id, host_id, actor, phase = _row_tuple(row, 'id', 'host_id', 'actor', 'phase') | ||
cursor = db.execute('INSERT INTO data_source (context, host_id, actor, phase) VALUES(?, ?, ?, ?)', | ||
(newcontext, host[host_id], actor, phase)) | ||
lookup[row_id] = cursor.lastrowid | ||
return lookup | ||
|
||
|
||
def _dup_message(db, data_source, newcontext, oldcontext): | ||
lookup = {} | ||
for row in _fetch_table_for_context(db, 'message', oldcontext): | ||
# id, context, data_source_id, stamp, topic, type, message_data_hash | ||
row_id, data_source_id, stamp, topic, type_, message_data_hash = _row_tuple( | ||
row, 'id', 'data_source_id', 'stamp', 'topic', 'type', 'message_data_hash') | ||
cursor = db.execute( | ||
'INSERT INTO message (context, data_source_id, stamp, topic, type, message_data_hash) ' | ||
' VALUES(?, ?, ?, ?, ?, ?)', | ||
(newcontext, data_source[data_source_id], stamp, topic, type_, message_data_hash)) | ||
lookup[row_id] = cursor.lastrowid | ||
return lookup | ||
|
||
|
||
def _dup_audit(db, message, data_source, newcontext, oldcontext): | ||
lookup = {} | ||
for row in _fetch_table_for_context(db, 'audit', oldcontext): | ||
# id, context, event, stamp, data_source_id, message_id, data | ||
row_id, event, stamp, data_source_id, message_id, data = _row_tuple( | ||
row, 'id', 'event', 'stamp', 'data_source_id', 'message_id', 'data') | ||
if message_id is not None: | ||
message_id = message[message_id] | ||
|
||
cursor = db.execute( | ||
'INSERT INTO audit (context, event, stamp, data_source_id, message_id, data) VALUES(?, ?, ?, ?, ?, ?)', | ||
(newcontext, event, stamp, data_source[data_source_id], message_id, data)) | ||
lookup[row_id] = cursor.lastrowid | ||
return lookup | ||
|
||
|
||
def clone_context(oldcontext, newcontext, use_db=None): | ||
# Enter transaction - In case of any exception automatic rollback is issued | ||
# and it is automatically committed if there was no exception | ||
with get_connection(use_db) as db: | ||
# First clone host entries | ||
host = _dup_host(db=db, newcontext=newcontext, oldcontext=oldcontext) | ||
# Next clone data_source entries and use the lookup table generated by the host duplication | ||
data_source = _dup_data_source(db=db, host=host, newcontext=newcontext, oldcontext=oldcontext) | ||
# Next clone message entries and use the lookup table generated by the data_source duplication | ||
message = _dup_message(db=db, data_source=data_source, newcontext=newcontext, oldcontext=oldcontext) | ||
# Last clone message entries and use the lookup table generated by the data_source and message duplications | ||
_dup_audit(db=db, data_source=data_source, message=message, newcontext=newcontext, oldcontext=oldcontext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name": "ipu-rerun-repo", "id": "bae57f03-85e0-4dea-9a6d-88c40205c7a3"} |
6 changes: 6 additions & 0 deletions
6
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/.leapp/leapp.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
[repositories] | ||
repo_path=${repository:root_dir} | ||
|
||
[database] | ||
path=${repository:state_dir}/leapp.db |
16 changes: 16 additions & 0 deletions
16
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/actors/firstbootactor/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from leapp.actors import Actor | ||
from leapp.tags import InplaceUpgradeWorkflowTag, FirstBootTag | ||
|
||
|
||
class FirstBootActor(Actor): | ||
""" | ||
No documentation has been provided for the first_boot_actor actor. | ||
""" | ||
|
||
name = 'first_boot_actor' | ||
consumes = () | ||
produces = () | ||
tags = (InplaceUpgradeWorkflowTag, FirstBootTag) | ||
|
||
def process(self): | ||
print('<<<TEST>>>: {}'.format(self.__class__.__name__)) |
16 changes: 16 additions & 0 deletions
16
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/actors/phaseaactor/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from leapp.actors import Actor | ||
from leapp.tags import InplaceUpgradeWorkflowTag, PhaseATag | ||
|
||
|
||
class PhaseAActor(Actor): | ||
""" | ||
No documentation has been provided for the phase_a_actor actor. | ||
""" | ||
|
||
name = 'phase_a_actor' | ||
consumes = () | ||
produces = () | ||
tags = (InplaceUpgradeWorkflowTag, PhaseATag) | ||
|
||
def process(self): | ||
print('<<<TEST>>>: {}'.format(self.__class__.__name__)) |
16 changes: 16 additions & 0 deletions
16
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/actors/phasebactor/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from leapp.actors import Actor | ||
from leapp.tags import InplaceUpgradeWorkflowTag, PhaseBTag | ||
|
||
|
||
class PhaseBActor(Actor): | ||
""" | ||
No documentation has been provided for the phase_b_actor actor. | ||
""" | ||
|
||
name = 'phase_b_actor' | ||
consumes = () | ||
produces = () | ||
tags = (InplaceUpgradeWorkflowTag, PhaseBTag) | ||
|
||
def process(self): | ||
print('<<<TEST>>>: {}'.format(self.__class__.__name__)) |
16 changes: 16 additions & 0 deletions
16
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/actors/rerunactor/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from leapp.actors import Actor | ||
from leapp.tags import InplaceUpgradeWorkflowTag, FirstBootTag, ReRunVerifyTag | ||
|
||
|
||
class ReRunActor(Actor): | ||
""" | ||
No documentation has been provided for the re_run_actor actor. | ||
""" | ||
|
||
name = 're_run_actor' | ||
consumes = () | ||
produces = () | ||
tags = (InplaceUpgradeWorkflowTag, FirstBootTag, ReRunVerifyTag) | ||
|
||
def process(self): | ||
print('<<<TEST>>>: {}'.format(self.__class__.__name__)) |
16 changes: 16 additions & 0 deletions
16
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/actors/rerunactorother/actor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from leapp.actors import Actor | ||
from leapp.tags import InplaceUpgradeWorkflowTag, FirstBootTag, ReRunVerifyOtherTag | ||
|
||
|
||
class ReRunActorOther(Actor): | ||
""" | ||
No documentation has been provided for the re_run_actor_other actor. | ||
""" | ||
|
||
name = 're_run_actor_other' | ||
consumes = () | ||
produces = () | ||
tags = (InplaceUpgradeWorkflowTag, FirstBootTag, ReRunVerifyOtherTag) | ||
|
||
def process(self): | ||
print('<<<TEST>>>: {}'.format(self.__class__.__name__)) |
5 changes: 5 additions & 0 deletions
5
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/tags/firstboot.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from leapp.tags import Tag | ||
|
||
|
||
class FirstBootTag(Tag): | ||
name = 'first_boot' |
5 changes: 5 additions & 0 deletions
5
tests/data/leapp-rerun-tests-repos/ipu-rerun-repo/tags/inplaceupgradeworkflow.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from leapp.tags import Tag | ||
|
||
|
||
class InplaceUpgradeWorkflowTag(Tag): | ||
name = 'inplace_upgrade_workflow' |
Oops, something went wrong.