Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,6 @@ def _refresh_importer_node(self) -> None:

if not node.setup_secondary_node(
GIT_UBUNTU_USER_HOME_DIR,
self._node_id,
self._num_workers,
GIT_UBUNTU_SYSTEM_USER_USERNAME,
self._is_publishing_active,
self._controller_port,
Expand All @@ -335,7 +333,7 @@ def _refresh_importer_node(self) -> None:

def _start_services(self) -> None:
"""Start the services and note the result through status."""
if node.start(GIT_UBUNTU_USER_HOME_DIR):
if node.start(GIT_UBUNTU_USER_HOME_DIR, self._node_id, self._num_workers):
node_type_str = "primary" if self._is_primary else "secondary"
self.unit.status = ops.ActiveStatus(
f"Running git-ubuntu importer {node_type_str} node."
Expand All @@ -352,8 +350,10 @@ def _update_git_user_config(self) -> bool:
self.unit.status = ops.MaintenanceStatus("Updating git config for git-ubuntu user.")

if not usr.update_git_user_name(
GIT_UBUNTU_SYSTEM_USER_USERNAME, GIT_UBUNTU_GIT_USER_NAME
) or not usr.update_git_email(GIT_UBUNTU_SYSTEM_USER_USERNAME, GIT_UBUNTU_GIT_EMAIL):
GIT_UBUNTU_SYSTEM_USER_USERNAME, GIT_UBUNTU_GIT_USER_NAME, GIT_UBUNTU_USER_HOME_DIR
) or not usr.update_git_email(
GIT_UBUNTU_SYSTEM_USER_USERNAME, GIT_UBUNTU_GIT_EMAIL, GIT_UBUNTU_USER_HOME_DIR
):
self.unit.status = ops.BlockedStatus("Failed to set git user config.")
return False
return True
Expand All @@ -363,7 +363,9 @@ def _update_lpuser_config(self) -> bool:
self.unit.status = ops.MaintenanceStatus("Updating lpuser entry for git-ubuntu user.")
lpuser = self._lp_username
if lp.is_valid_lp_username(lpuser):
if not usr.update_git_ubuntu_lpuser(GIT_UBUNTU_SYSTEM_USER_USERNAME, lpuser):
if not usr.update_git_ubuntu_lpuser(
GIT_UBUNTU_SYSTEM_USER_USERNAME, lpuser, GIT_UBUNTU_USER_HOME_DIR
):
self.unit.status = ops.BlockedStatus("Failed to update lpuser config.")
return False
else:
Expand Down
67 changes: 52 additions & 15 deletions src/git_ubuntu.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@ def _get_services_list(service_folder: str) -> list[str] | None:
return service_list


def _expand_service_list_for_workers(
base_service_list: list[str],
node_id: int,
num_workers: int,
) -> list[str]:
"""Expand the base service list to include worker instances.

Args:
base_service_list: The base list of service names.
node_id: The unique ID of this node.
num_workers: The number of worker instances to set up.

Returns:
The expanded list of service names including worker instances.
"""
expanded_service_list = []

for service in base_service_list:
if "@.service" in service:
for worker_id in range(num_workers):
service_name = service.replace("@.service", f"@w{node_id}-{worker_id}")
expanded_service_list.append(service_name)
else:
expanded_service_list.append(service)

return expanded_service_list


def generate_systemd_service_string(
description: str,
service_user: str,
Expand Down Expand Up @@ -139,15 +167,15 @@ def generate_systemd_service_string(


def setup_broker_service(
local_folder: str,
home_dir: str,
user: str,
group: str,
broker_port: int = 1692,
) -> bool:
"""Set up broker systemd service file.

Args:
local_folder: The local folder to store the service in.
home_dir: The home directory of the user.
user: The user to run the service as.
group: The permissions group to run the service as.
broker_port: The network port to provide tasks to workers on.
Expand All @@ -170,11 +198,12 @@ def setup_broker_service(
wanted_by="multi-user.target",
)

return create_systemd_service_file(filename, local_folder, service_string)
services_folder = pathops.LocalPath(home_dir, "services")
return create_systemd_service_file(filename, services_folder.as_posix(), service_string)


def setup_poller_service(
local_folder: str,
home_dir: str,
user: str,
group: str,
denylist: str,
Expand All @@ -184,7 +213,7 @@ def setup_poller_service(
"""Set up poller systemd service file.

Args:
local_folder: The local folder to store the service in.
home_dir: The home directory of the user.
user: The user to run the service as.
group: The permissions group to run the service as.
denylist: The location of the package denylist.
Expand Down Expand Up @@ -219,27 +248,26 @@ def setup_poller_service(
wanted_by="multi-user.target",
)

return create_systemd_service_file(filename, local_folder, service_string)
services_folder = pathops.LocalPath(home_dir, "services")
return create_systemd_service_file(filename, services_folder.as_posix(), service_string)


def setup_worker_service(
local_folder: str,
home_dir: str,
user: str,
group: str,
worker_name: str = "",
push_to_lp: bool = True,
broker_ip: str = "127.0.0.1",
broker_port: int = 1692,
lp_credentials_filename: str = "",
https_proxy: str = "",
) -> bool:
"""Set up worker systemd file with designated worker name.
"""Set up worker systemd file.

Args:
local_folder: The local folder to store the service in.
home_dir: The home directory of the user.
user: The user to run the service as.
group: The permissions group to run the service as.
worker_name: The unique worker ID to add to the service filename.
push_to_lp: True if publishing repositories to Launchpad.
broker_ip: The IP address of the broker process' node.
broker_port: The network port that the broker provides tasks on.
Expand All @@ -249,13 +277,13 @@ def setup_worker_service(
Returns:
True if setup succeeded, False otherwise.
"""
filename = f"git-ubuntu-importer-service-worker{worker_name}.service"
filename = "git-ubuntu-importer-service-worker@.service"

publish_arg = " --no-push" if not push_to_lp else ""
broker_url = f"tcp://{broker_ip}:{broker_port}"
exec_start = f"/snap/bin/git-ubuntu importer-service-worker{publish_arg} %i {broker_url}"

environment = "PYTHONUNBUFFERED=1"
environment = f"HOME={home_dir} PYTHONUNBUFFERED=1"

if lp_credentials_filename != "":
environment = f"LP_CREDENTIALS_FILE={lp_credentials_filename} " + environment
Expand All @@ -279,14 +307,17 @@ def setup_worker_service(
wanted_by="multi-user.target",
)

return create_systemd_service_file(filename, local_folder, service_string)
services_folder = pathops.LocalPath(home_dir, "services")
return create_systemd_service_file(filename, services_folder.as_posix(), service_string)


def start_services(service_folder: str) -> bool:
def start_services(service_folder: str, node_id: int, num_workers: int) -> bool:
"""Start all git-ubuntu services and wait for startup to complete.

Args:
service_folder: The name of the folder containing the service files.
node_id: The unique ID of this node.
num_workers: The number of worker instances to start if secondary.

Returns:
True if all services were started successfully, False otherwise.
Expand All @@ -296,6 +327,8 @@ def start_services(service_folder: str) -> bool:
if service_list is None:
return False

service_list = _expand_service_list_for_workers(service_list, node_id, num_workers)

services_started = True

# Start services
Expand Down Expand Up @@ -337,6 +370,10 @@ def stop_services(service_folder: str) -> bool:
services_stopped = True

for service in service_list:
# Glob worker services
if "@.service" in service:
service = f"'{service.replace('@.service', '@*')}'"

if stop_service(service):
logger.info("Stopped service %s", service)
else:
Expand Down
45 changes: 18 additions & 27 deletions src/importer_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

def setup_secondary_node(
git_ubuntu_user_home: str,
node_id: int,
num_workers: int,
system_user: str,
push_to_lp: bool,
primary_port: int,
Expand All @@ -28,8 +26,6 @@ def setup_secondary_node(

Args:
git_ubuntu_user_home: The home directory of the git-ubuntu user.
node_id: The unique ID of this node.
num_workers: The number of worker instances to set up.
system_user: The user + group to run the services as.
push_to_lp: True if publishing repositories to Launchpad.
primary_port: The network port used for worker assignments.
Expand All @@ -40,23 +36,18 @@ def setup_secondary_node(
Returns:
True if installation succeeded, False otherwise.
"""
services_folder = pathops.LocalPath(git_ubuntu_user_home, "services")

for i in range(num_workers):
worker_name = f"{node_id}_{i}"
if not git_ubuntu.setup_worker_service(
services_folder.as_posix(),
system_user,
system_user,
worker_name,
push_to_lp,
primary_ip,
primary_port,
lp_credentials_filename,
https_proxy,
):
logger.error("Failed to setup worker %s service.", worker_name)
return False
if not git_ubuntu.setup_worker_service(
git_ubuntu_user_home,
system_user,
system_user,
push_to_lp,
primary_ip,
primary_port,
lp_credentials_filename,
https_proxy,
):
logger.error("Failed to setup worker service file.")
return False

return True

Expand All @@ -80,11 +71,9 @@ def setup_primary_node(
Returns:
True if installation succeeded, False otherwise.
"""
services_folder = pathops.LocalPath(git_ubuntu_user_home, "services")

# Setup broker service.
if not git_ubuntu.setup_broker_service(
services_folder.as_posix(),
git_ubuntu_user_home,
system_user,
system_user,
primary_port,
Expand All @@ -99,7 +88,7 @@ def setup_primary_node(

# Setup poller service.
if not git_ubuntu.setup_poller_service(
services_folder.as_posix(),
git_ubuntu_user_home,
system_user,
system_user,
denylist.as_posix(),
Expand All @@ -112,18 +101,20 @@ def setup_primary_node(
return True


def start(git_ubuntu_user_home: str) -> bool:
def start(git_ubuntu_user_home: str, node_id: int, num_workers: int) -> bool:
"""Start all git-ubuntu services and wait for their startups to complete.

Args:
git_ubuntu_user_home: The home directory of the git-ubuntu user.
node_id: The node ID of this node.
num_workers: The number of worker services to start if secondary.

Returns:
True if all services were started successfully, False otherwise.
"""
services_folder = pathops.LocalPath(git_ubuntu_user_home, "services")

if not git_ubuntu.start_services(services_folder.as_posix()):
if not git_ubuntu.start_services(services_folder.as_posix(), node_id, num_workers):
logger.error("Failed to start all services.")
return False

Expand Down
Loading
Loading