Skip to content

Commit b264836

Browse files
committed
add services configuration for the ks config.
1 parent 43dd748 commit b264836

4 files changed

Lines changed: 78 additions & 0 deletions

File tree

docs/ks_config.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,21 @@ Used to configure the network.
753753
}
754754
```
755755

756+
### _"services":_ (optional)
757+
- A dictionary of systemd service names and their desired states.
758+
- The state must be one of: `enabled`, `disabled`, `masked`.
759+
- By default, `sshd` is `masked` unless explicitly enabled or disabled. This prevents it from being started automatically by other services via `Wants=` dependencies.
760+
761+
Example:
762+
```json
763+
{
764+
"services": {
765+
"sshd": "enabled",
766+
"docker": "enabled"
767+
}
768+
}
769+
```
770+
756771
### _"shadow_password":_ (optional)
757772
- Contains encrypted root password <encrypted password here>.
758773
- Short form of:

examples/ova/minimal_ks.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ packagelist_file: packages_minimal.json
3232
additional_packages:
3333
- vim
3434

35+
services:
36+
sshd: enabled
37+
3538
postinstall:
3639
# allow ssh root login
3740
- sed -i "s/\(^PermitRootLogin\)[ ]*no$/\1 yes/g" /etc/ssh/sshd_config

photon_installer/installer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Installer(object):
9595
'partition_type',
9696
'partitions',
9797
'security',
98+
'services',
9899
'network',
99100
'no_unmount',
100101
'no_clean',
@@ -713,6 +714,15 @@ def _check_install_config(self, install_config):
713714
if not key.strip():
714715
raise InstallerConfigError("Environment variable name cannot be empty or whitespace")
715716

717+
if 'services' in install_config:
718+
services = install_config['services']
719+
if not isinstance(services, dict):
720+
raise InstallerConfigError("'services' must be a dictionary of service states")
721+
allowed_states = ['enabled', 'disabled', 'masked']
722+
for service, state in services.items():
723+
if state not in allowed_states:
724+
raise InstallerConfigError(f"Invalid state '{state}' for service '{service}'. Allowed states are: {', '.join(allowed_states)}")
725+
716726
# Validate grub password_pbkdf2 format
717727
if 'grub' in install_config and 'password_pbkdf2' in install_config['grub']:
718728
password_hash = install_config['grub']['password_pbkdf2']
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# /*
2+
# * Copyright © 2026 Broadcom, Inc.
3+
# * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-only
4+
# */
5+
6+
import os
7+
8+
import commons
9+
10+
install_phase = commons.POST_INSTALL
11+
enabled = True
12+
13+
14+
def execute(installer):
15+
default_services = {}
16+
17+
# Get user-defined services from config
18+
user_services = installer.install_config.get('services', {})
19+
20+
# Merge configurations, prioritizing user_services
21+
services = default_services.copy()
22+
services.update(user_services)
23+
24+
if not services:
25+
return
26+
27+
# Map states to systemctl verbs
28+
verb_map = {
29+
'enabled': 'enable',
30+
'disabled': 'disable',
31+
'masked': 'mask'
32+
}
33+
34+
for service, state in services.items():
35+
verb = verb_map.get(state)
36+
if not verb:
37+
installer.logger.warning(f"Invalid state '{state}' for service '{service}'")
38+
continue
39+
40+
if state in ['enabled', 'disabled']:
41+
# Check if it's masked first
42+
service_link = os.path.join(installer.photon_root, f"etc/systemd/system/{service}.service")
43+
if os.path.islink(service_link) and os.readlink(service_link) == "/dev/null":
44+
installer.logger.info(f"Unmasking service '{service}' before setting state to '{state}'")
45+
installer.cmd.run_in_chroot(installer.photon_root, f"systemctl unmask {service}")
46+
47+
installer.logger.info(f"Setting service '{service}' to '{state}'")
48+
retval = installer.cmd.run_in_chroot(installer.photon_root, f"systemctl {verb} {service}")
49+
if retval != 0:
50+
raise Exception(f"Failed to set service '{service}' to '{state}' (exit code: {retval})")

0 commit comments

Comments
 (0)