Releases: canonical/operator
2.16.1 Don't have Harness alter os.environ
This is a small bug-fix release to address a regression in ops 2.16.0 where creating a Harness
object would add a JUJU_VERSION
to os.environ
.
Fixes
- Don't alter os.environ in Harness in #1359
Full Changelog: 2.16.0...2.16.1
2.16.0
This release adds a private _JujuContext
dataclass used to parse all `JUJU_*`` environment variables in one place; besides, a significant amount of work has been done on tests, continuous integration and documentation.
Features
- Add the description field to SecretInfo in #1338
Refactor
- Parse JUJU_* env in one place in #1313
Fixes
- Juju passes the expiry in a field 'expiry', not 'expires' in #1317
- Correct the signature of .events() in #1342
Documentation
- Security policy change to only support each active major release in #1297
- Add example Juju version markers in #1311
- Use Sphinx 8 in #1303
- Live reload with sphinx-autobuild in #1323
Tests
- Update the smoke test series/bases in #1318
- Run pytest in parallel with pytest xdist in #1319
- Bump pyright to 1.1.377 in #1332
- Run tests on Py 3.12 and install test on Py 3.13 in #1315
CI
- Add a workflow that runs the TIOBE quality checks in #1301
- Allow executing the TIOBE workflow manually in #1321
- Make Pyright report unnecessary type ignore comments in #1333
- Enable linting of docs/custom_conf.py in #1330
New Contributors
Thanks @james-garner-canonical for your first contributions, and welcome to the team!
Full Changelog: 2.15.0...2.16.0
2.15.0 Support Pebble check-failed and check-recovered events
What's Changed
This release adds support for new events based on Pebble checks. As of Juju 3.6b2, when a Pebble check reaches the failure threshold, a PebbleCheckFailedEvent will be emitted - and when the check starts passing again, the charm will get a PebbleCheckRecoveredEvent. Kubernetes charms can observe these events to react to failing checks - for example, change the unit or application status, output additional logging, or dynamically adjust the workload to work around the failure.
- Add support for Pebble check-failed and check-recovered events in #1281
Fixes
- Pass secret data to Juju via files, rather than as command-line values in #1290 fixing CVE-2024-41129
- Include checks and log targets when merging layers in ops.testing by @amandahla in #1268
Documentation
- Clarify distinction between maintenance and waiting status in #1148
CI
- Bump the Go version to match Pebble in #1285
- Run ruff format over charm pin update code in #1278
- Bump certifi from 2024.2.2 to 2024.7.4 in /docs in #1282
- Update charm pins in #1269
New Contributors
- @amandahla made their first code contribution in #1268
Full Changelog: 2.14.1...2.15.0
2.14.1 Fix a possible Pebble exec hang and minor other fixes
What's Changed
No new features with this release, but it includes a significant fix for Pebble exec
to avoid hanging when Pebble is unable to respond quickly.
We've also corrected the Harness behaviour when working with secrets when the secret does not exist or the charm does not have permission to view/modify it, and also expanded the API reference documentation for secrets.
Fixes
- Add connect timeout for exec websockets to avoid hanging in #1247
- Adjust Harness secret behaviour to align with Juju in #1248
Tests
- Fix TypeError when running test.pebble_cli in #1245
- Properly clean up after running setup_root_logging in test_log in #1259
- Verify that defer() is not usable on stop,remove,secret-expired,secret-rotate in #1233
Documentation
- Fix HACKING.md link on PyPI, and internal links in #1261 and #1236
- Add a section to HACKING.md on PR titles (commit messages to main) in #1252
- Add release step to update pinned charm tests in #1213
- Add a security policy in #1266
- Add ops.main to API reference in #1273
CI
- Only run tests once on push to PR in #1242
- Validate PR title against conventional commit rules in #1262
- Only update ops, not all dependencies, in charm tests in #1275
- Add artefact attestation in #1267
Thanks go to the members of the Canonical security teams who helped out putting the security policy together!
Full Changelog: 2.14.0...2.14.1
2.14.0 Fix RelationDataContent.update, add ActionFailed.__str__
This release fixes the RelationDataContent.update
method to follow dict.update
semantics, that is to allow another dict, an iterable, keyword arguments or a mixture thereof.
Features
- feat: add a
__str__
to ActionFailed, for better unexpected failure output in #1209
Fixes
Documentation
- Use the actual emoji character rather than GitHub markup, to show properly on PyPI in #1221
- Clarify that SecretNotFound may be raised for permission errors in #1231
Refactoring
- Refactor tests to pytest style in #1199 #1200 #1203 #1206
- Use
ruff
formatter and reformat all code in #1224 - Don't use f-strings in logging calls in #1227 #1234
New Contributors
- @dimaqq made their first contribution in #1217. Thanks @dimaqq for your first contributions, and welcome to the team!
- @addyess made their first contribution in #1226
Full Changelog: 2.13.0...2.14.0
2.13.0 Testing User Secrets with Harness and Other Improvements
The main feature this release is the ability to work with user secrets (secrets that a Juju admin adds to the model) in Harness. You'll want to start with the new add_user_secret()
method and from there can mostly manage them in the same way as application secrets.
Note that one of the fixes corrects the type of config values, which were previously strongly typed as str
, when they may be int
, float
, bool
, or str
. This may break your existing type checks, although we have endeavoured to reach out preemptively with PRs to address this where possible.
Features
Fixes
- Correct the model config types in #1183
- In Harness, only inspect the source file if it will be used - this fixes using Harness in a Python REPL in #1181
Documentation
- Update publishing a release in HACKING.md in #1173
- Add
tox -e docs-deps
to compile requirements.txt in #1172 - Update doc to note deprecated functionality in #1178
Tests
Full Changelog: 2.12.0...2.13.0
2.12.0 Support getting cloud specs via the credential-get hook tool, and other improvements.
This release adds a new model method, get_cloud_spec
, that returns information about the cloud where the charm is deployed. This may also include credentials that can be used by the charm to interact directly with the cloud, where Juju does not yet provide sufficient modelling. If your charm is currently using the credential-get
tool directly, you can now make use of this native support in ops. Note that this functionality is only available on machine charms.
Features
- Added
Model.get_cloud_spec
which uses thecredential-get
hook tool to get details of the cloud where the model is deployed #1152
Fixes
- Add a consistency check and default network to
add_relation
by @PietroPasotti in #1138 - Warn when an observer weakref is lost by @PietroPasotti in #1142
- Update Pebble Notices
get_notices
parameter name tousers=all
(previouslyselect=all
) #1146 - More robust validation of observer signatures #1147
- Fix attaching storage in Harness before
begin
#1150 - Change
Model.relation.app
type fromApplication|None
toApplication
#1151 - Fixed an issue where
pebble.Client.exec
might leak asocket.timeout
(builtins.TimeoutError
) exception #1155 - Don't special-case
get_relation
behaviour inleader-elected
#1156 - Accept
type: secret
for config options by @jameinel in #1167
Refactoring
- Refactor main.py, creating a new
_Manager
class by @PietroPasotti in #1085
Documentation
- Use "integrate with" rather than "relate to" #1145
- Updated code examples in the docstring of
ops.testing
from unittest to pytest style #1157 - Add peer relation details in
Harness.add_relation
docstring #1168 - Update Read the Docs Sphinx Furo theme to use Canonical's latest styling #1163, #1164, #1165
New Contributors
Thanks @IronCore864 for your first contributions, and welcome to the team!
Full Changelog: 2.11.0...2.12.0
2.11.0 Marking additional events as non-defer()able, and other minor improvements
This release marks additional events as not suitable for deferring: StopEvent
, RemoveEvent
, and the LifecycleEvents
: CollectStatusEvent
, CommitEvent
, and PreCommitEvent
. The defer()
method on these event classes is marked as NoReturn
and calling it will raise a RuntimeError
.
Features
- feat: add the action's ID to the ActionEvent object in #1124
- feat: add the ability to compare two Plan objects with == and create a Plan from a dict in #1134
- feat: only have a
defer()
method on events that can be deferred in #1122
Fixes
- fix(testing): set JUJU_REMOTE_APP and allow fetching relation data in relation-broken in #1130
Documentation
- docs: tweak the wording around can_connect() usage in #1123
Tooling
- chore: move to ruff for linting in #1120
- chore: adjust isort to be more compatible with ruff in #1139
- chore: expand ruff rule sets and make corresponding minor adjustments in #1114
Full Changelog: 2.10.0...2.11.0
2.10.0 Pebble custom notices, adjustments to relation-broken, and more
This release adds support for Pebble custom notices, including in the Harness testing framework, and removes the broken relation from the model's relations list when in the relation-broken event. There's also the usual collection of documentation improvements, bug fixes, and other minor improvements.
Pebble Notices
Pebble now includes a subsystem called Notices, each of which has a type and a key (currently the only type is "custom"). Custom notices allow the workload to wake up the charm when something interesting happens with the workload, for example, when a PostgreSQL backup process finishes, or some kind of alert occurs.
Workloads can run pebble notify
to record an occurrence of a custom notice, providing a unique key and optional data, and Juju will trigger a PebbleCustomNotice
event on the charm for it to take appropriate action.
Support for Pebble Notices is available from Juju 3.4.0 onwards. Read the docs about how to use custom notices from the workload container.
Relation-Broken
When a charm is handling a relation-broken event, the relation is on the verge of being removed. A common pattern in charms is to iterate through Model.relations
(to generate a configuration file, for example), and the broken relation should not be included with the active relations. To simplify charm code, Model.relations
now excludes the broken relation. The relation is still accessible via the event's .relation
attribute, and all Relation
objects now have an .active
attribute to distinguish between the broken relation (active == False) and other relations (active == True).
The plan is that this change will also appear when using the Juju hook tools directly in a future version of Juju.
This does not change accessing the relation data during relation-broken, and this does not change any behaviour in relation-departed.
Features
- feat: support for Pebble Notices in #1086 and in #1100
- feat: add Relation.active, exclude inactive relations from Model.relations in #1091
- feat: when handling actions, print uncaught exceptions to stderr in #1087
- feat: model error on testing module if invalid status set by charm by @yanksyoon in #1107
- feat: add support for v2 fields in CharmMeta in #1106
Fixes
- fix: add pebble log targets and checks to testing plan by @PietroPasotti in #1111
- fix(charm): make collect-status a LifeCycleEvent to avoid logging it by @PietroPasotti in #1080
Documentation
- docs: update README.md in light of changes to
charmcraft init
output by @tmihoc in #1089 - docs: document limitations with pushing locked or bind-mount files in #1094
- docs: add instructions on how to use a custom version of ops in a Charm in #1092
Tooling
- build: migrate to pyproject.toml in #1068
- ci: use a trusted publisher token for publishing to PyPI in #1061
- fix(typing): update to latest version of Pyright and fix errors in #1105
Many thanks to @PietroPasotti, @yanksyoon, and @tmihoc for their contributions to this release!
Full Changelog: 2.9.0...2.10.0
2.9.0: Pebble log forwarding, unit testing actions, and more
This release makes it easy to write tests for your Charm actions, aligns testing secrets with upcoming Juju changes, and exposes the ability to use the new Pebble log forwarding functionality. There's also the usual collection of documentation improvements, bug fixes, and other minor improvements.
Unit Testing Actions
Writing unit tests for actions with Harness is now as simple as:
def test_action(harness):
out = harness.run_action("my-action-name", {"param1": value, "param2": value2})
assert out.results == {"result1": "expected"}
Added in #1053
Secrets
In the original implementation of Juju secrets, the owner of a secret would automatically peek (get the latest revision) at secret contents - this also meant that using 'refresh' was not allowed (since there was no revision tracking). This behaviour causes difficulties in some situations, so is being changed in the next versions of Juju (back to 3.1.7), removing the automatic peek and allowing refresh.
In ops
, we are switching to the new behaviour, and this applies regardless of the detected/set JujuVersion. This primarily applies to Harness, which was updated in #1067, but also to the ops
documentation. The constraints outside of Harness are applied by Juju, so your charms will reflect the new behaviour when Juju updates.
Note that you can get the old behaviour by always using refresh=True
if that's what you prefer (to support both old and new Juju, you'll need to wrap this so that in older Juju you retry when it complains that you can't refresh).
We've also fixed the simulated access to app secrets for non-leaders in #1076.
Pebble Log Targets
Pebble 1.4 added the ability to configure log forwarding for services to a Loki server, and Pebble 1.6 extends this with the ability to add custom labels to the forwarded logs. This functionality is now exposed in ops
via a new (optional) log-targets
section in Pebble layers and plans. Added in #1074
Documentation Improvements
- A fresh README that's simpler and better aligns with the docs and other projects in the Juju universe in #1052 - many thanks to @tmihoc for this contribution!
- Clarified how custom events are emitted in
emit()
in #1072 - Fixed the
Harness.get_filesystem_root
example in the docs in #1065
Minor Improvements
- Removed the executable bit from all the .py files by in #1059 - thanks @jameinel!
- The test suite now passes under Python 3.12 in #1081
Fixes
- The SQLite storage file is no longer group/other readable. We strongly recommend against storing any secret data in stored state (use secrets), but we are aware of cases of this in the wild. This change prevents other users in the containers from being able to access the saved state file. Existing storage files will be
chmod
'd to 0o600 whenops
first opens them after upgrading to 2.9.0+. #1057 - When parsing a timestamp returned from Pebble, there was a 1 in 2 million chance that
ops
would fail with aValueError
. Fixed in #1084 Container.push_path
andHarness.list_files
would fail if the files/folders involved belonged to a user or group ID that did not have a name (for example, had been removed). Fixed in #1082. Thanks to @nedbat for the report!
Full Changelog: 2.8.0...2.9.0