Merge ~barryprice/charm-k8s-discourse/+git/charm-k8s-discourse:v2.8.0.beta7-20.04 into charm-k8s-discourse:master

Proposed by Barry Price
Status: Superseded
Proposed branch: ~barryprice/charm-k8s-discourse/+git/charm-k8s-discourse:v2.8.0.beta7-20.04
Merge into: charm-k8s-discourse:master
Diff against target: 191 lines (+40/-16)
5 files modified
image/Dockerfile (+2/-2)
image/build_scripts/build_app (+1/-0)
image/build_scripts/get_app_dependencies (+1/-0)
lib/charms/redis_k8s/v0/redis.py (+33/-14)
tests/unit/test_charm.py (+3/-0)
Reviewer Review Type Date Requested Status
Discourse Charm Maintainers Pending
Review via email: mp+411006@code.launchpad.net

Commit message

Run charmcraft fetch-lib to update our redis_k8s library, and add its missing path to our tests

To post a comment you must log in.

Unmerged commits

28e3d00... by Barry Price

Run charmcraft fetch-lib to update our redis_k8s library, and add its missing path to our tests

7b1f859... by Barry Price

Add the libssl-dev dependency to our image, and explicitly install the bundler gem before attempting to use it (for all image types)

Reviewed-on: https://code.launchpad.net/~barryprice/charm-k8s-discourse/+git/charm-k8s-discourse/+merge/410992
Reviewed-by: Haw Loeung <email address hidden>

05c5a4d... by Barry Price

