Merge ~jslarraz/review-tools:use-logging-module into review-tools:master

Proposed by Jorge Sancho Larraz
Status: Merged
Merged at revision: f2c630c4f9025a91435ee9a60d93b382756c13e4
Proposed branch: ~jslarraz/review-tools:use-logging-module
Merge into: review-tools:master
Diff against target: 1149 lines (+150/-212)
17 files modified
bin/create-snap-declaration (+3/-3)
bin/dump-tool (+9/-9)
bin/rock-check-notices (+6/-7)
bin/rock-updates-available (+7/-7)
bin/snap-check-notices (+6/-7)
bin/snap-review (+8/-18)
bin/snap-updates-available (+10/-10)
bin/snap-verify-declaration (+8/-11)
bin/store-query (+11/-9)
reviewtools/__init__.py (+16/-0)
reviewtools/available.py (+5/-7)
reviewtools/common.py (+17/-58)
reviewtools/sr_declaration.py (+4/-3)
reviewtools/store.py (+26/-27)
tests/test-dump-tool.sh.expected (+8/-8)
tests/test-snap-verify-declaration.sh.expected (+3/-25)
tests/test-updates-available.sh.expected (+3/-3)
Reviewer Review Type Date Requested Status
Alex Murray Approve
Review via email: mp+466961@code.launchpad.net

Commit message

Use python logging module instead of custom error, warn, msg and debug functions defined in reviewtools.common

To post a comment you must log in.
Revision history for this message
Jorge Sancho Larraz (jslarraz) wrote :

This MR slighly changes the output format under certain circumstances. It removes the ability to return json formatted errors for errors generated by the cli script caused during the cli arguments validation/processing. This behaviour looks desirable to me anyway tbh

See inline comments!

Revision history for this message
Jorge Sancho Larraz (jslarraz) :
Revision history for this message
Alex Murray (alexmurray) wrote :

