Skip to content

Commit 981b892

Browse files
authored
Merge pull request #4451 from tpurschke/develop
Hotfix - missing disposed userConfig ExtRequest module
2 parents 67c4814 + a8bfaf2 commit 981b892

9 files changed

Lines changed: 228 additions & 75 deletions

File tree

roles/api/handlers/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
listen: "api handler"
2222

2323
- name: restore from backup
24-
include_tasks: hasura-install.yml
24+
include_tasks: ../tasks/rollback-restore.yml
2525
listen: "api handler"
2626

2727
- name: fail message

roles/api/tasks/hasura-install.yml

Lines changed: 157 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,21 @@
5252
when:
5353
- installation_mode == "upgrade"
5454
- hasura_admin_secret_file.stat.exists
55-
- api_use_existing_hasura_on_upgrade | default(false) | bool
5655

57-
- name: set hasura admin secret from existing file
56+
- name: cache existing hasura admin secret during upgrade
5857
set_fact:
59-
api_hasura_admin_secret: "{{ existing_hasura_admin_secret['content'] | b64decode | trim }}"
58+
api_existing_hasura_admin_secret: "{{ existing_hasura_admin_secret['content'] | b64decode | trim }}"
6059
when:
6160
- installation_mode == "upgrade"
6261
- hasura_admin_secret_file.stat.exists
62+
63+
- name: set hasura admin secret from existing file
64+
set_fact:
65+
api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}"
66+
when:
67+
- installation_mode == "upgrade"
6368
- api_use_existing_hasura_on_upgrade | default(false) | bool
69+
- api_existing_hasura_admin_secret is defined
6470

6571
- name: set static hasura admin pwd for test purposes only
6672
set_fact:
@@ -76,22 +82,30 @@
7682
when:
7783
- api_hasura_admin_secret is not defined
7884

79-
- name: write hasura admin password to secrets directory
80-
copy:
81-
content: "{{ api_hasura_admin_secret }}\n"
82-
dest: "{{ fworch_secrets_dir }}/hasura_admin_pwd"
83-
mode: "0600"
84-
owner: "{{ fworch_user }}"
85-
group: "{{ fworch_group }}"
86-
become: true
87-
when:
88-
- installation_mode != "upgrade" or not (api_use_existing_hasura_on_upgrade | default(false) | bool) or not hasura_admin_secret_file.stat.exists
89-
9085
- name: check for existing hasura cli file
9186
stat:
9287
path: "{{ api_hasura_cli_bin }}"
9388
register: api_cli_check
9489

