Skip to content

Commit

Permalink
Add repo managing
Browse files Browse the repository at this point in the history
  • Loading branch information
Akm0d committed Sep 4, 2024
1 parent ae55978 commit 5bc1bb6
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 3 deletions.
144 changes: 144 additions & 0 deletions src/soluble/salt/repo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Anything higher than 20 is assumed to be ubuntu, lower than 20 is debian
DEBIAN_UBUNTU_MAJOR_RELEASE_CUTTOFF = 18

DEBIAN_REPO = "deb http://repo.saltproject.io/py3/ubuntu/{{ grains['osmajorrelease'] }}/amd64/latest {{ grains['oscodename'] }} main"
DEBIAN_KEY = "https://repo.saltproject.io/py3/ubuntu/{{ grains['osmajorrelease'] }}/amd64/latest/SALTSTACK-GPG-KEY.pub"
DEBIAN_TARGET = (
f"os_family:Debian|osmajorrelease:>={DEBIAN_UBUNTU_MAJOR_RELEASE_CUTTOFF}"
)

UBUNTU_REPO = "deb http://repo.saltproject.io/py3/debian/{{ grains['osmajorrelease'] }}/amd64/latest {{ grains['oscodename'] }} main"
UBUNTU_KEY = "https://repo.saltproject.io/py3/debian/{{ grains['osmajorrelease'] }}/amd64/latest/SALTSTACK-GPG-KEY.pub"
UBUNTU_TARGET = (
f"os_family:Debian|osmajorrelease:<{DEBIAN_UBUNTU_MAJOR_RELEASE_CUTTOFF}"
)

REDHAT_REPO = "https://repo.saltproject.io/py3/redhat/el{{ grains['osmajorrelease'] }}/x86_64/latest/"
REDHAT_KEY = "https://repo.saltproject.io/py3/redhat/el{{ grains['osmajorrelease'] }}/x86_64/latest/SALTSTACK-GPG-KEY.pub"
REDHAT_TARGET = "os_family:RedHat"

AMAZON_REPO = "https://repo.saltproject.io/py3/amazon/2/x86_64/latest/"
AMAZON_KEY = (
"https://repo.saltproject.io/py3/amazon/2/x86_64/latest/SALTSTACK-GPG-KEY.pub"
)
AMAZON_TARGET = "os:Amazon"


async def setup(hub, name: str):
"""
Add the SaltStack repository and install Salt based on the target OS.
First, target Ubuntu-based systems, then fall back to other Debian-based systems (e.g., Debian, SteamOS).
"""
# TODO this functionality is not quite ready
return
hub.log.info("Setting up SaltStack repository on target(s)...")

# Handle Ubuntu-based systems (Pop!_OS, etc.)
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.managed",
f'name="{DEBIAN_REPO}"',
f'key_url="{DEBIAN_KEY}"',
"refresh=True",
"--delimiter='|'",
target=DEBIAN_TARGET,
target_type="grain_pcre",
)

# Fallback to other Debian-based systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.managed",
f'name="{UBUNTU_REPO}"',
f'key_url="{UBUNTU_KEY}"',
"refresh=True",
"--delimiter='|'",
target=UBUNTU_TARGET,
target_type="grain_pcre",
)

# Target RedHat/CentOS systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.managed",
f'name="{REDHAT_REPO}"',
f'gpgkey="{REDHAT_KEY}"',
"gpgcheck=1",
"refresh=True",
target=REDHAT_TARGET,
target_type="grain",
)

# Target Amazon Linux systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.managed",
f'name="{AMAZON_REPO}"',
f'gpgkey="{AMAZON_KEY}"',
"gpgcheck=1",
"refresh=True",
target=AMAZON_TARGET,
target_type="grain",
)

hub.log.info("SaltStack repository set up successfully.")


async def teardown(hub, name: str):
"""
Remove the SaltStack repository based on the target OS.
First, target Ubuntu-based systems, then fall back to other Debian-based systems (e.g., Debian, SteamOS).
Finally, handle RedHat-based and Amazon Linux systems.
"""
# TODO this functionality is not quite ready
return
hub.log.info("Removing SaltStack repository from target(s)...")

# Handle Ubuntu-based systems (Pop!_OS, etc.)
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.absent",
f'name="{UBUNTU_REPO}"',
"--delimiter='|'",
target=UBUNTU_TARGET,
target_type="grain_pcre",
)

