Skip to content

Commit

Permalink
history: Avoid using temp file while using transaction_sr
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Mach committed Nov 24, 2020
1 parent b9ccf98 commit 12f9677
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 49 deletions.
45 changes: 8 additions & 37 deletions dnf/cli/commands/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
import json
import logging
import os
import shutil
import sys
import tempfile


logger = logging.getLogger('dnf')
Expand Down Expand Up @@ -167,24 +165,10 @@ def _hcmd_redo(self, extcmds):

# TODO(dmach): refactor store/replay code to avoid using the temporary file
data = serialize_transaction(old)
tmp_dir = tempfile.mkdtemp(prefix="dnf_history_redo_")
filename = os.path.join(tmp_dir, "transaction.json")
try:
# store the transaction into a json file that will be loaded in the following step
with open(filename, "w") as f:
json.dump(data, f, indent=4, sort_keys=True)
f.write("\n")

# replay the transaction from file
self.base.read_comps(arch_filter=True)
self.replay = TransactionReplay(self.base, filename, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable)
self.replay.run()
finally:
# cleanup, remove the json with stored transaction
try:
shutil.rmtree(tmp_dir)
except:
pass
self.base.read_comps(arch_filter=True)
self.replay = TransactionReplay(self.base, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable)
self.replay.load_from_dict(data)
self.replay.run()

def _hcmd_undo(self, extcmds):
old = self.base.history_get_transaction(extcmds)
Expand Down Expand Up @@ -241,28 +225,15 @@ def _revert_transaction(self, trans):
if ti["action"] == "Install" and ti.get("reason", None) == "clean":
ti["reason"] = "dependency"

tmp_dir = tempfile.mkdtemp(prefix="dnf_history_rollback_")
filename = os.path.join(tmp_dir, "transaction.json")
self.base.read_comps(arch_filter=True)
self.replay = TransactionReplay(self.base, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable)
try:
# store the transaction into a json file that will be loaded in the following step
with open(filename, "w") as f:
json.dump(data, f, indent=4, sort_keys=True)
f.write("\n")

# replay the transaction from file
self.base.read_comps(arch_filter=True)
self.replay = TransactionReplay(self.base, filename, ignore_installed=True, ignore_extras=True, skip_unavailable=self.opts.skip_unavailable)
self.replay.load_from_dict(data)
self.replay.run()
except dnf.transaction_sr.TransactionFileError as ex:
for error in ex.errors:
print(error, file=sys.stderr)
raise dnf.exceptions.PackageNotFoundError(_('no package matched'))
finally:
# cleanup, remove the json with stored transaction
try:
shutil.rmtree(tmp_dir)
except:
pass

def _hcmd_userinstalled(self):
"""Execute history userinstalled command."""
Expand Down Expand Up @@ -342,11 +313,11 @@ def run(self):

self.replay = TransactionReplay(
self.base,
self.opts.transaction_filename,
ignore_installed = self.opts.ignore_installed,
ignore_extras = self.opts.ignore_extras,
skip_unavailable = self.opts.skip_unavailable
)
self.replay.load_from_file(self.opts.transaction_filename)
self.replay.run()
else:
tids, merged_tids = self._args2transaction_ids()
Expand Down
29 changes: 17 additions & 12 deletions dnf/transaction_sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ class TransactionReplay(object):
def __init__(
self,
base,
fn,
ignore_extras=False,
ignore_installed=False,
skip_unavailable=False
Expand All @@ -208,7 +207,7 @@ def __init__(
"""

self._base = base
self._filename = fn
self._filename = ""
self._ignore_installed = ignore_installed
self._ignore_extras = ignore_extras
self._skip_unavailable = skip_unavailable
Expand All @@ -220,25 +219,31 @@ def __init__(
self._nevra_reason_cache = {}
self._warnings = []

def load_from_file(self, fn):
self._filename = fn
with open(fn, "r") as f:
try:
self._replay_data = json.load(f)
replay_data = json.load(f)
except json.decoder.JSONDecodeError as e:
raise TransactionFileError(fn, str(e) + ".")

try:
self._verify_toplevel_json(self._replay_data)
self.load_from_dict(replay_data)
except TransactionError as e:
raise TransactionFileError(fn, e)

self._rpms = self._replay_data.get("rpms", [])
self._assert_type(self._rpms, list, "rpms", "array")
def load_from_dict(self, data):
self._replay_data = data
self._verify_toplevel_json(self._replay_data)

self._groups = self._replay_data.get("groups", [])
self._assert_type(self._groups, list, "groups", "array")
self._rpms = self._replay_data.get("rpms", [])
self._assert_type(self._rpms, list, "rpms", "array")

self._environments = self._replay_data.get("environments", [])
self._assert_type(self._environments, list, "environments", "array")
except TransactionError as e:
raise TransactionFileError(fn, e)
self._groups = self._replay_data.get("groups", [])
self._assert_type(self._groups, list, "groups", "array")

self._environments = self._replay_data.get("environments", [])
self._assert_type(self._environments, list, "environments", "array")

def _raise_or_warn(self, warn_only, msg):
if warn_only:
Expand Down

0 comments on commit 12f9677

Please sign in to comment.