Skip to content

Commit f988725

Browse files
chore: update charm libraries
1 parent f469fc5 commit f988725

File tree

1 file changed

+56
-29
lines changed
  • agent/charms/testflinger-agent-host-charm/lib/charms/operator_libs_linux/v0

1 file changed

+56
-29
lines changed

agent/charms/testflinger-agent-host-charm/lib/charms/operator_libs_linux/v0/apt.py

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
and their properties (available groups, baseuri. gpg key). This class can add, disable, or
6767
manipulate repositories. Items can be retrieved as `DebianRepository` objects.
6868
69-
In order add a new repository with explicit details for fields, a new `DebianRepository` can
70-
be added to `RepositoryMapping`
69+
In order to add a new repository with explicit details for fields, a new `DebianRepository`
70+
can be added to `RepositoryMapping`
7171
7272
`RepositoryMapping` provides an abstraction around the existing repositories on the system,
7373
and can be accessed and iterated over like any `Mapping` object, to retrieve values by key,
@@ -98,6 +98,10 @@
9898
repo = DebianRepository.from_repo_line(line)
9999
repositories.add(repo)
100100
```
101+
102+
Dependencies:
103+
Note that this module requires `opentelemetry-api`, which is already included into
104+
your charm's virtual environment via `ops >= 2.21`.
101105
"""
102106

103107
from __future__ import annotations
@@ -114,7 +118,10 @@
114118
from typing import Any, Iterable, Iterator, Literal, Mapping
115119
from urllib.parse import urlparse
116120

121+
import opentelemetry.trace
122+
117123
logger = logging.getLogger(__name__)
124+
tracer = opentelemetry.trace.get_tracer(__name__)
118125

119126
# The unique Charmhub library identifier, never change it
120127
LIBID = "7c3dbc9c2ad44a47bd6fcb25caa270e5"
@@ -124,7 +131,9 @@
124131

125132
# Increment this PATCH version before using `charmcraft publish-lib` or reset
126133
# to 0 if you are raising the major API version
127-
LIBPATCH = 17
134+
LIBPATCH = 18
135+
136+
PYDEPS = ["opentelemetry-api"]
128137

129138

130139
VALID_SOURCE_TYPES = ("deb", "deb-src")
@@ -249,7 +258,9 @@ def _apt(
249258
try:
250259
env = os.environ.copy()
251260
env["DEBIAN_FRONTEND"] = "noninteractive"
252-
subprocess.run(_cmd, capture_output=True, check=True, text=True, env=env)
261+
with tracer.start_as_current_span(_cmd[0]) as span:
262+
span.set_attribute("argv", _cmd)
263+
subprocess.run(_cmd, capture_output=True, check=True, text=True, env=env)
253264
except CalledProcessError as e:
254265
raise PackageError(
255266
f"Could not {command} package(s) {package_names}: {e.stderr}"
@@ -464,18 +475,20 @@ def from_apt_cache(
464475
arch: an optional architecture, defaulting to `dpkg --print-architecture`.
465476
If an architecture is not specified, this will be used for selection.
466477
"""
467-
system_arch = check_output(
468-
["dpkg", "--print-architecture"], universal_newlines=True
469-
).strip()
478+
cmd = ["dpkg", "--print-architecture"]
479+
with tracer.start_as_current_span(cmd[0]) as span:
480+
span.set_attribute("argv", cmd)
481+
system_arch = check_output(cmd, universal_newlines=True).strip()
470482
arch = arch if arch else system_arch
471483

472484
# Regexps are a really terrible way to do this. Thanks dpkg
473485
keys = ("Package", "Architecture", "Version")
474486

487+
cmd = ["apt-cache", "show", package]
475488
try:
476-
output = check_output(
477-
["apt-cache", "show", package], stderr=PIPE, universal_newlines=True
478-
)
489+
with tracer.start_as_current_span(cmd[0]) as span:
490+
span.set_attribute("argv", cmd)
491+
output = check_output(cmd, stderr=PIPE, universal_newlines=True)
479492
except CalledProcessError as e:
480493
raise PackageError(f"Could not list packages in apt-cache: {e.stderr}") from None
481494

@@ -880,7 +893,9 @@ def update() -> None:
880893
"""Update the apt cache via `apt-get update`."""
881894
cmd = ["apt-get", "update", "--error-on=any"]
882895
try:
883-
subprocess.run(cmd, capture_output=True, check=True)
896+
with tracer.start_as_current_span(cmd[0]) as span:
897+
span.set_attribute("argv", cmd)
898+
subprocess.run(cmd, capture_output=True, check=True)
884899
except CalledProcessError as e:
885900
logger.error(
886901
"%s:\nstdout:\n%s\nstderr:\n%s",
@@ -1107,12 +1122,14 @@ def disable(self) -> None:
11071122
" Please raise an issue if you require this feature."
11081123
)
11091124
searcher = f"{self.repotype} {self.make_options_string()}{self.uri} {self.release}"
1110-
with fileinput.input(self._filename, inplace=True) as lines:
1111-
for line in lines:
1112-
if re.match(rf"^{re.escape(searcher)}\s", line):
1113-
print(f"# {line}", end="")
1114-
else:
1115-
print(line, end="")
1125+
with tracer.start_as_current_span("disable source") as span:
1126+
span.set_attribute("filename", self._filename)
1127+
with fileinput.input(self._filename, inplace=True) as lines:
1128+
for line in lines:
1129+
if re.match(rf"^{re.escape(searcher)}\s", line):
1130+
print(f"# {line}", end="")
1131+
else:
1132+
print(line, end="")
11161133

11171134
def import_key(self, key: str) -> None:
11181135
"""Import an ASCII Armor key.
@@ -1145,8 +1162,10 @@ def _get_keyid_by_gpg_key(key_material: bytes) -> str:
11451162
"""
11461163
# Use the same gpg command for both Xenial and Bionic
11471164
cmd = ["gpg", "--with-colons", "--with-fingerprint"]
1148-
ps = subprocess.run(cmd, capture_output=True, input=key_material)
1149-
out, err = ps.stdout.decode(), ps.stderr.decode()
1165+
with tracer.start_as_current_span(cmd[0]) as span:
1166+
span.set_attribute("argv", cmd)
1167+
ps = subprocess.run(cmd, capture_output=True, input=key_material)
1168+
out, err = ps.stdout.decode(), ps.stderr.decode()
11501169
if "gpg: no valid OpenPGP data found." in err:
11511170
raise GPGKeyError("Invalid GPG key material provided")
11521171
# from gnupg2 docs: fpr :: Fingerprint (fingerprint is in field 10)
@@ -1191,8 +1210,10 @@ def _get_key_by_keyid(keyid: str) -> str:
11911210
"https://keyserver.ubuntu.com" "/pks/lookup?op=get&options=mr&exact=on&search=0x{}"
11921211
)
11931212
curl_cmd = ["curl", keyserver_url.format(keyid)]
1194-
# use proxy server settings in order to retrieve the key
1195-
return check_output(curl_cmd).decode()
1213+
with tracer.start_as_current_span(curl_cmd[0]) as span:
1214+
span.set_attribute("argv", curl_cmd)
1215+
# use proxy server settings in order to retrieve the key
1216+
return check_output(curl_cmd).decode()
11961217

11971218
@staticmethod
11981219
def _dearmor_gpg_key(key_asc: bytes) -> bytes:
@@ -1207,8 +1228,11 @@ def _dearmor_gpg_key(key_asc: bytes) -> bytes:
12071228
Raises:
12081229
GPGKeyError
12091230
"""
1210-
ps = subprocess.run(["gpg", "--dearmor"], capture_output=True, input=key_asc)
1211-
out, err = ps.stdout, ps.stderr.decode()
1231+
cmd = ["gpg", "--dearmor"]
1232+
with tracer.start_as_current_span(cmd[0]) as span:
1233+
span.set_attribute("argv", cmd)
1234+
ps = subprocess.run(cmd, capture_output=True, input=key_asc)
1235+
out, err = ps.stdout, ps.stderr.decode()
12121236
if "gpg: no valid OpenPGP data found." in err:
12131237
raise GPGKeyError(
12141238
"Invalid GPG key material. Check your network setup"
@@ -1289,11 +1313,12 @@ def __init__(self):
12891313
if not os.path.isfile(default_sources):
12901314
raise
12911315

1292-
# read sources.list.d
1293-
for file in glob.iglob(os.path.join(sources_dir, "*.list")):
1294-
self.load(file)
1295-
for file in glob.iglob(os.path.join(sources_dir, "*.sources")):
1296-
self.load_deb822(file)
1316+
with tracer.start_as_current_span("load sources"):
1317+
# read sources.list.d
1318+
for file in glob.iglob(os.path.join(sources_dir, "*.list")):
1319+
self.load(file)
1320+
for file in glob.iglob(os.path.join(sources_dir, "*.sources")):
1321+
self.load_deb822(file)
12971322

12981323
def __contains__(self, key: Any) -> bool:
12991324
"""Magic method for checking presence of repo in mapping.
@@ -1533,7 +1558,9 @@ def _add_repository(
15331558
cmd.append("--no-update")
15341559
logger.info("%s", cmd)
15351560
try:
1536-
subprocess.run(cmd, check=True, capture_output=True)
1561+
with tracer.start_as_current_span(cmd[0]) as span:
1562+
span.set_attribute("argv", cmd)
1563+
subprocess.run(cmd, check=True, capture_output=True)
15371564
except CalledProcessError as e:
15381565
logger.error(
15391566
"subprocess.run(%s):\nstdout:\n%s\nstderr:\n%s",

0 commit comments

Comments
 (0)