# Fallback to other Debian-based systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.absent",
f'name="{DEBIAN_REPO}"',
"--delimiter='|'",
target=DEBIAN_TARGET,
target_type="grain_pcre",
)

# Remove repository for RedHat/CentOS systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.absent",
f'name="{REDHAT_REPO}"',
target=REDHAT_TARGET,
target_type="grain",
)

# Remove repository for Amazon Linux systems
await hub.salt.ssh.run_command(
name,
"state.single",
"pkgrepo.absent",
f'name="{AMAZON_REPO}"',
target=AMAZON_TARGET,
target_type="grain",
)

hub.log.info("SaltStack repository removed successfully.")
return 0
18 changes: 15 additions & 3 deletions src/soluble/salt/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ async def run_command(
hub,
name: str,
command: str,
*,
*args,
capture_output: bool = True,
hard_fail: bool = True,
target: str = None,
target_type: str = "glob",
) -> dict[str, object]:
"""Run a salt-ssh command asynchronously, handle all prompts, and return the output."""
target = hub.soluble.RUN[name].ssh_target
if target is None:
target = hub.soluble.RUN[name].ssh_target
roster = hub.soluble.RUN[name].roster_file
escalate = hub.soluble.RUN[name].escalate
config_dir = hub.soluble.RUN[name].salt_config_dir
Expand All @@ -16,7 +19,16 @@ async def run_command(
cmd = hub.soluble.RUN[name].salt_ssh_bin
assert cmd, "Could not find salt-ssh"

full_command = f"{cmd} '{target}' --roster-file={roster} {command} --log-level={hub.OPT.pop_config.log_level} {options}"
# Add targeting logic based on the passed target_type
if target_type == "grain":
target_option = f"--grain '{target}'"
elif target_type == "grain_pcre":
target_option = f"--grain-pcre '{target}'"
else:
target_option = f"'{target}'"

full_command = f"{cmd} {target_option} --roster-file={roster} {command} --log-level={hub.OPT.pop_config.log_level} {options} {' '.join(args)}"

if capture_output:
full_command += " --no-color --out=json"
if config_dir:
Expand Down
1 change: 1 addition & 0 deletions src/soluble/soluble/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ async def setup(hub, name: str):
async def run(hub, name: str) -> int:
"""This is where a soluble plugin runs its primary function"""
hub.log.info("Soluble run")
# TODO do a salt-ssh --raw
await hub.salt.ssh.run_command(name, f"test.ping", capture_output=False)
return 0

Expand Down
6 changes: 6 additions & 0 deletions src/soluble_master/soluble/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ async def setup(hub, name: str):
f"state.single file.managed source=file://{config.master_config} name=/etc/salt/master",
)

# Set up salt repo if necessary
await hub.salt.repo.setup(name)

# Install Salt on the target
hub.log.info("Installing Salt on target(s)...")
await hub.salt.ssh.run_command(name, "state.single pkg.installed name=salt-master")
Expand Down Expand Up @@ -56,6 +59,9 @@ async def teardown(hub, name: str):
hub.log.info("Uninstalling Salt from target(s)...")
await hub.salt.ssh.run_command(name, "state.single pkg.removed name=salt-master")

# Remove the salt repo if necessary
await hub.salt.repo.teardown(name)

# Remove the master configuration file
hub.log.info("Removing master configuration from target(s)...")
await hub.salt.ssh.run_command(
Expand Down
6 changes: 6 additions & 0 deletions src/soluble_minion/soluble/minion.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ async def setup(hub, name: str):
f'state.single cmd.run name="echo {minion_id} > /etc/salt/minion_id"',
)

# Set up salt repo if necessary
await hub.salt.repo.setup(name)

# Install Salt on the target
hub.log.info("Installing Salt on target(s)...")
await hub.salt.ssh.run_command(name, "state.single pkg.installed name=salt-minion")
Expand Down Expand Up @@ -76,6 +79,9 @@ async def teardown(hub, name: str):
name, "state.single pkg.removed name=salt-minion", hard_fail=False
)

# Remove the salt repo if necessary
await hub.salt.repo.teardown(name)

# Remove the minion configuration file
hub.log.info("Removing minion configuration from target(s)...")
await hub.salt.ssh.run_command(
Expand Down

0 comments on commit 5bc1bb6

Please sign in to comment.