diff --git a/dev_container b/dev_container index 759973f96..b59a73bc2 100755 --- a/dev_container +++ b/dev_container @@ -856,9 +856,31 @@ launch() { "$@" } -build_and_install_desc() { c_echo 'Build the application and install the binaries into install/ if supported +build_and_package_desc() { c_echo 'Build the debian package + Usage: ./dev_container build_and_package + View extra options with `./dev_container build_and_run_desc` ignoring run options + ' +} + +build_and_package() { + if [[ -z $1 ]]; then + c_echo "No package name provided (see ./run list_packages)" + exit 1 + fi + pkg=$(basename "$1") + shift + packages=$(${HOLOHUB_ROOT}/run list_packages | awk '{print $1}') + if [[ ! " ${packages[*]} " =~ " ${pkg} " ]]; then + c_echo "Package ${pkg} not found in list of packages: (see ./run list_packages)" + exit 1 + fi + dockerfile=$(./run get_pkg_dockerfile ${pkg}) + build_and_run $pkg --no_run --docker_file ${dockerfile} "$@" +} + +build_and_install_desc() { c_echo 'Build and install the binaries into install/ if supported Usage: ./dev_container build_and_install - View options with `./dev_container build_and_run_desc` + View extra options with `./dev_container build_and_run_desc` ignoring run options ' } @@ -1060,9 +1082,7 @@ build_and_run() { if [[ -z "${docker_file}" ]]; then docker_file=$(./run get_app_dockerfile ${app_name} ${app_language:-cpp}) fi - if [[ -n "${docker_file}" ]]; then - container_build_args+=(--docker_file ${docker_file}) - fi + container_build_args+=(--docker_file ${docker_file}) if [[ -n "${configure_args}" ]]; then extra_build_args+=" --configure-args ${configure_args}" @@ -1079,15 +1099,15 @@ build_and_run() { container_build_args+=(--img $image_name) container_launch_args+=" --img $image_name" - c_echo "Building application container..." + c_echo "Building container..." run_command ${SCRIPT_DIR}/dev_container build "${container_build_args[@]}" if [[ $build_app == 1 ]]; then - c_echo "Building application..." + c_echo "Building $app_name..." run_command ${SCRIPT_DIR}/dev_container launch $container_launch_args --docker_opts "$docker_opts" -- -c "./run build $app_name $install $parallel_jobs $extra_build_with $extra_build_args" fi if [[ $run_app == 1 ]]; then - c_echo "Launching application..." + c_echo "Launching $app_name..." run_command ${SCRIPT_DIR}/dev_container launch $container_launch_args --docker_opts "$docker_opts" -- -c "./run launch $app_name $app_language $extra_run_args" fi } @@ -1197,9 +1217,7 @@ vscode() { docker_file=$(./run get_app_dockerfile ${app_name} ${app_language:-cpp}) c_echo W "Using Dockerfile: " G "${docker_file}" fi - if [[ -n "${docker_file}" ]]; then - container_build_args+=" --docker_file ${docker_file}" - fi + container_build_args+=" --docker_file ${docker_file}" if [ -n "${app_name}" ]; then dev_container_tag+="-${app_name}" diff --git a/pkg/holoscan-networking/metadata.json b/pkg/holoscan-networking/metadata.json new file mode 100644 index 000000000..859e92bff --- /dev/null +++ b/pkg/holoscan-networking/metadata.json @@ -0,0 +1,5 @@ +{ + "package": { + "dockerfile": "operators/advanced_network/Dockerfile" + } +} diff --git a/pkg/metadata.schema.json b/pkg/metadata.schema.json new file mode 100644 index 000000000..8b3c6eade --- /dev/null +++ b/pkg/metadata.schema.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "$id": "holohub/package/v1", + "type": "object", + "properties": { + "package": { + "type": "object", + "properties": { + "dockerfile": { + "type": "string", + "description": "Path to the Dockerfile used to build this package" + } + } + } + } +} diff --git a/run b/run index db5f29c1d..f14c6683d 100755 --- a/run +++ b/run @@ -161,6 +161,64 @@ get_app_source_lang_dir() { echo -n "${holohub_app_source}" } +get_pkg_dir() { + # Get source path for a given package according to HoloHub convention. + # Usage: ./run get_pkg_dir + local pkgname="$1" + if [[ -z "${pkgname}" ]]; then + echo "Missing package name argument for get_pkg_dir" + exit 1 + fi + + holohub_pkg_source="${SCRIPT_DIR}/pkg/${pkgname}" + + # Check if the package is in a subdirectory + if [ ! -d "$holohub_pkg_source" ]; then + sub_pkg_path=$(find ${SCRIPT_DIR}/pkg -type d -name "${pkgname}") + pkg_rel_path=${sub_pkg_path#"${SCRIPT_DIR}/pkg/"} + if [[ -n "$pkg_rel_path" ]]; then + holohub_pkg_source="${SCRIPT_DIR}/pkg/${pkg_rel_path}" + fi + fi + + if [ ! -d "$holohub_pkg_source" ]; then + echo "Could not find package ${pkgname}" + exit 1 + fi + + echo -n "${holohub_pkg_source}" +} + +get_pkg_dockerfile() { + # Parse the path to a custom package Dockerfile, if provided. + # Follows the HoloHub convention: + # 1. Check the metadata.json file for a "dockerfile" entry. + # 2. Check for a Dockerfile in the package directory. + # 3. Use the default Dockerfile provided at the top level of the HoloHub repository. + # Usage: ./run get_pkg_dockerfile + local pkgname="$1" + local dockerfile_path="" + + packages=$(list_packages | awk '{print $1}') + if [[ ! " ${packages[*]} " =~ " ${pkgname} " ]]; then + echo "Package ${pkgname} not found in list of packages: (see ./run list_packages)" + exit 1 + fi + + local pkg_source_path=$(get_pkg_dir ${pkgname}) + local dockerfile_entry=$(cat "${pkg_source_path}/metadata.json" 2>/dev/null | grep "dockerfile" ) + if [[ -n "${dockerfile_entry}" ]]; then + pattern="s##${pkg_source_path}#g" + dockerfile_path=$(echo "${dockerfile_entry}" | awk -F'["]' '{ print $4 }' | sed -E ${pattern}) + elif [[ -f "${pkg_source_path}/Dockerfile" ]]; then + dockerfile_path="${pkg_source_path}/Dockerfile" + else + dockerfile_path="${SCRIPT_DIR}/Dockerfile" + fi + + echo -n "${dockerfile_path}" +} + get_app_dockerfile() { # Parse the path to a custom application Dockerfile, if provided. # Follows the HoloHub convention: diff --git a/utilities/metadata_validator.py b/utilities/metadata_validator.py index 65cb721e8..373d683d0 100644 --- a/utilities/metadata_validator.py +++ b/utilities/metadata_validator.py @@ -112,6 +112,7 @@ def validate_json_directory(directory, ignore_patterns=[], metadata_is_required: "tutorials", ignore_patterns=["template"], metadata_is_required=False ) exit_code_benchmarks = validate_json_directory("benchmarks") + exit_code_packages = validate_json_directory("pkg", metadata_is_required=False) sys.exit( max( @@ -120,5 +121,6 @@ def validate_json_directory(directory, ignore_patterns=[], metadata_is_required: exit_code_applications, exit_code_tutorials, exit_code_benchmarks, + exit_code_packages, ) )