Skip to content

Commit a0ad662

Browse files
authored
feat(rabbitmq): community plugin install + optional feature_flag pre-upgrade (#754)
- Extend `plugins:` pillar to accept dict entries `{name, url, force_cleanup?}`: downloads the .ez (filename derived from URL via basename) into the active /usr/lib/rabbitmq/lib/rabbitmq_server-<VER>/plugins/ dir BEFORE the broker restart, so /etc/rabbitmq/enabled_plugins references all stay resolvable on start-up. String entries (built-in plugins) keep their original behaviour. - Cleanup of stale copies runs in both the active versioned dir and /usr/lib/rabbitmq/plugins/. Default pattern `<name>-<digit>*` keeps unrelated files (`<name>.bak`, `<name>-foo`) intact; per-plugin `force_cleanup: True` widens it to `<name>-*`. - Add optional `rabbitmq:enable_all_feature_flag: True` which runs `rabbitmqctl enable_feature_flag all` BEFORE `rabbit_pkg`, gated by an `onlyif: rabbitmqctl status` so fresh installs skip it silently.
1 parent 27aeff3 commit a0ad662

2 files changed

Lines changed: 71 additions & 1 deletion

File tree

rabbitmq/install.sls

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,18 @@ rabbitmq_repo:
4343
##
4444
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb1.rabbitmq.com/rabbitmq-server/{{ grains["os"].lower() }}/{{ grains["oscodename"] }} {{ grains["oscodename"] }} main
4545
deb [arch=amd64 signed-by=/usr/share/keyrings/com.rabbitmq.team.gpg] https://deb2.rabbitmq.com/rabbitmq-server/{{ grains["os"].lower() }}/{{ grains["oscodename"] }} {{ grains["oscodename"] }} main
46-
46+
47+
{#- Optional: enable all feature flags on the currently-installed broker before any
48+
upgrade. Required before upgrading to a major RabbitMQ version that drops support
49+
for older feature-flag states. Safe no-op on fresh installs (onlyif skips when the
50+
broker is not yet up). #}
51+
{%- if pillar["rabbitmq"].get("enable_all_feature_flag", False) %}
52+
rabbit_enable_feature_flag:
53+
cmd.run:
54+
- name: rabbitmqctl enable_feature_flag all
55+
- onlyif: rabbitmqctl status 2>/dev/null | grep -q Uptime
56+
{%- endif %}
57+
4758
rabbit_pkg:
4859
{%- if "version" in pillar["rabbitmq"] %}
4960
{%- if pillar["rabbitmq"]["version"] == "latest" %}
@@ -116,6 +127,45 @@ rabbit_service_4:
116127
cmd.run:
117128
- name: systemctl daemon-reload
118129
130+
{#- Download community plugin .ez files BEFORE the broker restart, so all .ez referenced
131+
by /etc/rabbitmq/enabled_plugins are on disk when the broker starts. Otherwise
132+
rabbitmq-plugins enable for any other plugin fails with plugins_not_found for the
133+
community ones that are already recorded as enabled. #}
134+
{%- for plugin in pillar["rabbitmq"].get("plugins", []) %}
135+
{%- if plugin is mapping %}
136+
rabbit_plugin_{{ loop.index }}_download:
137+
cmd.run:
138+
- name: |
139+
set -eo pipefail
140+
RMQVER=$(dpkg-query -W -f='${Version}' rabbitmq-server | sed -E 's/^[0-9]+://;s/[-+~].*//')
141+
DEST_DIR="/usr/lib/rabbitmq/lib/rabbitmq_server-${RMQVER}/plugins"
142+
DEST_FILE="${DEST_DIR}/$(basename '{{ plugin["url"] }}')"
143+
# remove stale copies of this plugin from both the active versioned dir and the
144+
# system-wide /usr/lib/rabbitmq/plugins dir. -type f leaves bundled-plugin dirs
145+
# like amqp10_client-3.13.6/ untouched. ! -path "$DEST_FILE" preserves our target
146+
# if it is already at the requested version.
147+
# Default pattern is the safe `<name>-<digit>*` (versioned files only). Set
148+
# `force_cleanup: True` on the pillar entry to widen it to `<name>-*` so any file
149+
# with the plugin name prefix is removed (e.g. `<name>.bak`, `<name>-foo`).
150+
for D in "$DEST_DIR" "/usr/lib/rabbitmq/plugins"; do
151+
[ -d "$D" ] || continue
152+
{%- if plugin.get("force_cleanup", False) %}
153+
find "$D" -maxdepth 1 -type f -name '{{ plugin["name"] }}-*' ! -path "$DEST_FILE" -print -delete
154+
{%- else %}
155+
find "$D" -maxdepth 1 -type f -name '{{ plugin["name"] }}-[0-9]*' ! -path "$DEST_FILE" -print -delete
156+
{%- endif %}
157+
done
158+
if [ ! -f "$DEST_FILE" ]; then
159+
curl -fsSL -o "${DEST_FILE}.tmp" '{{ plugin["url"] }}'
160+
mv "${DEST_FILE}.tmp" "$DEST_FILE"
161+
chmod 644 "$DEST_FILE"
162+
echo "downloaded $(basename '{{ plugin["url"] }}')"
163+
fi
164+
- require:
165+
- pkg: rabbit_pkg
166+
{%- endif %}
167+
{%- endfor %}
168+
119169
rabbit_service_5:
120170
cmd.run:
121171
- name: service rabbitmq-server restart
@@ -138,9 +188,17 @@ rabbit_fix_salt_module:
138188
timeout 2m bash -c 'salt-call saltutil.refresh_modules'; } || true
139189
140190
{%- for plugin in pillar["rabbitmq"].get("plugins", []) %}
191+
{%- if plugin is mapping %}
192+
rabbit_plugin_{{ loop.index }}:
193+
rabbitmq_plugin.enabled:
194+
- name: '{{ plugin["name"] }}'
195+
- require:
196+
- cmd: rabbit_plugin_{{ loop.index }}_download
197+
{%- else %}
141198
rabbit_plugin_{{ loop.index }}:
142199
rabbitmq_plugin.enabled:
143200
- name: {{ plugin }}
201+
{%- endif %}
144202
{%- endfor %}
145203
146204
{% endif %}

rabbitmq/pillar.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
rabbitmq:
44
version: 4.2.3 # optional, specific version or latest, if omitted, install latest first, then keep it without upgrades
55
#local_ip: 1.2.3.4 # optional, make sure /etc/hosts has short hostname resolution to this local IP, otherwise rabbitmq will not start, if omitted, 127.0.1.1 is used
6+
#enable_all_feature_flag: True # optional, runs `rabbitmqctl enable_feature_flag all` BEFORE the package upgrade on the currently-installed broker; required before upgrading across major versions that drop older feature-flag states. Skipped silently on fresh installs.
67
config: # optional
78
- 'key = val' # see https://github.com/rabbitmq/rabbitmq-server/blob/v3.7.x/docs/rabbitmq.conf.example, each item is copied as is
89
admin:
@@ -14,6 +15,17 @@ rabbitmq:
1415
acme_account: example.com # acme state account
1516
plugins: # optional
1617
- rabbitmq_management
18+
# community plugin, downloaded as .ez and enabled. Pick a URL whose plugin version
19+
# matches RabbitMQ major.minor (RabbitMQ 4.2.x -> plugin 4.2.x). The on-disk filename
20+
# is derived from the URL via basename. Removing the entry stops managing it; disable
21+
# manually on the host if needed.
22+
# Cleanup of stale copies runs in both /usr/lib/rabbitmq/lib/rabbitmq_server-<VER>/plugins
23+
# and /usr/lib/rabbitmq/plugins. By default only files matching the safe pattern
24+
# `<name>-<digit>*` are removed. Set force_cleanup: True to widen the pattern to
25+
# `<name>-*` so files like `<name>.bak` or `<name>-foo` are also removed.
26+
- name: rabbitmq_delayed_message_exchange
27+
url: https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v4.2.0/rabbitmq_delayed_message_exchange-4.2.0.ez
28+
#force_cleanup: True # optional, default False
1729
vhosts:
1830
- name: vhost_a
1931
present: True

0 commit comments

Comments
 (0)