90+
- name: detect whether upgrade can reuse installed Hasura
91+
set_fact:
92+
api_hasura_upgrade_reuse_possible: >-
93+
{{
94+
installation_mode == "upgrade"
95+
and (api_existing_service_name | default('') | length > 0)
96+
and hasura_admin_secret_file.stat.exists
97+
}}
98+
99+
- name: fail when Hasura upgrade reuse was requested without reusable state
100+
fail:
101+
msg: >-
102+
Hasura upgrade fallback requires both an installed Hasura service unit and the existing
103+
{{ fworch_secrets_dir }}/hasura_admin_pwd secret file.
104+
when:
105+
- installation_mode == "upgrade"
106+
- api_use_existing_hasura_on_upgrade | default(false) | bool
107+
- not api_hasura_upgrade_reuse_possible | bool
108+
95109
- name: build GitHub auth header
96110
set_fact:
97111
api_github_auth_header: "{{ {'Authorization': 'Bearer ' ~ api_github_token} if api_github_token is defined else {} }}"
@@ -149,6 +163,50 @@
149163
when: hasura_cli_asset_id is defined
150164
rescue:
151165
- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download after asset API failure
166+
block:
167+
- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download after asset API failure
168+
get_url:
169+
url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-{{ linux_architecture }}"
170+
dest: "{{ api_hasura_cli_bin }}"
171+
force: true
172+
timeout: "{{ github_download_timeout }}"
173+
mode: "0755"
174+
owner: "{{ fworch_user }}"
175+
group: "{{ fworch_group }}"
176+
environment: "{{ proxy_env }}"
177+
register: api_hasura_cli_download_fallback
178+
retries: 3
179+
delay: 5
180+
until: api_hasura_cli_download_fallback is succeeded
181+
become: true
182+
rescue:
183+
- name: fall back to existing Hasura after CLI download failure during upgrade
184+
set_fact:
185+
api_use_existing_hasura_on_upgrade: true
186+
api_service_name: "{{ api_existing_service_name }}"
187+
api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}"
188+
when: api_hasura_upgrade_reuse_possible | bool
189+
190+
- name: show Hasura CLI upgrade fallback decision
191+
debug:
192+
msg: >-
193+
Hasura CLI download failed during upgrade, reusing the installed Hasura service/container
194+
and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred
195+
until a later run can download the required artifacts.
196+
when: api_hasura_upgrade_reuse_possible | bool
197+
198+
- name: fail when Hasura CLI download fails without upgrade fallback
199+
fail:
200+
msg: >-
201+
Failed to download Hasura CLI and no existing Hasura service is available for upgrade fallback.
202+
when: not api_hasura_upgrade_reuse_possible | bool
203+
when:
204+
- not api_cli_check.stat.exists
205+
- not api_use_existing_hasura_on_upgrade | default(false) | bool
206+
207+
- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download when no asset id was found
208+
block:
209+
- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download when no asset id was found
152210
get_url:
153211
url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-{{ linux_architecture }}"
154212
dest: "{{ api_hasura_cli_bin }}"
@@ -163,25 +221,28 @@
163221
delay: 5
164222
until: api_hasura_cli_download_fallback is succeeded
165223
become: true
166-
when:
167-
- not api_cli_check.stat.exists
168-
- not api_use_existing_hasura_on_upgrade | default(false) | bool
169-
170-
- name: download {{ api_hasura_version }} hasura cli binary via direct GitHub download when no asset id was found
171-
get_url:
172-
url: "https://github.com/hasura/graphql-engine/releases/download/{{ api_hasura_version }}/cli-hasura-linux-{{ linux_architecture }}"
173-
dest: "{{ api_hasura_cli_bin }}"
174-
force: true
175-
timeout: "{{ github_download_timeout }}"
176-
mode: "0755"
177-
owner: "{{ fworch_user }}"
178-
group: "{{ fworch_group }}"
179-
environment: "{{ proxy_env }}"
180-
register: api_hasura_cli_download_fallback
181-
retries: 3
182-
delay: 5
183-
until: api_hasura_cli_download_fallback is succeeded
184-
become: true
224+
rescue:
225+
- name: fall back to existing Hasura after direct CLI download failure during upgrade
226+
set_fact:
227+
api_use_existing_hasura_on_upgrade: true
228+
api_service_name: "{{ api_existing_service_name }}"
229+
api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}"
230+
when: api_hasura_upgrade_reuse_possible | bool
231+
232+
- name: show Hasura direct CLI upgrade fallback decision
233+
debug:
234+
msg: >-
235+
Direct Hasura CLI download failed during upgrade, reusing the installed Hasura service/container
236+
and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred
237+
until a later run can download the required artifacts.
238+
when: api_hasura_upgrade_reuse_possible | bool
239+
240+
- name: fail when direct Hasura CLI download fails without upgrade fallback
241+
fail:
242+
msg: >-
243+
Failed to download Hasura CLI from the release URL and no existing Hasura service is available
244+
for upgrade fallback.
245+
when: not api_hasura_upgrade_reuse_possible | bool
185246
when:
186247
- not api_cli_check.stat.exists
187248
- not api_use_existing_hasura_on_upgrade | default(false) | bool
@@ -198,6 +259,69 @@
198259
- not api_cli_check.stat.exists
199260
- not api_use_existing_hasura_on_upgrade | default(false) | bool
200261