Add the libssl-dev dependency to our image, and explicitly install the bundler gem before attempting to use it (for all image types)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/image/Dockerfile b/image/Dockerfile
2index 24fb59a..8ae09bc 100644
3--- a/image/Dockerfile
4+++ b/image/Dockerfile
5@@ -77,7 +77,7 @@ RUN cd ${CONTAINER_APP_ROOT}/app/plugins && git clone https://github.com/canonic
6 RUN chown -R ${CONTAINER_APP_USERNAME}:${CONTAINER_APP_GROUP} ${CONTAINER_APP_ROOT}/app/plugins
7 # Have to determine the gems needed and install them now, otherwise Discourse will
8 # try to install them at runtime, which may not work due to network access issues.
9-RUN cd ${CONTAINER_APP_ROOT}/app/plugins/discourse-saml && mkdir -p gems && chown ${CONTAINER_APP_USERNAME} gems && echo 'source "https://rubygems.org"' > Gemfile ; grep -e ^gem plugin.rb >> Gemfile && su -s /bin/bash -c '${CONTAINER_APP_ROOT}/app/bin/bundle install --gemfile=Gemfile --path=${CONTAINER_APP_ROOT}/app/plugins/discourse-saml/gems' ${CONTAINER_APP_USERNAME} && cd gems && ln -s ruby/* ./
10+RUN cd ${CONTAINER_APP_ROOT}/app/plugins/discourse-saml && mkdir -p gems && chown ${CONTAINER_APP_USERNAME} gems && echo 'source "https://rubygems.org"' > Gemfile ; grep -e ^gem plugin.rb >> Gemfile && su -s /bin/bash -c 'gem install bundler' ${CONTAINER_APP_USERNAME} && su -s /bin/bash -c '${CONTAINER_APP_ROOT}/app/bin/bundle install --gemfile=Gemfile --path=${CONTAINER_APP_ROOT}/app/plugins/discourse-saml/gems' ${CONTAINER_APP_USERNAME} && cd gems && ln -s ruby/* ./
11 RUN cd ${CONTAINER_APP_ROOT}/app && su -s /bin/bash -c 'bin/bundle install' ${CONTAINER_APP_USERNAME}
12
13 RUN echo "markdown-saml image complete"
14@@ -91,7 +91,7 @@ RUN cd ${CONTAINER_APP_ROOT}/app/plugins && git clone https://github.com/canonic
15 RUN chown -R ${CONTAINER_APP_USERNAME}:${CONTAINER_APP_GROUP} ${CONTAINER_APP_ROOT}/app/plugins
16 # Have to determine the gems needed and install them now, otherwise Discourse will
17 # try to install them at runtime, which may not work due to network access issues.
18-RUN cd ${CONTAINER_APP_ROOT}/app/plugins/discourse-saml && mkdir -p gems && chown ${CONTAINER_APP_USERNAME} gems && echo 'source "https://rubygems.org"' > Gemfile ; grep -e ^gem plugin.rb >> Gemfile && su -s /bin/bash -c '${CONTAINER_APP_ROOT}/app/bin/bundle install --gemfile=Gemfile --path=${CONTAINER_APP_ROOT}/app/plugins/discourse-saml/gems' ${CONTAINER_APP_USERNAME} && cd gems && ln -s ruby/* ./
19+RUN cd ${CONTAINER_APP_ROOT}/app/plugins/discourse-saml && mkdir -p gems && chown ${CONTAINER_APP_USERNAME} gems && echo 'source "https://rubygems.org"' > Gemfile ; grep -e ^gem plugin.rb >> Gemfile && su -s /bin/bash -c 'gem install bundler' ${CONTAINER_APP_USERNAME} && su -s /bin/bash -c '${CONTAINER_APP_ROOT}/app/bin/bundle install --gemfile=Gemfile --path=${CONTAINER_APP_ROOT}/app/plugins/discourse-saml/gems' ${CONTAINER_APP_USERNAME} && cd gems && ln -s ruby/* ./
20 RUN cd ${CONTAINER_APP_ROOT}/app && su -s /bin/bash -c 'bin/bundle install' ${CONTAINER_APP_USERNAME}
21
22 RUN echo "markdown-saml-solved image complete"
23diff --git a/image/build_scripts/build_app b/image/build_scripts/build_app
24index d217f17..cb0f0e0 100755
25--- a/image/build_scripts/build_app
26+++ b/image/build_scripts/build_app
27@@ -24,6 +24,7 @@ cd ${CONTAINER_APP_ROOT}/app
28
29 # This must be done as the discourse user in order to avoid permission
30 # problems later.
31+su -s /bin/bash -c 'gem install bundler' ${CONTAINER_APP_USERNAME}
32 su -s /bin/bash -c 'bin/bundle install' ${CONTAINER_APP_USERNAME}
33
34 # If intermediate files are generated by the build process or other files are
35diff --git a/image/build_scripts/get_app_dependencies b/image/build_scripts/get_app_dependencies
36index 65b267a..0c78012 100755
37--- a/image/build_scripts/get_app_dependencies
38+++ b/image/build_scripts/get_app_dependencies
39@@ -12,6 +12,7 @@ apt-get install -y brotli \
40 jpegoptim \
41 libjpeg-turbo-progs \
42 libpq-dev \
43+ libssl-dev \
44 libxml2-dev \
45 libxslt1-dev \
46 libz-dev \
47diff --git a/lib/charms/redis_k8s/v0/redis.py b/lib/charms/redis_k8s/v0/redis.py
48index 70787b6..5360ce0 100644
49--- a/lib/charms/redis_k8s/v0/redis.py
50+++ b/lib/charms/redis_k8s/v0/redis.py
51@@ -6,15 +6,29 @@ redis interface.
52 Import `RedisRequires` in your charm by adding the following to `src/charm.py`:
53 ```
54 from charms.redis_k8s.v0.redis import RedisRequires
55-
56-# In your charm's `__init__` method.
57+```
58+And then in your charm's `__init__` method:
59+```
60+# Make sure you set redis_relation in StoredState. Assuming you refer to this
61+# as `self._stored`:
62+self._stored.set_default(redis_relation={})
63 self.redis = RedisRequires(self, self._stored)
64 ```
65-And then wherever you need to reference the relation data:
66+And then wherever you need to reference the relation data it will be available
67+via StoredState:
68 ```
69+redis_hosts = []
70 for redis_unit in self._stored.redis_relation:
71- redis_host = self._stored.redis_relation[redis_unit]["hostname"]
72- redis_port = self._stored.redis_relation[redis_unit]["port"]
73+ redis_hosts.append({
74+ "redis-host": self._stored.redis_relation[redis_unit]["hostname"],
75+ "redis-port": self._stored.redis_relation[redis_unit]["port"],
76+ })
77+```
78+You will also need to add the following to `metadata.yaml`:
79+```
80+requires:
81+ redis:
82+ interface: redis
83 ```
84 """
85 import logging
86@@ -22,30 +36,31 @@ import logging
87 from ops.charm import CharmEvents
88 from ops.framework import EventBase, EventSource, Object
89
90-# The unique Charmhub library identifier, never change it
91+# The unique Charmhub library identifier, never change it.
92 LIBID = "fe18a608cec5465fa5153e419abcad7b"
93
94-# Increment this major API version when introducing breaking changes
95+# Increment this major API version when introducing breaking changes.
96 LIBAPI = 0
97
98 # Increment this PATCH version before using `charmcraft publish-lib` or reset
99-# to 0 if you are raising the major API version
100-LIBPATCH = 1
101+# to 0 if you are raising the major API version.
102+LIBPATCH = 2
103
104 logger = logging.getLogger(__name__)
105
106
107 class RedisRelationUpdatedEvent(EventBase):
108- pass
109+ """An event for the redis relation having been updated."""
110
111
112 class RedisRelationCharmEvents(CharmEvents):
113+ """A class to carry custom charm events so requires can react to relation changes."""
114 redis_relation_updated = EventSource(RedisRelationUpdatedEvent)
115
116
117 class RedisRequires(Object):
118 def __init__(self, charm, _stored):
119- # Define a constructor that takes the charm and it's StoredState
120+ """A class implementing the redis requires relation."""
121 super().__init__(charm, "redis")
122 self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed)
123 self.framework.observe(charm.on.redis_relation_broken, self._on_relation_broken)
124@@ -53,19 +68,20 @@ class RedisRequires(Object):
125 self.charm = charm
126
127 def _on_relation_changed(self, event):
128+ """Handle the relation changed event."""
129 if not event.unit:
130 return
131
132 hostname = event.relation.data[event.unit].get("hostname")
133 port = event.relation.data[event.unit].get("port")
134- # Store some data from the relation in local state
135 self._stored.redis_relation[event.relation.id] = {"hostname": hostname, "port": port}
136
137 # Trigger an event that our charm can react to.
138 self.charm.on.redis_relation_updated.emit()
139
140 def _on_relation_broken(self, event):
141- # Remove the unit data from local state
142+ """Handle the relation broken event."""
143+ # Remove the unit data from local state.
144 self._stored.redis_relation.pop(event.relation.id, None)
145
146 # Trigger an event that our charm can react to.
147@@ -74,23 +90,26 @@ class RedisRequires(Object):
148
149 class RedisProvides(Object):
150 def __init__(self, charm, port):
151+ """A class implementing the redis provides relation."""
152 super().__init__(charm, "redis")
153 self.framework.observe(charm.on.redis_relation_changed, self._on_relation_changed)
154 self._port = port
155
156 def _on_relation_changed(self, event):
157+ """Handle the relation changed event."""
158 if not self.model.unit.is_leader():
159 logger.debug("Relation changes ignored by non-leader")
160 return
161
162 event.relation.data[self.model.unit]['hostname'] = str(self._bind_address(event))
163 event.relation.data[self.model.unit]['port'] = str(self._port)
164- # The reactive Redis charm exposes also 'password'. When tackling
165+ # The reactive Redis charm also exposes 'password'. When tackling
166 # https://github.com/canonical/redis-operator/issues/7 add 'password'
167 # field so that it matches the exposed interface information from it.
168 # event.relation.data[self.unit]['password'] = ''
169
170 def _bind_address(self, event):
171+ """Convenience function for getting the unit address."""
172 relation = self.model.get_relation(event.relation.name, event.relation.id)
173 if address := self.model.get_binding(relation).network.bind_address:
174 return address
175diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py
176index 2012479..95f8691 100644
177--- a/tests/unit/test_charm.py
178+++ b/tests/unit/test_charm.py
179@@ -7,9 +7,12 @@ import copy
180 import glob
181 import mock
182 import os
183+import sys
184 import unittest
185 import yaml
186
187+sys.path.insert(0, 'lib')
188+
189 from types import SimpleNamespace
190
191 from charm import (

Subscribers

People subscribed via source and target branches