Skip to content

Commit

Permalink
Improve docker control
Browse files Browse the repository at this point in the history
  • Loading branch information
rbonghi committed Jan 23, 2025
1 parent d269c3f commit 2e79d05
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 60 deletions.
20 changes: 8 additions & 12 deletions src/nanosaur/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,6 @@ def docker_start(platform, params: Params, args):
print(TerminalFormatter.color_text(f"robot {robot.name} starting", color='green'))
# Create a DockerClient object with the docker-compose file
nanosaur_compose = DockerClient(compose_files=[docker_compose_path])
if args.build:
print(TerminalFormatter.color_text("Building the Docker container...", color='green'))
nanosaur_compose.compose.build()
# Start the container in detached mode
try:
nanosaur_compose.compose.up(detach=args.detach)
Expand All @@ -115,27 +112,26 @@ def docker_simulator_start(platform, params: Params, args):
nanosaur_home_path = get_nanosaur_home()
# Create the full file path
docker_compose_path = os.path.join(nanosaur_home_path, docker_compose)
robot = RobotList.get_robot(params)

# Check which simulation tool is selected
if 'simulation_tool' not in params:
print(TerminalFormatter.color_text("No simulation tool selected. Please run simulation set first.", color='red'))
return False

# Start the container in detached mode
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
# Create a DockerClient object with the docker-compose file
nanosaur_compose = DockerClient(compose_files=[docker_compose_path])
if len(nanosaur_compose.compose.ps()) > 0:
print(TerminalFormatter.color_text(f"The robot {robot.name} is already running.", color='red'))
return False

#if len(nanosaur_compose.compose.ps()) > 0:
# print(TerminalFormatter.color_text(f"The robot {robot.name} is already running.", color='red'))
# return False
# Build env file
if not is_env_file():
print(TerminalFormatter.color_text("Creating the environment file...", color='green'))
build_env_file(params)
print(TerminalFormatter.color_text(f"robot {robot.name} starting", color='green'))
# Start the container in detached mode
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
print(TerminalFormatter.color_text(f"Simulator {simulation_tool} starting", color='green'))
try:
nanosaur_compose.compose.up(services=[f'nanosaur_{simulation_tool}'])
nanosaur_compose.compose.up(services=[f'nanosaur_{simulation_tool}'], recreate=False)
except DockerException as e:
print(TerminalFormatter.color_text(f"Error starting the simulation tool: {e}", color='red'))
return False
Expand Down
6 changes: 5 additions & 1 deletion src/nanosaur/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ def main():
# Create the argument parser
parser = argparse.ArgumentParser(
description="Nanosaur CLI - A command-line interface for the Nanosaur package.")


parser.add_argument('--mode', type=str, help="Specify the mode of operation")
# Define subcommands
subparsers = parser.add_subparsers(dest='command', help="Available commands")

Expand Down Expand Up @@ -200,6 +201,9 @@ def main():

# Parse the arguments
args = parser.parse_args()
# Override mode if provided as an argument
if args.mode:
params.set('mode', args.mode, save=False)

# Handle subcommands without a specific type
if args.command in ['workspace', 'ws'] and not args.workspace_type:
Expand Down
23 changes: 16 additions & 7 deletions src/nanosaur/ros.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@

ISAAC_ROS_DISTRO_SUFFIX = "ros2_humble"
NANOSAUR_DOCKERFILE_SUFFIX = "nanosaur"
NANOSAUR_DOCKER_PACKAGE_ROBOT = "nanosaur"
NANOSAUR_DOCKER_PACKAGE_SIMULATION = "simulation"
NANOSAUR_DOCKER_PACKAGE_PERCEPTION = "perception"


def run_dev_script(params, host_workspace_path, workspace_path):
Expand Down Expand Up @@ -262,27 +265,29 @@ def run_colcon_build(folder_path) -> bool:
return False