262+
- name: set Hasura image reuse mode
263+
set_fact:
264+
api_reuse_existing_hasura_image: >-
265+
{{
266+
installation_mode == "upgrade"
267+
and (api_use_existing_hasura_on_upgrade | default(false) | bool)
268+
and api_hasura_keep_existing_container | default(true) | bool
269+
}}
270+
271+
- name: set Hasura systemd dependencies
272+
set_fact:
273+
api_hasura_systemd_after: >-
274+
{{
275+
['network.target', 'remote-fs.target', 'nss-lookup.target']
276+
+ (['postgresql.service'] if 'databaseserver' in group_names else [])
277+
}}
278+
279+
- name: ensure Hasura image is present
280+
block:
281+
- name: ensure Hasura image is present
282+
containers.podman.podman_image:
283+
name: "{{ api_hasura_image }}"
284+
state: present
285+
environment: "{{ proxy_env }}"
286+
become: true
287+
rescue:
288+
- name: fall back to existing Hasura image after pull failure during upgrade
289+
set_fact:
290+
api_use_existing_hasura_on_upgrade: true
291+
api_reuse_existing_hasura_image: true
292+
api_service_name: "{{ api_existing_service_name }}"
293+
api_hasura_admin_secret: "{{ api_existing_hasura_admin_secret }}"
294+
when: api_hasura_upgrade_reuse_possible | bool
295+
296+
- name: show Hasura image upgrade fallback decision
297+
debug:
298+
msg: >-
299+
Hasura image pull failed during upgrade, reusing the installed Hasura service/container
300+
and continuing with metadata-only upgrade steps. Docker-to-Podman migration is deferred
301+
until a later run can download the required artifacts.
302+
when: api_hasura_upgrade_reuse_possible | bool
303+
304+
- name: fail when Hasura image pull fails without upgrade fallback
305+
fail:
306+
msg: >-
307+
Failed to pull Hasura image {{ api_hasura_image }} and no existing Hasura service is available
308+
for upgrade fallback.
309+
when: not api_hasura_upgrade_reuse_possible | bool
310+
when:
311+
- not api_reuse_existing_hasura_image | bool
312+
- api_rollback_is_running | default(false) | bool == false
313+
314+
- name: write hasura admin password to secrets directory
315+
copy:
316+
content: "{{ api_hasura_admin_secret }}\n"
317+
dest: "{{ fworch_secrets_dir }}/hasura_admin_pwd"
318+
mode: "0600"
319+
owner: "{{ fworch_user }}"
320+
group: "{{ fworch_group }}"
321+
become: true
322+
when:
323+
- installation_mode != "upgrade" or not (api_use_existing_hasura_on_upgrade | default(false) | bool) or not hasura_admin_secret_file.stat.exists
324+
201325
- name: set hasura env variable
202326
set_fact:
203327
hasura_env:
@@ -226,33 +350,6 @@
226350
var: hasura_env
227351
when: debug_level > '1'
228352