Thanks for the very extensive comments to help walk-through this MR - it was very valuable. I really like this cleanup and it makes the code more pythonic by using the standard logging module, plus I actually like the CLI printing the errors directly rather than including them in the json output. LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bin/create-snap-declaration b/bin/create-snap-declaration
index 4666a65..a924e93 100755
--- a/bin/create-snap-declaration
+++ b/bin/create-snap-declaration
@@ -5,6 +5,7 @@ import json
5import re5import re
6import sys6import sys
77
8from reviewtools import logger
8from reviewtools.common import read_snapd_base_declaration9from reviewtools.common import read_snapd_base_declaration
910
10decl = {}11decl = {}
@@ -158,9 +159,8 @@ def add_missing():
158159
159 cstr_s = "allow-%s" % cstr160 cstr_s = "allow-%s" % cstr
160 if in_base and cstr_s not in decl[side][iface]:161 if in_base and cstr_s not in decl[side][iface]:
161 print(162 logger.warning(
162 "WARN: adding missing '%s' for '%s' from base decl"163 "adding missing '%s' for '%s' from base decl" % (cstr, iface)
163 % (cstr, iface)
164 )164 )
165 decl[side][iface][cstr_b] = bool2str(base_decl[side][iface][cstr_b])165 decl[side][iface][cstr_b] = bool2str(base_decl[side][iface][cstr_b])
166 if isinstance(decl[side][iface][cstr_b], dict):166 if isinstance(decl[side][iface][cstr_b], dict):
diff --git a/bin/dump-tool b/bin/dump-tool
index 1361328..4a9658b 100755
--- a/bin/dump-tool
+++ b/bin/dump-tool
@@ -57,7 +57,7 @@ import textwrap
57import yaml57import yaml
5858
59import reviewtools.common as common59import reviewtools.common as common
60from reviewtools.common import error, warn, msg, debug60from reviewtools import logger
6161
62# TODO:62# TODO:
63# - --file read in one at a time and flush to disk (either --output or63# - --file read in one at a time and flush to disk (either --output or
@@ -72,11 +72,11 @@ def _read_store_dump(input, warn_if_empty=False, progress=False, merge=None):
72 """72 """
7373
74 def _add_entry(db, id, rev, y):74 def _add_entry(db, id, rev, y):
75 debug("adding: id=%s,rev=%s,yaml=\n%s" % (id, rev, y))75 logger.debug("adding: id=%s,rev=%s,yaml=\n%s" % (id, rev, y))
76 try:76 try:
77 snap_yaml = yaml.load(y, Loader=yaml.SafeLoader)77 snap_yaml = yaml.load(y, Loader=yaml.SafeLoader)
78 except Exception as e:78 except Exception as e:
79 warn("Skipping %s|%s: %s" % (cId, cRev, e))79 logger.warning("Skipping %s|%s: %s" % (cId, cRev, e))
80 return80 return
8181
82 # skipping existing entries82 # skipping existing entries
@@ -115,7 +115,7 @@ def _read_store_dump(input, warn_if_empty=False, progress=False, merge=None):
115 (cId, cRev, cYaml) = line.split("|")115 (cId, cRev, cYaml) = line.split("|")
116 if cYaml == "\n": # id|rev|116 if cYaml == "\n": # id|rev|
117 if warn_if_empty and not progress:117 if warn_if_empty and not progress:
118 warn("Skipping %s|%s: empty" % (cId, cRev))118 logger.warning("Skipping %s|%s: empty" % (cId, cRev))
119 cId = None119 cId = None
120 elif cId is not None:120 elif cId is not None:
121 cYaml += "%s" % (line)121 cYaml += "%s" % (line)
@@ -139,7 +139,7 @@ def _write_json_db(db, fn, stdout=False):
139 return139 return
140140
141 if os.path.exists(fn):141 if os.path.exists(fn):
142 error("%s exists. Aborting" % (fn))142 logger.error("%s exists. Aborting" % (fn))
143 with open(fn, "w") as fh:143 with open(fn, "w") as fh:
144 json.dump(db, fh, sort_keys=True, indent=2)144 json.dump(db, fh, sort_keys=True, indent=2)
145 fh.write("\n")145 fh.write("\n")
@@ -183,21 +183,21 @@ def main():
183183
184 # Arg validation184 # Arg validation
185 if not (args.file) and not (args.db_file):185 if not (args.file) and not (args.db_file):
186 error("Must specify either --file or --db-file")186 logger.error("Must specify either --file or --db-file")
187 elif (args.file) and (args.db_file):187 elif (args.file) and (args.db_file):
188 if not os.path.exists(args.file) or not os.path.exists(args.db_file):188 if not os.path.exists(args.file) or not os.path.exists(args.db_file):
189 error("Both --file and --db-file must exist when used together")189 logger.error("Both --file and --db-file must exist when used together")
190 if not args.force_merge:190 if not args.force_merge:
191 ans = input("Merge '%s' into '%s' (y|N)? " % (args.file, args.db_file))191 ans = input("Merge '%s' into '%s' (y|N)? " % (args.file, args.db_file))
192 if ans.strip().lower() not in ["y", "yes"]:192 if ans.strip().lower() not in ["y", "yes"]:
193 msg("Aborting")193 logger.info("Aborting")
194 sys.exit(0)194 sys.exit(0)
195195
196 if args.db_file: # read the existing db196 if args.db_file: # read the existing db
197 try:197 try:
198 db = common.read_file_as_json_dict(args.db_file)198 db = common.read_file_as_json_dict(args.db_file)
199 except json.decoder.JSONDecodeError as e:199 except json.decoder.JSONDecodeError as e:
200 error("Could not read '%s': %s" % (args.db_file, e))200 logger.error("Could not read '%s': %s" % (args.db_file, e))
201201
202 if args.file and args.db_file:202 if args.file and args.db_file:
203 db = _read_store_dump(203 db = _read_store_dump(
diff --git a/bin/rock-check-notices b/bin/rock-check-notices
index e2e0271..2b7303c 100755
--- a/bin/rock-check-notices
+++ b/bin/rock-check-notices
@@ -18,12 +18,11 @@ import argparse
18import json18import json
19import os19import os
20import sys20import sys
21from reviewtools import logger
2122
22import reviewtools.common as common23import reviewtools.common as common
23from reviewtools.common import (24from reviewtools.common import (
24 cmd,25 cmd,
25 debug,
26 warn,
27 fetch_usn_db,26 fetch_usn_db,
28 get_debug_info_from_environment,27 get_debug_info_from_environment,
29 initialize_environment_variables,28 initialize_environment_variables,
@@ -67,10 +66,10 @@ def main():
67 available = "%s/bin/rock-updates-available" % os.path.abspath(66 available = "%s/bin/rock-updates-available" % os.path.abspath(
68 os.environ["SNAP"]67 os.environ["SNAP"]
69 )68 )
70 debug("Running " + available)69 logger.debug("Running " + available)
71 else:70 else:
72 available = "review-tools.rock-updates-available"71 available = "review-tools.rock-updates-available"
73 debug("SNAP not set. Defaulting to 'review-tools.*'")72 logger.debug("SNAP not set. Defaulting to 'review-tools.*'")
7473
75 reports = dict()74 reports = dict()
76 had_debug = get_debug_info_from_environment()75 had_debug = get_debug_info_from_environment()
@@ -78,7 +77,7 @@ def main():
78 for pkg in argv:77 for pkg in argv:
79 valid_rock, warn_msg = is_rock_valid(pkg)78 valid_rock, warn_msg = is_rock_valid(pkg)
80 if not valid_rock:79 if not valid_rock:
81 warn(warn_msg)80 logger.warning(warn_msg)
82 continue81 continue
8382
84 # The expected rock name for this initial implementation is:83 # The expected rock name for this initial implementation is:
@@ -89,7 +88,7 @@ def main():
89 rev = os.path.splitext(os.path.basename(pkg))[0].split("_")[1]88 rev = os.path.splitext(os.path.basename(pkg))[0].split("_")[1]
9089
91 if rock in reports and rev in reports[rock]:90 if rock in reports and rev in reports[rock]:
92 debug("Skipping %s with revision %s" % (rock, rev))91 logger.debug("Skipping %s with revision %s" % (rock, rev))
93 continue92 continue
9493
95 usndb_fn = os.path.join(os.environ["SNAP_USER_COMMON"], usndb)94 usndb_fn = os.path.join(os.environ["SNAP_USER_COMMON"], usndb)
@@ -112,7 +111,7 @@ def main():
112 os.environ["SNAP_DEBUG"] = had_debug111 os.environ["SNAP_DEBUG"] = had_debug
113112
114 if rc != 0:113 if rc != 0:
115 warn(out)114 logger.warning(out)
116 continue115 continue
117116
118 if rock not in reports:117 if rock not in reports:
diff --git a/bin/rock-updates-available b/bin/rock-updates-available
index 77a8c42..a6f12bf 100755
--- a/bin/rock-updates-available
+++ b/bin/rock-updates-available
@@ -44,7 +44,7 @@ import textwrap
44import reviewtools.available as available44import reviewtools.available as available
4545
46import reviewtools.common as common46import reviewtools.common as common
47from reviewtools.common import error47from reviewtools import logger
4848
4949
50def main():50def main():
@@ -80,13 +80,13 @@ def main():
8080
81 # Arg validation81 # Arg validation
82 if args.rock and not args.usn_db:82 if args.rock and not args.usn_db:
83 error("Must specify --usn-db with --rock")83 logger.error("Must specify --usn-db with --rock")
84 elif args.rock and args.store_db:84 elif args.rock and args.store_db:
85 error("Must not specify --store-db with --rock")85 logger.error("Must not specify --store-db with --rock")
86 elif not args.rock and not args.store_db:86 elif not args.rock and not args.store_db:
87 error("Must specify --rock or --store-db")87 logger.error("Must specify --rock or --store-db")
88 elif args.with_cves and not args.rock:88 elif args.with_cves and not args.rock:
89 error("--with-cves should only be used with --rock")89 logger.error("--with-cves should only be used with --rock")
9090
91 ignore_pockets = [pocket.strip() for pocket in args.ignore_pockets.split(",")]91 ignore_pockets = [pocket.strip() for pocket in args.ignore_pockets.split(",")]
9292
@@ -97,7 +97,7 @@ def main():
97 args.usn_db, args.rock, args.with_cves, ignore_pockets97 args.usn_db, args.rock, args.with_cves, ignore_pockets
98 )98 )
99 except ValueError as e:99 except ValueError as e:
100 error(e)100 logger.error(e)
101 elif args.store_db:101 elif args.store_db:
102 (_, errors) = available.scan_store(102 (_, errors) = available.scan_store(
103 args.usn_db,103 args.usn_db,
@@ -108,7 +108,7 @@ def main():
108 ignore_pockets,108 ignore_pockets,
109 )109 )
110 if len(errors):110 if len(errors):
111 error("Errors encountered when scanning store entries")111 logger.error("Errors encountered when scanning store entries")
112112
113 if report != "":113 if report != "":
114 print(report)114 print(report)
diff --git a/bin/snap-check-notices b/bin/snap-check-notices
index e1b16c2..81f2bc0 100755
--- a/bin/snap-check-notices
+++ b/bin/snap-check-notices
@@ -19,11 +19,10 @@ import json
19import os19import os
20import sys20import sys
2121
22from reviewtools import logger
22import reviewtools.common as common23import reviewtools.common as common
23from reviewtools.common import (24from reviewtools.common import (
24 cmd,25 cmd,
25 debug,
26 warn,
27 fetch_usn_db,26 fetch_usn_db,
28 initialize_environment_variables,27 initialize_environment_variables,
29 get_debug_info_from_environment,28 get_debug_info_from_environment,
@@ -66,17 +65,17 @@ def main():
66 available = "%s/bin/snap-updates-available" % os.path.abspath(65 available = "%s/bin/snap-updates-available" % os.path.abspath(
67 os.environ["SNAP"]66 os.environ["SNAP"]
68 )67 )
69 debug("Running " + available)68 logger.debug("Running " + available)
70 else:69 else:
71 available = "review-tools.updates-available"70 available = "review-tools.updates-available"
72 debug("SNAP not set. Defaulting to 'review-tools.*'")71 logger.debug("SNAP not set. Defaulting to 'review-tools.*'")
7372
74 reports = dict()73 reports = dict()
75 had_debug = get_debug_info_from_environment()74 had_debug = get_debug_info_from_environment()
7675
77 for pkg in argv:76 for pkg in argv:
78 if not os.path.isfile(pkg):77 if not os.path.isfile(pkg):
79 warn("Skipping '%s', not a regular file" % pkg)78 logger.warning("Skipping '%s', not a regular file" % pkg)
80 continue79 continue
8180
82 snap = os.path.basename(pkg).split("_")[0]81 snap = os.path.basename(pkg).split("_")[0]
@@ -85,7 +84,7 @@ def main():
85 rev = os.path.splitext(os.path.basename(pkg))[0].split("_")[1]84 rev = os.path.splitext(os.path.basename(pkg))[0].split("_")[1]
8685
87 if snap in reports and rev in reports[snap]:86 if snap in reports and rev in reports[snap]:
88 debug("Skipping %s with revision %s" % (snap, rev))87 logger.debug("Skipping %s with revision %s" % (snap, rev))
89 continue88 continue
9089
91 usndb_fn = os.path.join(os.environ["SNAP_USER_COMMON"], usndb)90 usndb_fn = os.path.join(os.environ["SNAP_USER_COMMON"], usndb)
@@ -111,7 +110,7 @@ def main():
111 os.environ["SNAP_DEBUG"] = had_debug110 os.environ["SNAP_DEBUG"] = had_debug
112111
113 if rc != 0:112 if rc != 0:
114 warn(out)113 logger.warning(out)
115 continue114 continue
116115
117 if snap not in reports:116 if snap not in reports:
diff --git a/bin/snap-review b/bin/snap-review
index 8199929..fa891d9 100755
--- a/bin/snap-review
+++ b/bin/snap-review
@@ -11,9 +11,9 @@ import tempfile
11import textwrap11import textwrap
12import logging12import logging
1313
14from reviewtools import logger
14from reviewtools.common import (15from reviewtools.common import (
15 MKDTEMP_PREFIX,16 MKDTEMP_PREFIX,
16 error,
17 init_override_state_input,17 init_override_state_input,
18 verify_override_state,18 verify_override_state,
19)19)
@@ -72,14 +72,8 @@ def main():
72 parser.add_argument("--state-output", default=None, help="store state output blob")72 parser.add_argument("--state-output", default=None, help="store state output blob")
73 args = parser.parse_args()73 args = parser.parse_args()
7474
75 error_output_type = "console"
76 if args.json or args.sdk:
77 error_output_type = "json"
78
79 if not os.path.exists(args.filename):75 if not os.path.exists(args.filename):
80 error(76 logger.error("file '%s' does not exist." % args.filename)
81 "file '%s' does not exist." % args.filename, output_type=error_output_type
82 )
8377
84 modules = modules_mod.get_modules()78 modules = modules_mod.get_modules()
85 if not modules:79 if not modules:
@@ -93,14 +87,14 @@ def main():
93 overrides["snap_decl_plugs"] = json.loads(plugs_file.read())87 overrides["snap_decl_plugs"] = json.loads(plugs_file.read())
94 validate_json(overrides["snap_decl_plugs"])88 validate_json(overrides["snap_decl_plugs"])
95 except Exception as e:89 except Exception as e:
96 error("Failed to read plugs: %s" % e, output_type=error_output_type)90 logger.error("Failed to read plugs: %s" % e)
97 if args.slots:91 if args.slots:
98 try:92 try:
99 with open(args.slots, "r") as slots_file:93 with open(args.slots, "r") as slots_file:
100 overrides["snap_decl_slots"] = json.loads(slots_file.read())94 overrides["snap_decl_slots"] = json.loads(slots_file.read())
101 validate_json(overrides["snap_decl_slots"])95 validate_json(overrides["snap_decl_slots"])
102 except Exception as e:96 except Exception as e:
103 error("Failed to read slots: %s" % e, output_type=error_output_type)97 logger.error("Failed to read slots: %s" % e)
104 if args.allow_classic:98 if args.allow_classic:
105 overrides["snap_allow_classic"] = args.allow_classic99 overrides["snap_allow_classic"] = args.allow_classic
106 if args.allow_gadget:100 if args.allow_gadget:
@@ -112,27 +106,23 @@ def main():
112106
113 # --state-input alone is unsupported107 # --state-input alone is unsupported
114 if args.state_input and not args.state_output:108 if args.state_input and not args.state_output:
115 error(109 logger.error(
116 "Must specify --state-output with --state-input",110 "Must specify --state-output with --state-input",
117 output_type=error_output_type,
118 )111 )
119112
120 if args.state_output:113 if args.state_output:
121 if args.state_input:114 if args.state_input:
122 # --state-input --state-output indicates we have previous state115 # --state-input --state-output indicates we have previous state
123 if not os.path.exists(args.state_input):116 if not os.path.exists(args.state_input):
124 error(117 logger.error(
125 "file '%s' does not exist." % args.state_input,118 "file '%s' does not exist." % args.state_input,
126 output_type=error_output_type,
127 )119 )
128 try:120 try:
129 with open(args.state_input, "rb") as in_f:121 with open(args.state_input, "rb") as in_f:
130 st = in_f.read().decode("utf-8")122 st = in_f.read().decode("utf-8")
131 overrides["state_input"] = json.loads(st)123 overrides["state_input"] = json.loads(st)
132 except Exception as e:124 except Exception as e:
133 error(125 logger.error("Could not read state input: %s" % e)
134 "Could not read state input: %s" % e, output_type=error_output_type
135 )
136 else:126 else:
137 # --state-output alone indicates we are bootstrapping127 # --state-output alone indicates we are bootstrapping
138 overrides["state_input"] = init_override_state_input()128 overrides["state_input"] = init_override_state_input()
@@ -141,7 +131,7 @@ def main():
141 try:131 try:
142 verify_override_state(overrides["state_input"])132 verify_override_state(overrides["state_input"])
143 except Exception as e:133 except Exception as e:
144 error("state-input failed to verify: %s" % e, output_type=error_output_type)134 logger.error("state-input failed to verify: %s" % e)
145135
146 overrides["state_output"] = copy.deepcopy(overrides["state_input"])136 overrides["state_output"] = copy.deepcopy(overrides["state_input"])
147137
diff --git a/bin/snap-updates-available b/bin/snap-updates-available
index 4db68f9..98e888a 100755
--- a/bin/snap-updates-available
+++ b/bin/snap-updates-available
@@ -45,7 +45,7 @@ import textwrap
45import reviewtools.available as available45import reviewtools.available as available
4646
47import reviewtools.common as common47import reviewtools.common as common
48from reviewtools.common import error48from reviewtools import logger
4949
5050
51def main():51def main():
@@ -86,19 +86,19 @@ def main():
8686
87 # Arg validation87 # Arg validation
88 if args.check_shared_publishers and args.snap:88 if args.check_shared_publishers and args.snap:
89 error("--snap should not be used with --check-shared-publishers")89 logger.error("--snap should not be used with --check-shared-publishers")
90 elif args.check_shared_publishers and args.usn_db:90 elif args.check_shared_publishers and args.usn_db:
91 error("--usn-db should not be used with --check-shared-publishers")91 logger.error("--usn-db should not be used with --check-shared-publishers")
92 elif args.check_shared_publishers and not args.store_db:92 elif args.check_shared_publishers and not args.store_db:
93 error("Must specify --store-db with --check-shared-publishers")93 logger.error("Must specify --store-db with --check-shared-publishers")
94 elif args.snap and not args.usn_db:94 elif args.snap and not args.usn_db:
95 error("Must specify --usn-db with --snap")95 logger.error("Must specify --usn-db with --snap")
96 elif args.snap and args.store_db:96 elif args.snap and args.store_db:
97 error("Must not specify --store-db with --snap")97 logger.error("Must not specify --store-db with --snap")
98 elif not args.snap and not args.store_db:98 elif not args.snap and not args.store_db:
99 error("Must specify --snap or --store-db")99 logger.error("Must specify --snap or --store-db")
100 elif args.with_cves and not args.snap:100 elif args.with_cves and not args.snap:
101 error("--with-cves should only be used with --snap")101 logger.error("--with-cves should only be used with --snap")
102102
103 ignore_pockets = [pocket.strip() for pocket in args.ignore_pockets.split(",")]103 ignore_pockets = [pocket.strip() for pocket in args.ignore_pockets.split(",")]
104104
@@ -111,7 +111,7 @@ def main():
111 args.usn_db, args.snap, args.with_cves, ignore_pockets111 args.usn_db, args.snap, args.with_cves, ignore_pockets
112 )112 )
113 except ValueError as e:113 except ValueError as e:
114 error(e)114 logger.error(e)
115 elif args.store_db:115 elif args.store_db:
116 (_, errors) = available.scan_store(116 (_, errors) = available.scan_store(
117 args.usn_db,117 args.usn_db,
@@ -122,7 +122,7 @@ def main():
122 ignore_pockets,122 ignore_pockets,
123 )123 )
124 if len(errors):124 if len(errors):
125 error("Errors encountered when scanning store entries")125 logger.error("Errors encountered when scanning store entries")
126126
127 if report != "":127 if report != "":
128 print(report)128 print(report)
diff --git a/bin/snap-verify-declaration b/bin/snap-verify-declaration
index 7d7ee40..cb97a90 100755
--- a/bin/snap-verify-declaration
+++ b/bin/snap-verify-declaration
@@ -22,7 +22,7 @@ import json
22import sys22import sys
23import textwrap23import textwrap
2424
25from reviewtools.common import error25from reviewtools import logger
26import reviewtools.sr_declaration as sr_declaration26import reviewtools.sr_declaration as sr_declaration
2727
2828
@@ -50,12 +50,12 @@ def main():
50 )50 )
51 args = parser.parse_args()51 args = parser.parse_args()
5252
53 error_output_type = "console"53 output_type = "console"
54 if args.json:54 if args.json:
55 error_output_type = "json"55 output_type = "json"
5656
57 if not args.plugs and not args.slots:57 if not args.plugs and not args.slots:
58 error("Must specify --plugs and/or --slots", output_type=error_output_type)58 logger.error("Must specify --plugs and/or --slots")
5959
60 # Read in the snap declaration60 # Read in the snap declaration
61 snap_decl = {"plugs": {}, "slots": {}}61 snap_decl = {"plugs": {}, "slots": {}}
@@ -65,25 +65,22 @@ def main():
65 snap_decl["plugs"] = json.loads(plugs_file.read())65 snap_decl["plugs"] = json.loads(plugs_file.read())
66 sr_declaration.validate_json(snap_decl["plugs"])66 sr_declaration.validate_json(snap_decl["plugs"])
67 except Exception as e:67 except Exception as e:
68 error("Failed to read plugs: %s" % e, output_type=error_output_type)68 logger.error("Failed to read plugs: %s" % e)
69 if args.slots:69 if args.slots:
70 try:70 try:
71 with open(args.slots, "r") as slots_file:71 with open(args.slots, "r") as slots_file:
72 snap_decl["slots"] = json.loads(slots_file.read())72 snap_decl["slots"] = json.loads(slots_file.read())
73 sr_declaration.validate_json(snap_decl["slots"])73 sr_declaration.validate_json(snap_decl["slots"])
74 except Exception as e:74 except Exception as e:
75 error("Failed to read slots: %s" % e, output_type=error_output_type)75 logger.error("Failed to read slots: %s" % e)
7676
77 try:77 try:
78 review = sr_declaration.verify_snap_declaration(snap_decl)78 review = sr_declaration.verify_snap_declaration(snap_decl)
79 except Exception as e:79 except Exception as e:
80 error(80 logger.error("verify_snap_declaration() raised exception for snap decl: %s" % e)
81 "verify_snap_declaration() raised exception for snap decl: %s" % e,
82 output_type=error_output_type,
83 )
8481
85 report = review.review_report82 report = review.review_report
86 report.show_summary(error_output_type)83 report.show_summary(output_type)
8784
88 rc = 085 rc = 0
89 if report.errors:86 if report.errors:
diff --git a/bin/store-query b/bin/store-query
index e6b22b8..420e81f 100755
--- a/bin/store-query
+++ b/bin/store-query
@@ -35,7 +35,7 @@ import requests
35import yaml35import yaml
3636
37import reviewtools.common as common37import reviewtools.common as common
38from reviewtools.common import debug, error38from reviewtools import logger
3939
40from reviewtools.sr_common import SnapReview40from reviewtools.sr_common import SnapReview
4141
@@ -140,10 +140,10 @@ def _fetch(url, headers=None):
140140
141 h = str(headers)141 h = str(headers)
142 if url in responses and h in responses[url]:142 if url in responses and h in responses[url]:
143 debug("Cache: %s, headers=%s" % (url, headers))143 logger.debug("Cache: %s, headers=%s" % (url, headers))
144 return responses[url][h]144 return responses[url][h]
145145
146 debug("Fetch: %s, headers=%s" % (url, headers))146 logger.debug("Fetch: %s, headers=%s" % (url, headers))
147 if headers is None:147 if headers is None:
148 r = requests.get(url)148 r = requests.get(url)
149 else:149 else:
@@ -152,7 +152,7 @@ def _fetch(url, headers=None):
152 if r.status_code != 200:152 if r.status_code != 200:
153 raise Exception("Status code: %s (%s)" % (r.status_code, r.headers))153 raise Exception("Status code: %s (%s)" % (r.status_code, r.headers))
154154
155 debug("Response headers=%s" % r.headers)155 logger.debug("Response headers=%s" % r.headers)
156156
157 if url not in responses:157 if url not in responses:
158 responses[url] = {}158 responses[url] = {}
@@ -264,7 +264,7 @@ def _get_snap_yaml(snap_name, channel=None, arch=None):
264 ):264 ):
265 return yaml.load(item["snap-yaml"], Loader=yaml.SafeLoader)265 return yaml.load(item["snap-yaml"], Loader=yaml.SafeLoader)
266266
267 debug(format_resp(res, output_json=True))267 logger.debug(format_resp(res, output_json=True))
268 raise Exception(268 raise Exception(
269 "Could not find snap-yaml for (channel=%s, arch=%s)" % (channel, arch)269 "Could not find snap-yaml for (channel=%s, arch=%s)" % (channel, arch)
270 )270 )
@@ -360,10 +360,12 @@ def main():
360 args = parser.parse_args()360 args = parser.parse_args()
361361
362 if args.name_or_id is None and args.snap_id is None:362 if args.name_or_id is None and args.snap_id is None:
363 error("Must specify a snap name or snap id. Aborting")363 logger.error("Must specify a snap name or snap id. Aborting")
364364
365 if not args.snap_decl and not args.snap_info and not args.snap_yaml:365 if not args.snap_decl and not args.snap_info and not args.snap_yaml:
366 error("Must specify one of --snap-decl, --snap-info or --snap-yaml. Aborting")366 logger.error(
367 "Must specify one of --snap-decl, --snap-info or --snap-yaml. Aborting"
368 )
367369
368 # Note snap names are lower case, with numbers and '-' but snap ids are370 # Note snap names are lower case, with numbers and '-' but snap ids are
369 # alphanumerics of exactly 32. While possible that a snap-id and a name371 # alphanumerics of exactly 32. While possible that a snap-id and a name
@@ -398,7 +400,7 @@ def main():
398 if mf < 0:400 if mf < 0:
399 raise ValueError401 raise ValueError
400 except ValueError:402 except ValueError:
401 error("--max-format should be 'all' or integer >= 0")403 logger.error("--max-format should be 'all' or integer >= 0")
402404
403 if args.max_format == "all":405 if args.max_format == "all":
404 snap_decl = _get_all_snap_declarations_by_id(snap_id)406 snap_decl = _get_all_snap_declarations_by_id(snap_id)
@@ -416,4 +418,4 @@ if __name__ == "__main__":
416 try:418 try:
417 main()419 main()
418 except KeyboardInterrupt:420 except KeyboardInterrupt:
419 error("Aborted.")421 logger.error("Aborted.")
diff --git a/reviewtools/__init__.py b/reviewtools/__init__.py
index e69de29..4ce6539 100644
--- a/reviewtools/__init__.py
+++ b/reviewtools/__init__.py
@@ -0,0 +1,16 @@
1import logging
2
3
4class ShutdownHandler(logging.StreamHandler):
5 def emit(self, record):
6 super().emit(record)
7 if record.levelno >= logging.ERROR:
8 exit(1)
9
10
11logger = logging.getLogger(__name__)
12
13handler = ShutdownHandler()
14myFormatter = logging.Formatter("%(levelname)s: %(message)s")
15handler.setFormatter(myFormatter)
16logger.addHandler(handler)
diff --git a/reviewtools/available.py b/reviewtools/available.py
index 5b0dd3c..94bfbe1 100755
--- a/reviewtools/available.py
+++ b/reviewtools/available.py
@@ -18,10 +18,8 @@ import os
18import shutil18import shutil
19import tempfile19import tempfile
2020
21from reviewtools import logger
21from reviewtools.common import (22from reviewtools.common import (
22 error,
23 debug,
24 warn,
25 open_file_write,23 open_file_write,
26 read_file_as_json_dict,24 read_file_as_json_dict,
27 MKDTEMP_PREFIX,25 MKDTEMP_PREFIX,
@@ -356,7 +354,7 @@ def _email_report_for_pkg(pkg_db, seen_db):
356354
357 email.send(email_to_addr, subj, body, bcc)355 email.send(email_to_addr, subj, body, bcc)
358356
359 debug("Sent email for '%s'" % pkgname)357 logger.debug("Sent email for '%s'" % pkgname)
360 return (email_to_addr, subj, body)358 return (email_to_addr, subj, body)
361359
362360
@@ -469,7 +467,7 @@ def scan_store(
469 continue467 continue
470468
471 if body is None: # pragma: nocover469 if body is None: # pragma: nocover
472 debug("Skipped email for '%s': up to date" % pkg_db["name"])470 logger.debug("Skipped email for '%s': up to date" % pkg_db["name"])
473471
474 if seen_db_fn:472 if seen_db_fn:
475 _update_seen(seen_db_fn, seen_db, pkg_db)473 _update_seen(seen_db_fn, seen_db, pkg_db)
@@ -477,7 +475,7 @@ def scan_store(
477 if len(errors) > 0:475 if len(errors) > 0:
478 for p in errors:476 for p in errors:
479 for e in errors[p]:477 for e in errors[p]:
480 warn("%s: %s" % (p, e))478 logger.warning("%s: %s" % (p, e))
481479
482 return sent, errors480 return sent, errors
483481
@@ -489,7 +487,7 @@ def scan_snap(secnot_db_fn, snap_fn, with_cves=False, ignore_pockets=list()):
489 snap = SnapContainer(snap_fn)487 snap = SnapContainer(snap_fn)
490 (man, dpkg) = snap.get_snap_manifest()488 (man, dpkg) = snap.get_snap_manifest()
491 except ContainerException as e:489 except ContainerException as e:
492 error(str(e))490 logger.error(str(e))
493 man = get_faked_build_and_stage_packages(man)491 man = get_faked_build_and_stage_packages(man)
494492
495 # Use dpkg.list when the snap ships it in a spot we honor. This is limited493 # Use dpkg.list when the snap ships it in a spot we honor. This is limited
diff --git a/reviewtools/common.py b/reviewtools/common.py
index eaaadee..2b8472e 100644
--- a/reviewtools/common.py
+++ b/reviewtools/common.py
@@ -20,6 +20,7 @@ import copy
20from enum import Enum20from enum import Enum
21import inspect21import inspect
22import json22import json
23from reviewtools import logger
23import os24import os
24from pkg_resources import resource_filename25from pkg_resources import resource_filename
25import re26import re
@@ -229,51 +230,9 @@ class ReviewBase(object):
229#230#
230231
231232
232def error(out, exit_code=1, do_exit=True, output_type=None):
233 """Print error message and exit"""
234 global REPORT_OUTPUT
235 if output_type is None:
236 output_type = REPORT_OUTPUT
237
238 if output_type == "json":
239 report = Report()
240 report.add_result("runtime-errors", "error", "msg", out, manual_review=True)
241 report.show_results(output_type)
242 else:
243 print("ERROR: %s" % (out), file=sys.stderr)
244
245 if do_exit:
246 sys.exit(exit_code)
247
248
249def warn(out):
250 """Print warning message"""
251 try:
252 print("WARN: %s" % (out), file=sys.stderr)
253 except IOError:
254 pass
255
256
257def msg(out, output=sys.stdout):
258 """Print message"""
259 try:
260 print("%s" % (out), file=output)
261 except IOError:
262 pass
263
264
265def debug(out):
266 """Print debug message"""
267 if "SNAP_DEBUG" in os.environ:
268 try:
269 print("DEBUG: %s" % (out), file=sys.stderr)
270 except IOError:
271 pass
272
273
274def cmd(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT):233def cmd(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT):
275 """Try to execute the given command."""234 """Try to execute the given command."""
276 debug(" ".join(command))235 logger.debug(" ".join(command))
277 try:236 try:
278 sp = subprocess.Popen(command, stdout=stdout, stderr=stderr)237 sp = subprocess.Popen(command, stdout=stdout, stderr=stderr)
279 except OSError as ex:238 except OSError as ex:
@@ -595,14 +554,14 @@ def _unpack_rock_tar(rock_pkg, dest):
595 # https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall554 # https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall
596 for name in tar.getnames():555 for name in tar.getnames():
597 if name.startswith("..") or name.startswith("/"):556 if name.startswith("..") or name.startswith("/"):
598 error(557 logger.error(
599 "Bad path %s while extracting archive at %s"558 "Bad path %s while extracting archive at %s"
600 % (name, rock_pkg)559 % (name, rock_pkg)
601 )560 )
602561
603 tar.extractall(path=d)562 tar.extractall(path=d)
604 except Exception as e:563 except Exception as e:
605 error("Unexpected exception while unpacking rock %s" % e)564 logger.error("Unexpected exception while unpacking rock %s" % e)
606 if os.path.isdir(d):565 if os.path.isdir(d):
607 recursive_rm(d)566 recursive_rm(d)
608567
@@ -615,17 +574,17 @@ def _unpack_rock_tar(rock_pkg, dest):
615574
616 return dest575 return dest
617 else:576 else:
618 error(error_msg)577 logger.error(error_msg)
619578
620579
621def check_dir(dest):580def check_dir(dest):
622 if dest is not None and os.path.exists(dest):581 if dest is not None and os.path.exists(dest):
623 error("'%s' exists. Aborting." % dest)582 logger.error("'%s' exists. Aborting." % dest)
624583
625584
626def check_fn(fn):585def check_fn(fn):
627 if not os.path.isfile(fn):586 if not os.path.isfile(fn):
628 error("Could not find '%s'" % fn)587 logger.error("Could not find '%s'" % fn)
629 pkg = fn588 pkg = fn
630 if not pkg.startswith("/"):589 if not pkg.startswith("/"):
631 pkg = os.path.abspath(pkg)590 pkg = os.path.abspath(pkg)
@@ -636,7 +595,7 @@ def check_max_pkg_size(pkg):
636 size = os.stat(pkg)[stat.ST_SIZE]595 size = os.stat(pkg)[stat.ST_SIZE]
637 max = MAX_COMPRESSED_SIZE * 1024 * 1024 * 1024596 max = MAX_COMPRESSED_SIZE * 1024 * 1024 * 1024
638 if size > max:597 if size > max:
639 error(598 logger.error(
640 "compressed file is too large (%dM > %dM)"599 "compressed file is too large (%dM > %dM)"
641 % (size / 1024 / 1024, max / 1024 / 1024)600 % (size / 1024 / 1024, max / 1024 / 1024)
642 )601 )
@@ -654,7 +613,7 @@ def unpack_rock(fn, dest=None):
654 if tarfile.is_tarfile(pkg):613 if tarfile.is_tarfile(pkg):
655 return _unpack_rock_tar(fn, dest)614 return _unpack_rock_tar(fn, dest)
656615
657 error("Unsupported package format (not tar)")616 logger.error("Unsupported package format (not tar)")
658617
659618
660def open_file_read(path):619def open_file_read(path):
@@ -895,7 +854,7 @@ def check_results(
895def read_file_as_json_dict(fn):854def read_file_as_json_dict(fn):
896 """Read in filename as json dict"""855 """Read in filename as json dict"""
897 # XXX: consider reading in as stream856 # XXX: consider reading in as stream
898 debug("Loading: %s" % fn)857 logger.debug("Loading: %s" % fn)
899 raw = {}858 raw = {}
900 with open_file_read(fn) as fd:859 with open_file_read(fn) as fd:
901 try:860 try:
@@ -965,7 +924,7 @@ def build_manifest_from_rock_tar(man_fn, unpack_tmp_dir):
965924
966 if not dpkg_query:925 if not dpkg_query:
967 recursive_rm(unpack_tmp_dir)926 recursive_rm(unpack_tmp_dir)
968 error("%s not in %s" % (man_fn, unpack_tmp_dir))927 logger.error("%s not in %s" % (man_fn, unpack_tmp_dir))
969928
970 return build_man_from_dpkg_query_file_content(dpkg_query)929 return build_man_from_dpkg_query_file_content(dpkg_query)
971930
@@ -1037,7 +996,7 @@ def extract_dpkg_query_file_from_rock(dpkg_query, unpack_tmp_dir):
1037 if dpkg_query:996 if dpkg_query:
1038 return dpkg_query997 return dpkg_query
1039 except Exception as e:998 except Exception as e:
1040 error("Could not extract manifest %s" % e)999 logger.error("Could not extract manifest %s" % e)
1041 recursive_rm(unpack_tmp_dir)1000 recursive_rm(unpack_tmp_dir)
10421001
1043 return dpkg_query1002 return dpkg_query
@@ -1061,7 +1020,7 @@ def read_snapd_base_declaration():
1061 if not os.path.exists(bd_fn):1020 if not os.path.exists(bd_fn):
1062 bd_fn = resource_filename(__name__, "data/snapd-base-declaration.yaml")1021 bd_fn = resource_filename(__name__, "data/snapd-base-declaration.yaml")
1063 if not os.path.exists(bd_fn):1022 if not os.path.exists(bd_fn):
1064 error("could not find '%s'" % bd_fn)1023 logger.error("could not find '%s'" % bd_fn)
1065 fd = open_file_read(bd_fn)1024 fd = open_file_read(bd_fn)
1066 contents = fd.read()1025 contents = fd.read()
1067 fd.close()1026 fd.close()
@@ -1128,12 +1087,12 @@ def initialize_environment_variables():
1128 os.environ["SNAP_USER_COMMON"] = (1087 os.environ["SNAP_USER_COMMON"] = (
1129 "%s/snap/review-tools/common" % os.environ["HOME"]1088 "%s/snap/review-tools/common" % os.environ["HOME"]
1130 )1089 )
1131 debug(1090 logger.debug(
1132 "SNAP_USER_COMMON not set. Defaulting to %s"1091 "SNAP_USER_COMMON not set. Defaulting to %s"
1133 % os.environ["SNAP_USER_COMMON"]1092 % os.environ["SNAP_USER_COMMON"]
1134 )1093 )
1135 if not os.path.exists(os.environ["SNAP_USER_COMMON"]):1094 if not os.path.exists(os.environ["SNAP_USER_COMMON"]):
1136 error(1095 logger.error(
1137 "SNAP_USER_COMMON not set and %s does not exist"1096 "SNAP_USER_COMMON not set and %s does not exist"
1138 % os.environ["SNAP_USER_COMMON"]1097 % os.environ["SNAP_USER_COMMON"]
1139 )1098 )
@@ -1162,9 +1121,9 @@ def fetch_usn_db(args):
1162 ):1121 ):
1163 rc, out = cmd([fetchdb, "%s.bz2" % usndb])1122 rc, out = cmd([fetchdb, "%s.bz2" % usndb])
1164 if rc != 0:1123 if rc != 0:
1165 error(out)1124 logger.error(out)
1166 else:1125 else:
1167 debug("Reusing %s" % usndb)1126 logger.debug("Reusing %s" % usndb)
1168 os.chdir(curdir)1127 os.chdir(curdir)
1169 return usndb1128 return usndb
11701129
diff --git a/reviewtools/sr_declaration.py b/reviewtools/sr_declaration.py
index edfe023..e4df23b 100644
--- a/reviewtools/sr_declaration.py
+++ b/reviewtools/sr_declaration.py
@@ -15,8 +15,9 @@
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17from __future__ import print_function17from __future__ import print_function
18from reviewtools import logger
18from reviewtools.sr_common import SnapReview, SnapReviewException19from reviewtools.sr_common import SnapReview, SnapReviewException
19from reviewtools.common import error, ReviewBase, read_snapd_base_declaration20from reviewtools.common import ReviewBase, read_snapd_base_declaration
20from reviewtools.overrides import sec_iface_ref_overrides21from reviewtools.overrides import sec_iface_ref_overrides
21from reviewtools.schemas.schema_validator import load_schema22from reviewtools.schemas.schema_validator import load_schema
22import copy23import copy
@@ -1521,7 +1522,7 @@ def verify_snap_declaration(snap_decl, base_decl=None):
1521 try:1522 try:
1522 SnapReviewDeclaration._verify_declaration(review, base_decl, base=True)1523 SnapReviewDeclaration._verify_declaration(review, base_decl, base=True)
1523 except Exception as e: # pragma: nocover1524 except Exception as e: # pragma: nocover
1524 error("_verify_declaration() raised exception for base decl: %s" % e)1525 logger.error("_verify_declaration() raised exception for base decl: %s" % e)
15251526
1526 # First make sure that the interfaces in the snap declaration are known to1527 # First make sure that the interfaces in the snap declaration are known to
1527 # the base declaration1528 # the base declaration
@@ -1543,6 +1544,6 @@ def verify_snap_declaration(snap_decl, base_decl=None):
1543 try:1544 try:
1544 SnapReviewDeclaration._verify_declaration(review, snap_decl, base=False)1545 SnapReviewDeclaration._verify_declaration(review, snap_decl, base=False)
1545 except Exception as e: # pragma: nocover1546 except Exception as e: # pragma: nocover
1546 error("_verify_declaration() raised exception for snap decl: %s" % e)1547 logger.error("_verify_declaration() raised exception for snap decl: %s" % e)
15471548
1548 return review1549 return review
diff --git a/reviewtools/store.py b/reviewtools/store.py
index e84cd00..2d0a3ac 100644
--- a/reviewtools/store.py
+++ b/reviewtools/store.py
@@ -19,9 +19,8 @@ import yaml
1919
20import reviewtools.debversion as debversion20import reviewtools.debversion as debversion
2121
22from reviewtools import logger
22from reviewtools.common import (23from reviewtools.common import (
23 debug,
24 warn,
25 get_os_codename,24 get_os_codename,
26 assign_type_to_dict_values,25 assign_type_to_dict_values,
27 _add_error, # make a class26 _add_error, # make a class
@@ -233,7 +232,7 @@ def get_pkg_revisions(item, secnot_db, errors, pkg_type="snap", ignore_pockets=l
233 continue232 continue
234233
235 r = str(rev["revision"]) # ensure yaml and json agree on type234 r = str(rev["revision"]) # ensure yaml and json agree on type
236 debug("Checking %s r%s" % (item["name"], r))235 logger.debug("Checking %s r%s" % (item["name"], r))
237236
238 if "manifest_yaml" not in rev:237 if "manifest_yaml" not in rev:
239 _add_error(238 _add_error(
@@ -359,11 +358,11 @@ def get_staged_and_build_packages_from_manifest(m):
359 If not, obtain it from stage-packages for various parts instead358 If not, obtain it from stage-packages for various parts instead
360 """359 """
361 if "parts" not in m:360 if "parts" not in m:
362 debug("Could not find 'parts' in manifest")361 logger.debug("Could not find 'parts' in manifest")
363 return None362 return None
364363
365 if not m["parts"]:364 if not m["parts"]:
366 debug("'parts' exists in manifest but it is empty")365 logger.debug("'parts' exists in manifest but it is empty")
367 return None366 return None
368367
369 d = {}368 d = {}
@@ -407,18 +406,18 @@ def get_staged_and_build_packages_from_manifest(m):
407 if len(d) == 0:406 if len(d) == 0:
408 return None407 return None
409408
410 debug("\n" + pprint.pformat(d))409 logger.debug("\n" + pprint.pformat(d))
411 return d410 return d
412411
413412
414def get_staged_packages_from_rock_manifest(m):413def get_staged_packages_from_rock_manifest(m):
415 """Obtain list of packages in stage-packages if section is present."""414 """Obtain list of packages in stage-packages if section is present."""
416 if "stage-packages" not in m:415 if "stage-packages" not in m:
417 debug("Could not find 'stage-packages' in manifest")416 logger.debug("Could not find 'stage-packages' in manifest")
418 return None417 return None
419418
420 if not m["stage-packages"]:419 if not m["stage-packages"]:
421 debug("'stage-packages' exists in manifest but it is empty")420 logger.debug("'stage-packages' exists in manifest but it is empty")
422 return None421 return None
423422
424 d = {}423 d = {}
@@ -426,7 +425,7 @@ def get_staged_packages_from_rock_manifest(m):
426 if len(d) == 0:425 if len(d) == 0:
427 return None426 return None
428427
429 debug("\n" + pprint.pformat(d))428 logger.debug("\n" + pprint.pformat(d))
430 return d429 return d
431430
432431
@@ -440,11 +439,11 @@ def get_packages_from_manifest_section(d, manifest_section, package_type):
440 """439 """
441 for entry in manifest_section:440 for entry in manifest_section:
442 if "=" not in entry:441 if "=" not in entry:
443 warn("'%s' not properly formatted. Skipping" % entry)442 logger.warning("'%s' not properly formatted. Skipping" % entry)
444 continue443 continue
445 pkg, ver = entry.split("=")444 pkg, ver = entry.split("=")
446 if pkg in update_binaries_ignore:445 if pkg in update_binaries_ignore:
447 debug("Skipping ignored binary: '%s'" % pkg)446 logger.debug("Skipping ignored binary: '%s'" % pkg)
448 continue447 continue
449 if package_type not in d:448 if package_type not in d:
450 d[package_type] = {}449 d[package_type] = {}
@@ -467,7 +466,7 @@ def get_packages_from_rock_manifest_section(d, manifest_section, package_type):
467 # rock manifest v1 stage-packages section is a list of466 # rock manifest v1 stage-packages section is a list of
468 # "<binpkg1>=<version>,<srcpkg1>=<src version>"467 # "<binpkg1>=<version>,<srcpkg1>=<src version>"
469 if "=" not in entry or "," not in entry:468 if "=" not in entry or "," not in entry:
470 warn("'%s' not properly formatted. Skipping" % entry)469 logger.warning("'%s' not properly formatted. Skipping" % entry)
471 continue470 continue
472 pkg_info = entry.split(",")471 pkg_info = entry.split(",")
473 if len(pkg_info) == 2:472 if len(pkg_info) == 2:
@@ -485,7 +484,7 @@ def get_packages_from_rock_manifest_section(d, manifest_section, package_type):
485 binary_pkg_name = arch_qualifier_parts[0]484 binary_pkg_name = arch_qualifier_parts[0]
486 ver = binary_pkg[1]485 ver = binary_pkg[1]
487 if binary_pkg_name in update_binaries_ignore:486 if binary_pkg_name in update_binaries_ignore:
488 debug("Skipping ignored binary: '%s'" % binary_pkg_name)487 logger.debug("Skipping ignored binary: '%s'" % binary_pkg_name)
489 continue488 continue
490 if package_type not in d:489 if package_type not in d:
491 d[package_type] = {}490 d[package_type] = {}
@@ -494,10 +493,10 @@ def get_packages_from_rock_manifest_section(d, manifest_section, package_type):
494 if ver not in d[package_type][binary_pkg_name]:493 if ver not in d[package_type][binary_pkg_name]:
495 d[package_type][binary_pkg_name].append(ver)494 d[package_type][binary_pkg_name].append(ver)
496 else:495 else:
497 warn("'%s' not properly formatted. Skipping" % pkg_info)496 logger.warning("'%s' not properly formatted. Skipping" % pkg_info)
498 continue497 continue
499 else:498 else:
500 warn("'%s' not properly formatted. Skipping" % pkg_info)499 logger.warning("'%s' not properly formatted. Skipping" % pkg_info)
501 continue500 continue
502501
503502
@@ -544,7 +543,7 @@ def get_secnots_for_manifest(
544 ignore_pockets=list(),543 ignore_pockets=list(),
545):544):
546 """Find new security notifications for packages in the manifest"""545 """Find new security notifications for packages in the manifest"""
547 debug(manifest_type + "/manifest.yaml:\n" + pprint.pformat(manifest))546 logger.debug(manifest_type + "/manifest.yaml:\n" + pprint.pformat(manifest))
548 stage_and_build_pkgs = None547 stage_and_build_pkgs = None
549 rel = get_ubuntu_release_from_manifest(548 rel = get_ubuntu_release_from_manifest(
550 manifest, manifest_type549 manifest, manifest_type
@@ -561,7 +560,7 @@ def get_secnots_for_manifest(
561560
562 pending_secnots = {}561 pending_secnots = {}
563 if stage_and_build_pkgs is None:562 if stage_and_build_pkgs is None:
564 debug("no stage-packages found")563 logger.debug("no stage-packages found")
565 return pending_secnots564 return pending_secnots
566 # Since stage_and_build_pkgs can have stage-packages and build-packages565 # Since stage_and_build_pkgs can have stage-packages and build-packages
567 # keys, adding secnots into each group566 # keys, adding secnots into each group
@@ -594,7 +593,7 @@ def get_secnots_for_manifest(
594 if key in manifest["parts"][part]:593 if key in manifest["parts"][part]:
595 for entry in manifest["parts"][part][key]:594 for entry in manifest["parts"][part][key]:
596 if "=" not in entry:595 if "=" not in entry:
597 warn(596 logger.warning(
598 "'%s' not properly "597 "'%s' not properly "
599 "formatted. Skipping" % entry598 "formatted. Skipping" % entry
600 )599 )
@@ -616,7 +615,7 @@ def get_secnots_for_manifest(
616 secnotversion = secnot_db[rel][pkg][secnot]["version"]615 secnotversion = secnot_db[rel][pkg][secnot]["version"]
617616
618 if debversion.compare(pkgversion, secnotversion) < 0:617 if debversion.compare(pkgversion, secnotversion) < 0:
619 debug(618 logger.debug(
620 "adding %s: %s (pkg:%s < secnot:%s)"619 "adding %s: %s (pkg:%s < secnot:%s)"
621 % (620 % (
622 pkg,621 pkg,
@@ -641,7 +640,7 @@ def get_secnots_for_manifest(
641 else:640 else:
642 pending_secnots[pkg_type][pkg].append(secnot)641 pending_secnots[pkg_type][pkg].append(secnot)
643 else:642 else:
644 debug(643 logger.debug(
645 "skipping %s: %s (pkg:%s >= secnot:%s)"644 "skipping %s: %s (pkg:%s >= secnot:%s)"
646 % (645 % (
647 pkg,646 pkg,
@@ -675,7 +674,7 @@ def get_ubuntu_release_from_manifest_snap(m):
675 if "installed-snaps" in m["parts"][part]:674 if "installed-snaps" in m["parts"][part]:
676 for entry in m["parts"][part]["installed-snaps"]:675 for entry in m["parts"][part]["installed-snaps"]:
677 if "=" not in entry:676 if "=" not in entry:
678 warn("'%s' not properly formatted. Skipping" % entry)677 logger.warning("'%s' not properly formatted. Skipping" % entry)
679 continue678 continue
680 pkg = entry.split("=")[0] # we don't care about the version679 pkg = entry.split("=")[0] # we don't care about the version
681680
@@ -689,7 +688,7 @@ def get_ubuntu_release_from_manifest_snap(m):
689 ubuntu_release = get_os_codename(688 ubuntu_release = get_os_codename(
690 m["snapcraft-os-release-id"], m["snapcraft-os-release-version-id"]689 m["snapcraft-os-release-id"], m["snapcraft-os-release-version-id"]
691 )690 )
692 debug("Ubuntu release=%s" % ubuntu_release)691 logger.debug("Ubuntu release=%s" % ubuntu_release)
693 return ubuntu_release692 return ubuntu_release
694 except ValueError:693 except ValueError:
695 pass694 pass
@@ -720,7 +719,7 @@ def get_ubuntu_release_from_manifest_snap(m):
720 ubuntu_release = get_os_codename(719 ubuntu_release = get_os_codename(
721 "ubuntu", m["snapcraft-os-release-version-id"]720 "ubuntu", m["snapcraft-os-release-version-id"]
722 )721 )
723 debug(722 logger.debug(
724 "Could not determine Ubuntu release (non-core base)."723 "Could not determine Ubuntu release (non-core base)."
725 "Guessing based on snapcraft-os-release-version-id: %s"724 "Guessing based on snapcraft-os-release-version-id: %s"
726 % (m["snapcraft-os-release-version-id"])725 % (m["snapcraft-os-release-version-id"])
@@ -731,7 +730,7 @@ def get_ubuntu_release_from_manifest_snap(m):
731 if ubuntu_release is None:730 if ubuntu_release is None:
732 # no installed snaps, use default731 # no installed snaps, use default
733 if len(installed_snaps) == 0:732 if len(installed_snaps) == 0:
734 debug(733 logger.debug(
735 "Could not determine Ubuntu release (non-core base with "734 "Could not determine Ubuntu release (non-core base with "
736 "no "735 "no "
737 "installed snaps). Defaulting to '%s'" % default736 "installed snaps). Defaulting to '%s'" % default
@@ -757,7 +756,7 @@ def get_ubuntu_release_from_manifest_rock(m):
757 ubuntu_release = get_os_codename(756 ubuntu_release = get_os_codename(
758 m["os-release-id"], str(m["os-release-version-id"])757 m["os-release-id"], str(m["os-release-version-id"])
759 )758 )
760 debug("Ubuntu release=%s" % ubuntu_release)759 logger.debug("Ubuntu release=%s" % ubuntu_release)
761 except ValueError:760 except ValueError:
762 pass761 pass
763 else:762 else:
@@ -775,7 +774,7 @@ def get_ubuntu_release_from_manifest(m, m_type="snap"):
775 ubuntu_release = get_ubuntu_release_from_manifest_rock(m)774 ubuntu_release = get_ubuntu_release_from_manifest_rock(m)
776 else:775 else:
777 raise TypeError("Unsupported manifest type %s" % m_type)776 raise TypeError("Unsupported manifest type %s" % m_type)
778 debug("Ubuntu release=%s" % ubuntu_release)777 logger.debug("Ubuntu release=%s" % ubuntu_release)
779778
780 return ubuntu_release779 return ubuntu_release
781780
@@ -789,5 +788,5 @@ def get_snapcraft_version_from_manifest(m):
789 try:788 try:
790 return debversion.DebVersion(m["snapcraft-version"])789 return debversion.DebVersion(m["snapcraft-version"])
791 except ValueError as e:790 except ValueError as e:
792 warn("Invalid Snapcraft version: %s" % e)791 logger.warning("Invalid Snapcraft version: %s" % e)
793 return None792 return None
diff --git a/tests/test-dump-tool.sh.expected b/tests/test-dump-tool.sh.expected
index 702666e..1cc4104 100644
--- a/tests/test-dump-tool.sh.expected
+++ b/tests/test-dump-tool.sh.expected
@@ -14,14 +14,14 @@ Done: 10 revisions read
1414
15= Test --file --warn-if-empty =15= Test --file --warn-if-empty =
16Running: dump-tool --warn-if-empty --file ./tests/test-store-dump.116Running: dump-tool --warn-if-empty --file ./tests/test-store-dump.1
17WARN: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|1: empty17WARNING: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|1: empty
18WARN: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|2: empty18WARNING: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|2: empty
19WARN: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|3: empty19WARNING: Skipping 4ZWSHtNHDBdBsoGCTVgKkk8F9MtvjZS1|3: empty
20WARN: Skipping 99T7MUlRhtI3U0QFgl5mXXESAiSwt776|1: empty20WARNING: Skipping 99T7MUlRhtI3U0QFgl5mXXESAiSwt776|1: empty
21WARN: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|1: empty21WARNING: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|1: empty
22WARN: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|2: empty22WARNING: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|2: empty
23WARN: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|3: empty23WARNING: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|3: empty
24WARN: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|4: empty24WARNING: Skipping UqFziVZDHLSyO3TqSWgNBoAdHbLI4dAH|4: empty
2525
26= Test --db-file =26= Test --db-file =
27Running: dump-tool --db-file ./tests/test-store-dump.1.json27Running: dump-tool --db-file ./tests/test-store-dump.1.json
diff --git a/tests/test-snap-verify-declaration.sh.expected b/tests/test-snap-verify-declaration.sh.expected
index 0149682..88f34ee 100644
--- a/tests/test-snap-verify-declaration.sh.expected
+++ b/tests/test-snap-verify-declaration.sh.expected
@@ -4,7 +4,7 @@ usage: snap-verify-declaration [-h] [--json] [--plugs PLUGS] [--slots SLOTS]
44
5Check a snap declaration for errors5Check a snap declaration for errors
66
7optional arguments:7options:
8 -h, --help show this help message and exit8 -h, --help show this help message and exit
9 --json print json output9 --json print json output
10 --plugs PLUGS file specifying snap declaration for plugs10 --plugs PLUGS file specifying snap declaration for plugs
@@ -138,18 +138,7 @@ Running: snap-verify-declaration --plugs=./plugs
138ERROR: Failed to read plugs: Expecting property name enclosed in double quotes: line 2 column 1 (char 2)138ERROR: Failed to read plugs: Expecting property name enclosed in double quotes: line 2 column 1 (char 2)
139139
140Running: snap-verify-declaration --json --plugs=./plugs140Running: snap-verify-declaration --json --plugs=./plugs
141{141ERROR: Failed to read plugs: Expecting property name enclosed in double quotes: line 2 column 1 (char 2)
142 "runtime-errors": {
143 "error": {
144 "msg": {
145 "manual_review": true,
146 "text": "Failed to read plugs: Expecting property name enclosed in double quotes: line 2 column 1 (char 2)"
147 }
148 },
149 "info": {},
150 "warn": {}
151 }
152}
153142
154Running: snap-verify-declaration --plugs=./plugs143Running: snap-verify-declaration --plugs=./plugs
155{'error': {'snap-declaration-verify_v2:valid_interface:nonexistent': {'manual_review': False,144{'error': {'snap-declaration-verify_v2:valid_interface:nonexistent': {'manual_review': False,
@@ -208,16 +197,5 @@ Running: snap-verify-declaration --plugs=./plugs
208ERROR: Failed to read plugs: bare <class 'bool'> value True for 'mir:allow-auto-connection' is not allowed - this should be a string "true" instead197ERROR: Failed to read plugs: bare <class 'bool'> value True for 'mir:allow-auto-connection' is not allowed - this should be a string "true" instead
209198
210Running: snap-verify-declaration --json --plugs=./plugs199Running: snap-verify-declaration --json --plugs=./plugs
211{200ERROR: Failed to read plugs: bare <class 'bool'> value True for 'mir:allow-auto-connection' is not allowed - this should be a string "true" instead
212 "runtime-errors": {
213 "error": {
214 "msg": {
215 "manual_review": true,
216 "text": "Failed to read plugs: bare <class 'bool'> value True for 'mir:allow-auto-connection' is not allowed - this should be a string \"true\" instead"
217 }
218 },
219 "info": {},
220 "warn": {}
221 }
222}
223201
diff --git a/tests/test-updates-available.sh.expected b/tests/test-updates-available.sh.expected
index f6957fe..47edb1c 100644
--- a/tests/test-updates-available.sh.expected
+++ b/tests/test-updates-available.sh.expected
@@ -1419,7 +1419,7 @@ Running: snap-updates-available --with-cves --usn-db='./tests/test-usn-unittest-
1419}1419}
14201420
1421Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-1.db' --store-db='./tests/test-store-unittest-bad-1.db'1421Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-1.db' --store-db='./tests/test-store-unittest-bad-1.db'
1422WARN: 1ad: required field 'revisions' not found1422WARNING: 1ad: required field 'revisions' not found
1423ERROR: Errors encountered when scanning store entries1423ERROR: Errors encountered when scanning store entries
1424From: Snap Store <noreply+security-snap-review@canonical.com>1424From: Snap Store <noreply+security-snap-review@canonical.com>
1425To: olivier.tilloy@canonical.com1425To: olivier.tilloy@canonical.com
@@ -1655,10 +1655,10 @@ References:
16551655
16561656
1657Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-build-pkgs.db' --store-db='./tests/test-store-unittest-invalid-snapcraft-version.db'1657Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-build-pkgs.db' --store-db='./tests/test-store-unittest-invalid-snapcraft-version.db'
1658WARN: Invalid Snapcraft version: '4.4.3' not a valid Debian version1658WARNING: Invalid Snapcraft version: '4.4.3' not a valid Debian version
16591659
1660Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-build-pkgs.db' --store-db='./tests/test-store-kernel-invalid-snapcraft-version.db'1660Running: ./bin/snap-updates-available --usn-db='./tests/test-usn-unittest-build-pkgs.db' --store-db='./tests/test-store-kernel-invalid-snapcraft-version.db'
1661WARN: Invalid Snapcraft version: '2.3' not a valid Debian version1661WARNING: Invalid Snapcraft version: '2.3' not a valid Debian version
16621662
1663Running: snap-updates-available --usn-db='./tests/test-usn-unittest-lp1841848.db' --snap='./tests/test-check-notices_0.1_amd64.snap'1663Running: snap-updates-available --usn-db='./tests/test-usn-unittest-lp1841848.db' --snap='./tests/test-check-notices_0.1_amd64.snap'
16641664

Subscribers

People subscribed via source and target branches