Skip to content

Commit 11c4f05

Browse files
first-boot scripts: allow specifying a file name
1 parent e8c892b commit 11c4f05

5 files changed

Lines changed: 64 additions & 11 deletions

File tree

coriolis/osmorphing/base.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@
5858
run_scripts /usr/lib/coriolis/firstboot/user
5959
6060
if [ $first_error -eq 0 ]; then
61-
echo "All the scripts completed successfully, creating /var/lib/coriolis/firstboot-complete"
61+
echo "All the scripts completed successfully."
62+
echo "Creating /var/lib/coriolis/firstboot-complete"
6263
mkdir -p /var/lib/coriolis
6364
touch /var/lib/coriolis/firstboot-complete
6465
else
65-
echo "One of the scripts failed, won't create /var/lib/coriolis/firstboot-complete"
66+
echo "One of the scripts failed."
67+
echo "Won't create /var/lib/coriolis/firstboot-complete"
6668
fi
6769
6870
exit $first_error
@@ -168,8 +170,23 @@ def register_firstboot_script(
168170
self,
169171
script: str,
170172
index: int = 0,
171-
user_provided=True,
173+
user_provided: bool = True,
174+
script_filename: str | None = None,
172175
):
176+
"""Register a script to be executed during the first replica boot.
177+
178+
:param script: the script content
179+
:param index: script execution index (0-99), used as a script filename
180+
prefix. The scripts will be executed in alphabetic order,
181+
the Coriolis scripts first and then user provided scripts
182+
afterwards.
183+
:param user_provider: whether this is a Coriolis internal script
184+
(executed first) or user provided script.
185+
:param script_filename: optional script filename. The index parameter
186+
will be ignored when explicitly specifying
187+
the filename. Coriolis internal scripts should
188+
specify a filename to facilitate debugging.
189+
"""
173190
pass
174191

175192
@abc.abstractmethod
@@ -796,8 +813,10 @@ def register_firstboot_script(
796813
self,
797814
script: str,
798815
index: int = 0,
799-
user_provided=True,
816+
user_provided: bool = True,
817+
script_filename: str | None = None,
800818
):
819+
801820
if len(script) == 0:
802821
LOG.debug("Empty first-boot script, skipping...")
803822
return
@@ -806,8 +825,12 @@ def register_firstboot_script(
806825
script_dir = "/usr/lib/coriolis/firstboot/user"
807826
else:
808827
script_dir = "/usr/lib/coriolis/firstboot/service"
809-
unique_id = str(uuid.uuid4()).split("-")[0]
810-
script_path = os.path.join(script_dir, f"{index:02d}-{unique_id}.sh")
828+
829+
if not script_filename:
830+
unique_id = str(uuid.uuid4()).split("-")[0]
831+
script_filename = f"{index:02d}-{unique_id}.ps1"
832+
833+
script_path = os.path.join(script_dir, script_filename)
811834

812835
self._exec_cmd_chroot(f"mkdir -p {script_dir}")
813836
self._write_file_sudo(script_path, script)

coriolis/osmorphing/windows.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ def register_firstboot_script(
733733
self,
734734
script: str,
735735
index: int = 0,
736-
user_provided=True,
736+
user_provided: bool = True,
737+
script_filename: str | None = None,
737738
):
738739
if len(script) == 0:
739740
LOG.debug("Empty first-boot script, skipping...")
@@ -752,9 +753,10 @@ def register_firstboot_script(
752753

753754
cbslinit_base_dir = self._get_cbslinit_base_dir()
754755
script_dir = self._get_cbslinit_scripts_dir(cbslinit_base_dir)
755-
unique_id = str(uuid.uuid4()).split("-")[0]
756-
script_path = os.path.join(
757-
script_dir, f"{index:02d}-{unique_id}.ps1")
756+
if not script_filename:
757+
unique_id = str(uuid.uuid4()).split("-")[0]
758+
script_filename = f"{index:02d}-{unique_id}.ps1"
759+
script_path = os.path.join(script_dir, script_filename)
758760

759761
self._conn.exec_ps_command(f"mkdir -Force {script_dir}")
760762
utils.write_winrm_file(

coriolis/tests/integration/deployments/test_osmorphing.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ def test_os_morphing_global_script_first_boot(self):
184184
first_boot_script_path)
185185
if payload == first_boot_script:
186186
found = True
187+
if payload == "should-not-get-executed":
188+
raise AssertionError(
189+
"Linux instance contains Windows script.")
187190

188191
if not found:
189192
raise AssertionError(

coriolis/tests/osmorphing/test_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def setUp(self):
3131
},
3232
{
3333
"phase": constants.PHASE_REPLICA_FIRST_BOOT,
34-
"payload": "fist-boot-script",
34+
"payload": "first-boot-script",
3535
},
3636
]
3737

coriolis/tests/osmorphing/test_windows.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,3 +964,28 @@ def test_register_firstboot_script(self, mock_uuid, mock_write_winrm_file):
964964
self.morphing_tools._conn,
965965
"C:\\Cloudbase-Init\\LocalScripts/61-37c27abd.ps1",
966966
mock_script)
967+
968+
@mock.patch.object(windows.utils, 'write_winrm_file')
969+
@mock.patch("uuid.uuid4")
970+
def test_register_firstboot_script_explicit_fname(
971+
self,
972+
mock_uuid,
973+
mock_write_winrm_file,
974+
):
975+
mock_uuid.return_value = "37c27abd-85ff-4cb8-8d31-4e7067e145ab"
976+
mock_script = "mock-script"
977+
script_filename = "test-filename.ps1"
978+
979+
self.morphing_tools.register_firstboot_script(
980+
mock_script,
981+
index=10,
982+
user_provided=True,
983+
script_filename=script_filename,
984+
)
985+
986+
self.morphing_tools._conn.exec_ps_command.assert_called_once_with(
987+
"mkdir -Force C:\\Cloudbase-Init\\LocalScripts")
988+
mock_write_winrm_file.assert_called_once_with(
989+
self.morphing_tools._conn,
990+
f"C:\\Cloudbase-Init\\LocalScripts/{script_filename}",
991+
mock_script)

0 commit comments

Comments
 (0)