Skip to content

Commit

Permalink
more updates to include joystick support as container
Browse files Browse the repository at this point in the history
Signed-off-by: Douglas Schilling Landgraf <[email protected]>
  • Loading branch information
dougsland committed Sep 16, 2024
1 parent 81ae5ce commit 3a70946
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 154 deletions.
11 changes: 11 additions & 0 deletions etc/dbus-1/system.d/vss-dbus.conf
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Policy for the root user -->
<policy user="root">
<!-- Allow root to own and send to VehicleSignals interface -->
<allow own="com.vss_lib.VehicleSignals"/>
<allow send_destination="com.vss_lib.VehicleSignals"/>
<allow send_interface="com.vss_lib.VehicleSignals"/>
<!-- Allow root to own and send to JoystickSignals interface -->
<allow own="com.vss_lib.JoystickSignals"/>
<allow send_destination="com.vss_lib.JoystickSignals"/>
<allow send_interface="com.vss_lib.JoystickSignals"/>
</policy>

<!-- Default deny policy for other users -->
<policy context="default">
<!-- Deny ownership and sending messages to VehicleSignals interface -->
<deny own="com.vss_lib.VehicleSignals"/>
<deny send_destination="com.vss_lib.VehicleSignals"/>
<!-- Deny ownership and sending messages to JoystickSignals interface -->
<deny own="com.vss_lib.JoystickSignals"/>
<deny send_destination="com.vss_lib.JoystickSignals"/>
</policy>
</busconfig>
29 changes: 27 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
SHARE_DIR = '/usr/share/vss-lib/'
USR_LIB_DIR = '/usr/lib/vss-lib/'
DBUS_DIR = '/usr/lib/vss-lib/dbus/'
JOYSTICKS_USR_SHARE = '/usr/share/vss-lib/joysticks/'
JOYSTICKS_USR_LIB = '/usr/lib/vss-lib/joysticks/'
LOG_DIR = '/var/log/vss-lib/'
DBUS_CONF_DIR = '/etc/dbus-1/system.d/'
VSS_DBUS_SERVICE = "vss-dbus"
Expand All @@ -46,7 +48,8 @@
'client',
'dbus',
'vendor',
'vspec'
'vspec',
'containers'
]

# Function to remove the existing file and create a new one with the correct content
Expand Down Expand Up @@ -80,6 +83,8 @@ def run(self):
os.makedirs(SHARE_DIR, exist_ok=True)
os.makedirs(USR_LIB_DIR, exist_ok=True)
os.makedirs(DBUS_DIR, exist_ok=True)
os.makedirs(JOYSTICKS_USR_SHARE, exist_ok=True)
os.makedirs(JOYSTICKS_USR_LIB, exist_ok=True)
os.makedirs(LOG_DIR, exist_ok=True)
os.makedirs(ELECTRONICS_DIR, exist_ok=True)
dbus_manager_dir = os.path.join(SHARE_DIR, 'dbus-manager/')
Expand Down Expand Up @@ -128,6 +133,14 @@ def run(self):
shutil.copy('src/dbus/container_dbus_service', os.path.join(DBUS_DIR, 'container_dbus_service'))
print(f"Copied dbus service file to {DBUS_DIR}")

# Copy files to /usr/lib/vss-lib/joysticks
shutil.copy('src/joysticks/container_joysticks_service', os.path.join(JOYSTICKS_USR_LIB, 'container_joysticks_service'))
print(f"Copied joysticks service file to {JOYSTICKS_USR_LIB}")

# Copy files to /usr/share/vss-lib/joysticks
shutil.copy('usr/share/vss-lib/joysticks/ContainerFile', os.path.join(JOYSTICKS_USR_SHARE, 'ContainerFile'))
print(f"Copied joysticks service file to {JOYSTICKS_USR_SHARE}")

# Copy the D-Bus configuration file to /etc/dbus-1/system.d
shutil.copy('etc/dbus-1/system.d/vss-dbus.conf', os.path.join(DBUS_CONF_DIR, 'vss-dbus.conf'))
print(f"Copied D-Bus configuration to {DBUS_CONF_DIR}")
Expand All @@ -146,8 +159,19 @@ def run(self):
else:
print(f"Directory {electronics_source_dir} does not exist, skipping electronics files...")

