Skip to content

Commit 6f76040

Browse files
authored
Merge pull request #7487 from freedomofpress/prep-2.12.1
SecureDrop 2.12.1
2 parents 6609753 + e1b02dd commit 6f76040

File tree

8 files changed

+162
-13
lines changed

8 files changed

+162
-13
lines changed

changelog.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 2.12.1
4+
5+
Note: this is an Admin Workstation-only release. Servers will not receive an update.
6+
7+
### Ubuntu 24.04 (Noble) upgrade
8+
9+
* Make noble-migration playbook smarter for SSH-over-Tor (#7484)
10+
* Extend reboot timeout to 600 seconds (#7484)
11+
312
## 2.12.0
413

514
### Ubuntu 24.04 (Noble) upgrade

install_files/ansible-base/group_vars/all/securedrop

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Variables that apply to both the app and monitor server go in this file
33
# If the monitor or app server need different values define the variable in
44
# hosts_vars/app.yml or host_vars/mon.yml
5-
securedrop_version: "2.12.0"
5+
securedrop_version: "2.12.1"
66
securedrop_app_code_sdist_name: "securedrop-app-code-{{ securedrop_version | replace('~', '-') }}.tar.gz"
77

88
grsecurity: true

install_files/ansible-base/roles/noble-migration/tasks/main.yml

+141-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,50 @@
11
---
22

3+
- name: Initialize
4+
set_fact:
5+
# Keep in sync with upgrade.rs
6+
stages:
7+
- 'None'
8+
- 'PendingUpdates'
9+
- 'MigrationCheck'
10+
- 'DisableApache2'
11+
- 'Backup'
12+
- 'BackupIptables'
13+
- 'Marker'
14+
- 'SuspendOSSEC'
15+
- 'ChangeAptSources'
16+
- 'AptGetUpdate'
17+
- 'AptGetFullUpgrade'
18+
- 'AptGetAutoremove'
19+
- 'RestoreIptables'
20+
- 'ReenableUnattendedUpdates'
21+
- 'ReenableOSSEC'
22+
- 'Reboot'
23+
- 'SwitchUbuntuSources'
24+
- 'IntegrityCheck'
25+
- 'ReenableApache2'
26+
- 'RemoveBackup'
27+
- 'Done'
28+
329
- name: Check host's migration state
430
ansible.builtin.slurp:
531
src: /etc/securedrop-noble-migration-state.json
632
register: migration_json
7-
ignore_errors: yes
833

9-
- name: Skip migration if already done
34+
# Note: the variable finished_state is only for debugging and human-readable output.
35+
# The finished_state_index is what must be used for logic in `when` blocks.
36+
37+
- name: Extract current state
1038
set_fact:
11-
already_finished: "{{ not migration_json.failed and (migration_json.content | b64decode | from_json)['finished'] == 'Done' }}"
39+
# slurp base64-encodes our file
40+
finished_state: "{{ (migration_json.content | b64decode | from_json)['finished'] }}"
1241

13-
- name: Perform migration
14-
when: not already_finished
42+
- name: Extract current state (2)
43+
set_fact:
44+
finished_state_index: "{{ stages.index(finished_state) }}"
45+
46+
- name: Kick off migration
47+
when: finished_state_index|int == 0
1548
block:
1649
- name: Instruct upgrade to begin
1750
ansible.builtin.copy:
@@ -48,8 +81,31 @@
4881
connect_timeout: 20
4982
sleep: 5
5083
delay: 10
51-
timeout: 300
84+
timeout: 600
85+
86+
- name: Recheck host's migration state
87+
ansible.builtin.slurp:
88+
src: /etc/securedrop-noble-migration-state.json
89+
register: migration_json
90+
91+
- name: Extract current state
92+
set_fact:
93+
# slurp base64-encodes our file
94+
finished_state: "{{ (migration_json.content | b64decode | from_json)['finished'] }}"
95+
96+
- debug:
97+
msg: "The current upgrade state is: {{ finished_state }}"
98+
99+
- name: Extract current state (2)
100+
set_fact:
101+
finished_state_index: "{{ stages.index(finished_state) }}"
102+
# Note: do not add anything after this line in this block - it will not run, because
103+
# the block is in a `when` that we just made false by updating `finished_state_index`.
52104

105+
- name: Phase 2 of migration
106+
# After PendingUpdates (index 1) but before Reboot (index 15)
107+
when: finished_state_index|int >= 1 and finished_state_index|int < 15
108+
block:
53109
# Start the systemd service manually to avoid waiting for the timer to pick it up
54110
- name: Resume upgrade systemd service
55111
ansible.builtin.systemd:
@@ -61,7 +117,7 @@
61117

62118
# Same as above, this will most likely fail as unreachable when the server
63119
# actually reboots.
64-
- name: Wait for system upgrade to noble
120+
- name: Wait for system upgrade to noble (phase 2)
65121
ansible.builtin.wait_for:
66122
path: /etc/securedrop-noble-migration-state.json
67123
search_regex: '"finished":"Reboot"'
@@ -71,13 +127,78 @@
71127
ignore_unreachable: yes
72128
ignore_errors: yes
73129

74-
- name: Wait for the second reboot
130+
- name: Wait for the second reboot (phase 2)
75131
ansible.builtin.wait_for_connection:
76132
connect_timeout: 20
77133
sleep: 5
78134
delay: 10
79-
timeout: 300
135+
timeout: 600
136+
137+
- name: Recheck host's migration state
138+
ansible.builtin.slurp:
139+
src: /etc/securedrop-noble-migration-state.json
140+
register: migration_json
141+
142+
- name: Extract current state
143+
set_fact:
144+
# slurp base64-encodes our file
145+
finished_state: "{{ (migration_json.content | b64decode | from_json)['finished'] }}"
146+
147+
- debug:
148+
msg: "The current upgrade state is: {{ finished_state }}"
80149

150+
- name: Extract current state (2)
151+
set_fact:
152+
finished_state_index: "{{ stages.index(finished_state) }}"
153+
# Note: do not add anything after this line in this block - it will not run, because
154+
# the block is in a `when` that we just made false by updating `finished_state_index`.
155+
156+
- name: Phase 2.5 of migration (for SSH-over-Tor users)
157+
# After PendingUpdates (index 1) but before Reboot (index 15)
158+
when: enable_ssh_over_tor and finished_state_index|int >= 1 and finished_state_index|int < 15
159+
block:
160+
# Same as above, this will most likely fail as unreachable when the server
161+
# actually reboots.
162+
- name: Wait for system upgrade to noble (phase 2.5)
163+
ansible.builtin.wait_for:
164+
path: /etc/securedrop-noble-migration-state.json
165+
search_regex: '"finished":"Reboot"'
166+
sleep: 5
167+
# Should finish in less than 30 minutes
168+
timeout: 1800
169+
ignore_unreachable: yes
170+
ignore_errors: yes
171+
172+
- name: Wait for the second reboot (phase 2.5)
173+
ansible.builtin.wait_for_connection:
174+
connect_timeout: 20
175+
sleep: 5
176+
delay: 10
177+
timeout: 600
178+
179+
- name: Recheck host's migration state
180+
ansible.builtin.slurp:
181+
src: /etc/securedrop-noble-migration-state.json
182+
register: migration_json
183+
184+
- name: Extract current state
185+
set_fact:
186+
# slurp base64-encodes our file
187+
finished_state: "{{ (migration_json.content | b64decode | from_json)['finished'] }}"
188+
189+
- debug:
190+
msg: "The current upgrade state is: {{ finished_state }}"
191+
192+
- name: Extract current state (2)
193+
set_fact:
194+
finished_state_index: "{{ stages.index(finished_state) }}"
195+
# Note: do not add anything after this line in this block - it will not run, because
196+
# the block is in a `when` that we just made false by updating `finished_state_index`.
197+
198+
- name: Phase 3 of migration
199+
# After Reboot (index 15) but before Done (index 20)
200+
when: finished_state_index|int >= 15 and finished_state_index|int < 20
201+
block:
81202
- name: Re-resume upgrade systemd service
82203
ansible.builtin.systemd:
83204
name: securedrop-noble-migration-upgrade
@@ -90,3 +211,14 @@
90211
search_regex: '"finished":"Done"'
91212
sleep: 5
92213
timeout: 300
214+
215+
# Instead of slurping the file again, we can set the state to done
216+
# because we just waited for it to reach that point.
217+
- name: Extract current state
218+
set_fact:
219+
finished_state: "Done"
220+
finished_state_index: 20
221+
222+
- fail:
223+
msg: "Upgrade did not successfully finish; please check the logs and documentation for more details."
224+
when: finished_state != "Done"

molecule/shared/stable.ver

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.12.0
1+
2.12.1

noble-migration/src/bin/upgrade.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const EXTRA_APT_SOURCE: &str = "EXTRA_APT_SOURCE";
3030
///
3131
/// Each stage needs to be idempotent so that it can be run multiple times
3232
/// in case it errors/crashes.
33+
///
34+
/// Keep this in sync with the version in noble-migration/tasks/main.yml
3335
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
3436
enum Stage {
3537
None,

securedrop/debian/changelog

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
securedrop (2.12.1) unstable; urgency=medium
2+
3+
* see changelog.md
4+
5+
-- SecureDrop Team <[email protected]> Mon, 31 Mar 2025 11:08:01 -0400
6+
17
securedrop (2.12.0) unstable; urgency=medium
28

39
* see changelog.md

securedrop/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
setuptools.setup(
66
name="securedrop-app-code",
7-
version="2.12.0",
7+
version="2.12.1",
88
author="Freedom of the Press Foundation",
99
author_email="[email protected]",
1010
description="SecureDrop Server",

securedrop/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.12.0"
1+
__version__ = "2.12.1"

0 commit comments

Comments
 (0)