229-
- name: set Hasura image reuse mode
230-
set_fact:
231-
api_reuse_existing_hasura_image: >-
232-
{{
233-
installation_mode == "upgrade"
234-
and (api_use_existing_hasura_on_upgrade | default(false) | bool)
235-
and api_hasura_keep_existing_container | default(true) | bool
236-
}}
237-
238-
- name: set Hasura systemd dependencies
239-
set_fact:
240-
api_hasura_systemd_after: >-
241-
{{
242-
['network.target', 'remote-fs.target', 'nss-lookup.target']
243-
+ (['postgresql.service'] if 'databaseserver' in group_names else [])
244-
}}
245-
246-
- name: ensure Hasura image is present
247-
containers.podman.podman_image:
248-
name: "{{ api_hasura_image }}"
249-
state: present
250-
environment: "{{ proxy_env }}"
251-
become: true
252-
when:
253-
- not api_reuse_existing_hasura_image | bool
254-
- api_rollback_is_running | default(false) | bool == false
255-
256353
- name: write Hasura env file for Podman
257354
copy:
258355
dest: "{{ api_env_file }}"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
- name: collect installed Hasura service unit candidates for rollback
2+
stat:
3+
path: "/lib/systemd/system/{{ item }}.service"
4+
loop: "{{ [api_service_name] + (api_legacy_service_names | default([])) }}"
5+
register: api_restore_service_unit_candidates
6+
become: true
7+
8+
- name: pick Hasura service name for rollback restore
9+
set_fact:
10+
api_restore_service_name: >-
11+
{{
12+
(
13+
api_restore_service_unit_candidates.results
14+
| selectattr('stat.exists')
15+
| map(attribute='item')
16+
| list
17+
| first
18+
) | default(api_service_name)
19+
}}
20+
21+
- name: clear Hasura service failed state during rollback
22+
command: "systemctl reset-failed {{ api_restore_service_name }}"
23+
become: true
24+
failed_when: false
25+
26+
- name: start Hasura service during rollback
27+
ansible.builtin.systemd:
28+
name: "{{ api_restore_service_name }}"
29+
state: started
30+
enabled: true
31+
daemon_reload: true
32+
become: true
33+
failed_when: false

roles/lib/files/FWO.Report/ReportAppRules.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public ReportAppRules(ReportRules reportRules, ModellingFilter modellingFilter)
2424
{
2525
this.modellingFilter = modellingFilter;
2626
}
27-
27+
2828
public override async Task Generate(int elementsPerFetch, ApiConnection apiConnection, Func<ReportData, Task> callback, CancellationToken ct)
2929
{
3030
await base.Generate(elementsPerFetch, apiConnection, callback, ct);

roles/middleware/files/FWO.Middleware.Server/Controllers/ExternalRequestController.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,9 @@ public async Task<bool> Post([FromBody] ExternalRequestAddParameters parameters)
4040
{
4141
if (parameters.TicketId > 0)
4242
{
43-
GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true);
44-
UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish });
45-
46-
ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection);
43+
using GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true);
44+
using UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish });
45+
using ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection);
4746
return await extRequestHandler.SendFirstRequest(parameters.TicketId);
4847
}
4948
else
@@ -70,9 +69,9 @@ public async Task<bool> Change([FromBody] ExternalRequestPatchStateParameters pa
7069
{
7170
if (parameters.ExtRequestId > 0)
7271
{
73-
GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true);
74-
UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish });
75-
ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection);
72+
using GlobalConfig GlobalConfig = await GlobalConfig.ConstructAsync(apiConnection, true);
73+
using UserConfig userConfig = new(GlobalConfig, apiConnection, new() { Language = GlobalConst.kEnglish });
74+
using ExternalRequestHandler extRequestHandler = new(userConfig, apiConnection);
7675
ExternalRequest extRequest = new()
7776
{
7877
Id = parameters.ExtRequestId,

roles/middleware/files/FWO.Middleware.Server/Controllers/RuleController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,19 +404,19 @@ public bool IsInRange(IPAddress ipAddress, int minPrefix, List<NetworkObject> ob
404404
{
405405
continue;
406406
}
407-
407+
408408
int rangePrefix = CommonPrefixLength(start, end);
409409

410410
if (rangePrefix < minPrefix)
411411
{
412412
break;
413413
}
414-
414+
415415
if (IsInRange(ipAddress, start, end))
416416
{
417417
return true;
418418
}
419-
419+
420420
}
421421

422422
return false;

roles/middleware/files/FWO.Middleware.Server/ExternalRequestHandler.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ protected virtual void Dispose(bool disposing)
559559
{
560560
if (disposing)
561561
{
562-
UserConfig?.Dispose();
562+
// UserConfig is caller-owned and can be reused across multiple request handling steps.
563+
// Disposing it here breaks subsequent handler instances that receive the same config.
563564
}
564565
disposed = true;
565566
}

0 commit comments

Comments
 (0)