# Copy files from dbus-manager into /usr/share/vss-lib/joyticks
joystick_source_dir = './usr/share/vss-lib/joysticks/'
if os.path.exists(joystick_source_dir):
for file_name in os.listdir(joystick_source_dir):
src_file = os.path.join(joystick_source_dir, file_name)
dst_file = os.path.join(dbus_manager_dir, file_name)
shutil.copy(src_file, dst_file)
print(f"Copied {file_name} to {dbus_manager_dir}")
else:
print(f"Directory {joystick_source_dir} does not exist, skipping dbus-manager files...")

# Copy files from dbus-manager into /usr/share/vss-lib/dbus-manager
dbus_manager_source_dir = 'usr/share/vss-lib/dbus-manager/'
dbus_manager_source_dir = './usr/share/vss-lib/dbus-manager/'
if os.path.exists(dbus_manager_source_dir):
for file_name in os.listdir(dbus_manager_source_dir):
src_file = os.path.join(dbus_manager_source_dir, file_name)
Expand Down Expand Up @@ -269,6 +293,7 @@ def check_fuse_overlayfs():
"pydbus",
"toml",
"pyyaml",
"invoke",
],
cmdclass={
'install': CustomInstallCommand, # Custom install command for Python files and system-wide files
Expand Down
11 changes: 0 additions & 11 deletions src/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
from vss_lib.vspec_parser import load_vspec_file
from config_loader import get_vspec_file

from joystick_controller import JoystickController


class BaseModel:
"""
Expand All @@ -29,7 +27,6 @@ class BaseModel:
def __init__(self, vendor, preference, attached_electronics):
"""
Initialize the model by loading the VSS file for the specified vendor and setting up the vehicle interface.
Also conditionally initializes the JoystickController if enable_joystick is set to True.
"""
# Load the VSS file path for the given vendor using the configuration loader
vspec_file = get_vspec_file(vendor)
Expand All @@ -56,14 +53,6 @@ def __init__(self, vendor, preference, attached_electronics):
logger.error(f"Failed to initialize VehicleSignalInterface for {vendor}: {e}")
self.vehicle_signal_interface = None

# Load the configuration file to check for joystick enablement
if self.config.get("enable_joystick", True):
logger.info("Joystick enabled by configuration.")
self.joystick_controller = JoystickController()
self.joystick_controller.listen()
else:
logger.info("Joystick not enabled in the configuration.")

# Load available signals
self.available_signals = self.load_available_signals()

Expand Down
178 changes: 178 additions & 0 deletions src/containers/podman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
import toml
from invoke import run

CONFIG_PATH = "/etc/vss-lib/vss.config"

class PodmanManager:
def __init__(self, vendor, vspec_file, containerfile):
self.vendor = vendor
self.vspec_file = vspec_file
self.containerfile = containerfile
self.config = self.load_config(CONFIG_PATH)
self.vss_lib_path = self.find_vss_lib_path()

def load_config(self, config_path):
"""
Load the VSS configuration from a TOML file.
Args:
config_path (str): Path to the configuration file.
Returns:
dict: Parsed configuration data.
"""
try:
with open(config_path, 'r') as config_file:
config = toml.load(config_file)
return config
except FileNotFoundError:
print(f"Configuration file not found: {config_path}")
sys.exit(1)
except Exception as e:
print(f"Error loading configuration file: {e}")
sys.exit(1)

def find_vss_lib_path(self):
"""
Locate the vss-lib Python site-package path.
Returns:
str: Path to the vss-lib directory.
"""
pversion = f"python{sys.version_info.major}.{sys.version_info.minor}"
site_packages_paths = [
f"/usr/local/lib/{pversion}/site-packages/vss_lib/",
f"/usr/lib/{pversion}/site-packages/vss_lib/"
]

print(f"{pversion}")
print(f"{site_packages_paths}")
for path in site_packages_paths:
if os.path.exists(path):
return path

print("vss-lib path not found.")
sys.exit(1)

def build_container(self):
"""
Build a Podman container for the specified vendor.
"""
try:
command = f"podman build -t {self.vendor}_vss_image -f {self.containerfile} ."
result = run(command, hide=True, warn=True)
if result.ok:
print(f"Container image for {self.vendor} built successfully.")
else:
print(f"Failed to build container image for {self.vendor}: {result.stderr}")
sys.exit(1)
except Exception as e:
print(f"Error building Podman container image for {self.vendor}: {e}")
sys.exit(1)

def run_container(self):
"""
Run the Podman container with vendor-specific configurations.
"""
try:
vss_spec_path = self.config.get("global", {}).get("vspec_path", "/usr/share/vss-lib")
run_command = f"""
podman run -d --replace --name {self.vendor}_vss_container \
-e STORAGE_DRIVER=vfs \
--privileged \
--log-opt max-size=50m \
--log-opt max-file=3 \
-v {vss_spec_path}:{vss_spec_path}:Z \
-v {self.vss_lib_path}:{self.vss_lib_path}:Z \
-v {self.vspec_file}:/etc/vss-lib/{self.vendor}.vspec:Z \
-v /etc/vss-lib/vss.config:/etc/vss-lib/vss.config:Z \
-v /run/dbus/system_bus_socket:/run/dbus/system_bus_socket:Z \
{self.vendor}_vss_image \
sh -c "/usr/lib/vss-lib/dbus/container_dbus_service && sleep infinity"
"""
result = run(run_command, hide=True, warn=True)
if result.ok:
print(f"Podman container for {self.vendor} started successfully.")
else:
print(f"Failed to start Podman container for {self.vendor}: {result.stderr}")
sys.exit(1)
except Exception as e:
print(f"Error running Podman container for {self.vendor}: {e}")
sys.exit(1)

def stop_container(self, container_name=None):
"""
Stop and remove the Podman container.
Args:
container_name (str): The name of the container to stop. If not provided,
it stops the vendor-specific container.
"""
if not container_name:
container_name = f"{self.vendor}_vss_container" # Default to vendor container

try:
print(f"Stopping Podman container: {container_name}")
command = f"podman stop {container_name} && podman rm {container_name}"
result = run(command, hide=True, warn=True)
if result.ok:
print(f"Podman container {container_name} stopped and removed successfully.")
else:
print(f"Failed to stop Podman container {container_name}: {result.stderr}")
except Exception as e:
print(f"Error stopping Podman container {container_name}: {e}")

def run_joystick_container(self):
"""
Run the joystick Podman container using the joystick-specific ContainerFile.
"""
try:
joystick_containerfile = "/usr/share/vss-lib/joysticks/ContainerFile"
vss_spec_path = self.config.get("global", {}).get("vspec_path", "/usr/share/vss-lib")
run_command = f"""
podman run -d --replace --name joystick_vss_container \
-e STORAGE_DRIVER=vfs \
--privileged \
--log-opt max-size=50m \
--log-opt max-file=3 \
-v {vss_spec_path}:{vss_spec_path}:Z \
-v {self.vss_lib_path}:{self.vss_lib_path}:Z \
-v {self.vspec_file}:/etc/vss-lib/{self.vendor}.vspec:Z \
-v /etc/vss-lib/vss.config:/etc/vss-lib/vss.config:Z \
-v /run/dbus/system_bus_socket:/run/dbus/system_bus_socket:Z \
joystick_vss_image \
sh -c "/usr/lib/vss-lib/dbus/joystick_dbus_service && sleep infinity"
"""
result = run(run_command, hide=True, warn=True)
if result.ok:
print(f"Podman joystick container started successfully.")
else:
print(f"Failed to start Podman joystick container: {result.stderr}")
sys.exit(1)
except Exception as e:
print(f"Error running Podman joystick container: {e}")

def get_python_site_packages_version(self):
"""
Retrieve the Python version and return the path for site-packages dynamically.
Returns:
str: The full path to /usr/lib/pythonX.Y/site-packages/vss_lib/ where X.Y is the Python version.
"""
python_version = f"python{sys.version_info.major}.{sys.version_info.minor}"
vss_lib_path = f"/usr/lib/{python_version}/site-packages/vss_lib"
return vss_lib_path
Loading

0 comments on commit 3a70946

Please sign in to comment.