def deploy_docker_simulation(image_name: str, simulation_ws_path: str, all: bool) -> bool:
def deploy_docker_simulation(docker_user: str, simulation_ws_path: str, all: bool) -> bool:
# Get the path to the nanosaur_simulations package
nanosaur_simulations_path = os.path.join(simulation_ws_path, 'src', 'nanosaur_simulations')
# Build Gazebo sim docker
tag_image = f"{docker_user}/{NANOSAUR_DOCKER_PACKAGE_SIMULATION}:gazebo"
try:
print(TerminalFormatter.color_text("Building Gazebo Docker image...", color='magenta', bold=True))
print(TerminalFormatter.color_text(f"Building Gazebo simulation docker image {tag_image}", color='magenta', bold=True))
docker.build(
get_nanosaur_home(),
file=f"{nanosaur_simulations_path}/Dockerfile.gazebo",
tags="nanosaur/gazebo"
tags=tag_image
)
except DockerException as e:
print(TerminalFormatter.color_text(f"Error building Gazebo Docker image: {e}", color='red'))
return False
# Build the Docker image for nanosaur bridge
tag_image = f"{docker_user}/{NANOSAUR_DOCKER_PACKAGE_ROBOT}:simulation"
try:
print(TerminalFormatter.color_text("Building Nanosaur Docker image...", color='magenta', bold=True))
print(TerminalFormatter.color_text(f"Building Nanosaur robot docker image {tag_image}", color='magenta', bold=True))
docker.build(
get_nanosaur_home(),
file=f"{nanosaur_simulations_path}/Dockerfile.nanosaur",
tags=image_name
tags=tag_image
)
except DockerException as e:
print(TerminalFormatter.color_text(f"Error building Nanosaur Docker image: {e}", color='red'))
Expand All @@ -292,20 +297,24 @@ def deploy_docker_simulation(image_name: str, simulation_ws_path: str, all: bool
return True


def deploy_docker_perception(image_name: str, perception_ws_path: str) -> bool:
def deploy_docker_perception(docker_user: str, perception_ws_path: str) -> bool:
nanosaur_perception_path = os.path.join(perception_ws_path, 'src', 'nanosaur_perception')

src_folders = [
os.path.join(get_nanosaur_home(), 'shared_src'),
os.path.join(perception_ws_path, 'src')
]

tag_image = f"{docker_user}/{NANOSAUR_DOCKER_PACKAGE_PERCEPTION}:simulation"
print(TerminalFormatter.color_text(f"Building Nanosaur robot docker image {tag_image}", color='magenta', bold=True))

try:
os.chdir(nanosaur_perception_path)
print(f"Changed directory to: {nanosaur_perception_path}")

ws_dir_list = '--ws-src ' + ' --ws-src '.join(src_folders)
command = f"scripts/docker_build.sh {ws_dir_list} --image-name {image_name}"

command = f"scripts/docker_build.sh {ws_dir_list} --image-name {tag_image}"

process = subprocess.Popen(
command,
Expand Down
7 changes: 4 additions & 3 deletions src/nanosaur/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,11 @@ def simulation_start_debug(platform, params: Params, args):


def simulation_start(platform, params: Params, args):
if args.debug:
debug_mode = args.debug or params.get('mode', '') in ['Maintainer', 'Raffo']
if debug_mode:
return simulation_start_debug(platform, params, args)
else:
return docker_simulator_start(platform, params, args)
# Run from docker container
return docker_simulator_start(platform, params, args)


def simulation_set(platform, params: Params, args):
Expand Down
72 changes: 42 additions & 30 deletions src/nanosaur/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
NANOSAUR_MAIN_GITHUB_URL = 'https://github.com/rnanosaur/nanosaur.git'
NANOSAUR_MAIN_BRANCH = 'nanosaur2'

NANOSAUR_DOCKER_USER = 'nanosaur'

class Robot:

Expand Down Expand Up @@ -224,30 +225,6 @@ def print_all_robots(self, robot_idx=None):
print(f" {TerminalFormatter.color_text(f'Robot {idx}:', bold=True)} {robot}")


def is_env_file():
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
return os.path.exists(env_path)


def build_env_file(params):
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
# Get current robot running
robot = RobotList.get_robot(params)
uid = os.getuid()
gid = os.getgid()
# Create a .env file and save UID and GID
with open(env_path, 'w') as env_file:
env_file.write(f"USER_UID={uid}\n")
env_file.write(f"USER_GID={gid}\n")
# Check which simulation tool is selected and save it in the .env file
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
env_file.write(f"SIMULATION={simulation_tool}\n")
# Pass robot ros commands
env_file.write(f"COMMANDS={robot.config_to_ros()}\n")


class Params:

@classmethod
Expand Down Expand Up @@ -310,28 +287,63 @@ def get_params_file() -> str:
def get(self, key, default=None):
return getattr(self, key, default)

def set(self, key, value):
def set(self, key, value, save=True):
self._params_dict[key] = value
setattr(self, key, value)
# save the new value in the file
self.save()
if save:
self.save()
return value

def items(self):
return self._params_dict.items()


def is_env_file():
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
return os.path.exists(env_path)


def build_env_file(params):
nanosaur_home_path = get_nanosaur_home()
env_path = os.path.join(nanosaur_home_path, '.env')
# Get current robot running
robot = RobotList.get_robot(params)
uid = os.getuid()
gid = os.getgid()
# Create a .env file and save UID and GID
with open(env_path, 'w') as env_file:
env_file.write(f"USER_UID={uid}\n")
env_file.write(f"USER_GID={gid}\n")
# Check which simulation tool is selected and save it in the .env file
simulation_tool = params['simulation_tool'].lower().replace(' ', '_')
env_file.write(f"SIMULATION={simulation_tool}\n")
# Pass robot ros commands
env_file.write(f"COMMANDS={robot.config_to_ros()}\n")


def package_info(params: Params, verbose: bool):
# Print version information
nanosaur_website = TerminalFormatter.clickable_link(NANOSAUR_WEBSITE_URL)
print(f"{TerminalFormatter.color_text('Nanosaur website:', bold=True)} {nanosaur_website}")
nanosaur_home_folder = TerminalFormatter.clickable_link(get_nanosaur_home())
print(f"{TerminalFormatter.color_text('Nanosaur home:', bold=True)} {nanosaur_home_folder}")
if verbose:
print(f"{TerminalFormatter.color_text('Nanosaur package:', bold=True)} {__version__}")
nanosaur_branch = params.get('nanosaur_branch', NANOSAUR_MAIN_BRANCH)
print(f"{TerminalFormatter.color_text('Nanosaur version (branch):', bold=True)} {nanosaur_branch}")
# Print verbose information
def print_verbose_info(params):
nanosaur_docker_user = get_nanosaur_docker_user(params)
nanosaur_docker_home = TerminalFormatter.clickable_link(f"https://hub.docker.com/u/{nanosaur_docker_user}")
print(f"{TerminalFormatter.color_text('Nanosaur Docker Hub:', bold=True)} {nanosaur_docker_home}")
config_file_path = TerminalFormatter.clickable_link(Params.get_params_file())
print(f"{TerminalFormatter.color_text('Nanosaur config file:', bold=True)} {config_file_path}")
nanosaur_branch = params.get('nanosaur_branch', NANOSAUR_MAIN_BRANCH)
print(f"{TerminalFormatter.color_text('Nanosaur version (branch):', bold=True)} {nanosaur_branch}")
print(f"{TerminalFormatter.color_text('Nanosaur package:', bold=True)} {__version__}")
if verbose:
print_verbose_info(params)

def get_nanosaur_docker_user(params: Params) -> str:
return params.get('nanosaur_docker_user', NANOSAUR_DOCKER_USER)


def get_nanosaur_raw_github_url(params: Params) -> str:
Expand Down
11 changes: 4 additions & 7 deletions src/nanosaur/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from nanosaur.prompt_colors import TerminalFormatter
from nanosaur import ros
from nanosaur.simulation import simulation_robot_start_debug
from nanosaur.utilities import Params, get_nanosaur_raw_github_url, get_nanosaur_home, create_nanosaur_home, require_sudo_password
from nanosaur.utilities import Params, get_nanosaur_raw_github_url, get_nanosaur_home, create_nanosaur_home, require_sudo_password, get_nanosaur_docker_user
import inquirer


Expand All @@ -48,10 +48,6 @@
DEFAULT_WORKSPACE_ROBOT = 'robot_ws'
DEFAULT_WORKSPACE_DEVELOPER = 'ros_ws'

DEFAULT_DOCKER_PERCEPTION_IMAGE = 'nanosaur/perception'
DEFAULT_DOCKER_SIMULATION_IMAGE = 'nanosaur/simulation'
DEFAULT_DOCKER_ROBOT_IMAGE = 'nanosaur/nanosaur'


def workspaces_info(params: Params, verbose: bool):
"""Print information about the workspaces."""
Expand Down Expand Up @@ -258,10 +254,11 @@ def debug(platform, params: Params, args):


def deploy(platform, params: Params, args):
nanosaur_docker_user = get_nanosaur_docker_user(params)
""" Deploy the workspace """
workspace_actions = {
'simulation': lambda: ros.deploy_docker_simulation(DEFAULT_DOCKER_SIMULATION_IMAGE, get_workspace_path(params, 'ws_simulation_name'), args.all),
'perception': lambda: ros.deploy_docker_perception(DEFAULT_DOCKER_PERCEPTION_IMAGE, get_workspace_path(params, 'ws_perception_name')),
'simulation': lambda: ros.deploy_docker_simulation(nanosaur_docker_user, get_workspace_path(params, 'ws_simulation_name'), args.all),
'perception': lambda: ros.deploy_docker_perception(nanosaur_docker_user, get_workspace_path(params, 'ws_perception_name')),
}
if args.all:
print(TerminalFormatter.color_text("Deploying all workspaces", bold=True))
Expand Down

0 comments on commit 2e79d05

Please sign in to comment.