diff --git a/Cargo.lock b/Cargo.lock index 8c23f6fb7..0c1e6c9b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,7 +333,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "agent" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-debug-echo", "akri-discovery-utils", @@ -402,7 +402,7 @@ dependencies = [ [[package]] name = "akri-debug-echo" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-shared", @@ -422,7 +422,7 @@ dependencies = [ [[package]] name = "akri-discovery-utils" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-shared", "anyhow", @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "akri-onvif" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-shared", @@ -472,7 +472,7 @@ dependencies = [ [[package]] name = "akri-opcua" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-shared", @@ -496,7 +496,7 @@ dependencies = [ [[package]] name = "akri-shared" -version = "0.9.5" +version = "0.10.0" dependencies = [ "anyhow", "async-trait", @@ -525,7 +525,7 @@ dependencies = [ [[package]] name = "akri-udev" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "anyhow", @@ -999,7 +999,7 @@ checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "controller" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-shared", "anyhow", @@ -1199,7 +1199,7 @@ dependencies = [ [[package]] name = "debug-echo-discovery-handler" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-debug-echo", "akri-discovery-utils", @@ -2473,7 +2473,7 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "onvif-discovery-handler" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-onvif", @@ -2523,7 +2523,7 @@ dependencies = [ [[package]] name = "opcua-discovery-handler" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-opcua", @@ -4152,7 +4152,7 @@ dependencies = [ [[package]] name = "udev-discovery-handler" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-discovery-utils", "akri-udev", @@ -4163,7 +4163,7 @@ dependencies = [ [[package]] name = "udev-video-broker" -version = "0.9.5" +version = "0.10.0" dependencies = [ "akri-shared", "env_logger", @@ -4171,6 +4171,7 @@ dependencies = [ "log", "prometheus 0.12.0", "prost", + "regex", "rscam", "tokio 1.26.0", "tonic", @@ -4433,7 +4434,7 @@ dependencies = [ [[package]] name = "webhook-configuration" -version = "0.9.5" +version = "0.10.0" dependencies = [ "actix", "actix-rt 2.7.0", diff --git a/agent/Cargo.toml b/agent/Cargo.toml index d17c7e7d6..93f60abc2 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "agent" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring ", ""] edition = "2018" rust-version = "1.63.0" diff --git a/agent/src/util/device_plugin_builder.rs b/agent/src/util/device_plugin_builder.rs index 4bf39ea40..821333d4f 100644 --- a/agent/src/util/device_plugin_builder.rs +++ b/agent/src/util/device_plugin_builder.rs @@ -33,6 +33,7 @@ pub trait DevicePluginBuilderInterface: Send + Sync { async fn build_device_plugin( &self, instance_name: String, + instance_id: String, config: &Configuration, shared: bool, instance_map: InstanceMap, @@ -65,6 +66,7 @@ impl DevicePluginBuilderInterface for DevicePluginBuilder { async fn build_device_plugin( &self, instance_name: String, + instance_id: String, config: &Configuration, shared: bool, instance_map: InstanceMap, @@ -85,6 +87,7 @@ impl DevicePluginBuilderInterface for DevicePluginBuilder { mpsc::channel(DEVICE_PLUGIN_SERVER_ENDER_CHANNEL_CAPACITY); let device_plugin_service = DevicePluginService { instance_name: instance_name.clone(), + instance_id: instance_id.clone(), endpoint: device_endpoint.clone(), config: config.spec.clone(), config_name: config.metadata.name.clone().unwrap(), diff --git a/agent/src/util/device_plugin_service.rs b/agent/src/util/device_plugin_service.rs index 3e2e5ffe5..5d39e7625 100644 --- a/agent/src/util/device_plugin_service.rs +++ b/agent/src/util/device_plugin_service.rs @@ -73,6 +73,8 @@ pub type InstanceMap = Arc>>; pub struct DevicePluginService { /// Instance CRD name pub instance_name: String, + /// Instance hash id + pub instance_id: String, /// Socket endpoint pub endpoint: String, /// Instance's Configuration @@ -280,6 +282,8 @@ impl DevicePluginService { kube_interface: Arc, ) -> Result, Status> { let mut container_responses: Vec = Vec::new(); + // suffix to add to each device property + let device_property_suffix = self.instance_id.to_uppercase(); for request in requests.into_inner().container_requests { trace!( @@ -288,6 +292,7 @@ impl DevicePluginService { request, ); let mut akri_annotations = HashMap::new(); + let mut akri_device_properties = HashMap::new(); for device_usage_id in request.devices_i_ds { trace!( "internal_allocate - for Instance {} processing request for device usage slot id {}", @@ -300,6 +305,20 @@ impl DevicePluginService { device_usage_id.clone(), ); + // add suffix _ to each device property + let converted_properties = self + .device + .properties + .iter() + .map(|(key, value)| { + ( + format!("{}_{}", key, &device_property_suffix), + value.to_string(), + ) + }) + .collect::>(); + akri_device_properties.extend(converted_properties); + if let Err(e) = try_update_instance_device_usage( &device_usage_id, &self.node_name, @@ -324,7 +343,7 @@ impl DevicePluginService { // Successfully reserved device_usage_slot[s] for this node. // Add response to list of responses let broker_properties = - get_all_broker_properties(&self.config.broker_properties, &self.device.properties); + get_all_broker_properties(&self.config.broker_properties, &akri_device_properties); let response = build_container_allocate_response( broker_properties, akri_annotations, @@ -829,11 +848,12 @@ mod device_plugin_service_tests { add_to_instance_map: bool, ) -> (DevicePluginService, DevicePluginServiceReceivers) { let path_to_config = "../test/yaml/config-a.yaml"; + let instance_id = "b494b6"; let kube_akri_config_yaml = fs::read_to_string(path_to_config).expect("Unable to read file"); let kube_akri_config: Configuration = serde_yaml::from_str(&kube_akri_config_yaml).unwrap(); let config_name = kube_akri_config.metadata.name.as_ref().unwrap(); - let device_instance_name = get_device_instance_name("b494b6", config_name); + let device_instance_name = get_device_instance_name(instance_id, config_name); let unique_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH); let device_endpoint: String = format!( "{}-{}.sock", @@ -863,6 +883,7 @@ mod device_plugin_service_tests { }; let dps = DevicePluginService { instance_name: device_instance_name, + instance_id: instance_id.to_uppercase(), endpoint: device_endpoint, config: kube_akri_config.spec.clone(), config_name: config_name.to_string(), @@ -1379,7 +1400,10 @@ mod device_plugin_service_tests { assert_eq!(broker_envs.get("RESOLUTION_HEIGHT").unwrap(), "600"); // Check that Device properties are set as env vars by checking for // property of device created in `create_device_plugin_service` - assert_eq!(broker_envs.get("DEVICE_LOCATION_INFO").unwrap(), "endpoint"); + assert_eq!( + broker_envs.get("DEVICE_LOCATION_INFO_B494B6").unwrap(), + "endpoint" + ); assert!(device_plugin_service_receivers .list_and_watch_message_receiver .try_recv() diff --git a/agent/src/util/discovery_operator.rs b/agent/src/util/discovery_operator.rs index 2c5cd6b74..63c552e17 100644 --- a/agent/src/util/discovery_operator.rs +++ b/agent/src/util/discovery_operator.rs @@ -327,6 +327,7 @@ impl DiscoveryOperator { if let Err(e) = device_plugin_builder .build_device_plugin( instance_name, + id, &self.config, shared, instance_map, @@ -1146,7 +1147,7 @@ pub mod tests { mock_device_plugin_builder .expect_build_device_plugin() .times(2) - .returning(move |_, _, _, _, _| Ok(())); + .returning(move |_, _, _, _, _, _| Ok(())); discovery_operator .handle_discovery_results( mock_kube_interface, diff --git a/controller/Cargo.toml b/controller/Cargo.toml index 62a9f79a0..624c0fadf 100644 --- a/controller/Cargo.toml +++ b/controller/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "controller" -version = "0.9.5" +version = "0.10.0" authors = ["", ""] edition = "2018" rust-version = "1.63.0" diff --git a/deployment/helm/Chart.yaml b/deployment/helm/Chart.yaml index cdbef896a..0e49d0152 100644 --- a/deployment/helm/Chart.yaml +++ b/deployment/helm/Chart.yaml @@ -15,9 +15,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.9.5 +version: 0.10.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 0.9.5 +appVersion: 0.10.0 diff --git a/discovery-handler-modules/debug-echo-discovery-handler/Cargo.toml b/discovery-handler-modules/debug-echo-discovery-handler/Cargo.toml index d279698a5..2ebabfef5 100644 --- a/discovery-handler-modules/debug-echo-discovery-handler/Cargo.toml +++ b/discovery-handler-modules/debug-echo-discovery-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "debug-echo-discovery-handler" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handler-modules/onvif-discovery-handler/Cargo.toml b/discovery-handler-modules/onvif-discovery-handler/Cargo.toml index 814eda212..12c41173b 100644 --- a/discovery-handler-modules/onvif-discovery-handler/Cargo.toml +++ b/discovery-handler-modules/onvif-discovery-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "onvif-discovery-handler" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handler-modules/opcua-discovery-handler/Cargo.toml b/discovery-handler-modules/opcua-discovery-handler/Cargo.toml index 93ec5b90e..8e966aa77 100644 --- a/discovery-handler-modules/opcua-discovery-handler/Cargo.toml +++ b/discovery-handler-modules/opcua-discovery-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opcua-discovery-handler" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handler-modules/udev-discovery-handler/Cargo.toml b/discovery-handler-modules/udev-discovery-handler/Cargo.toml index 1fa5af2cc..12f4f0c73 100644 --- a/discovery-handler-modules/udev-discovery-handler/Cargo.toml +++ b/discovery-handler-modules/udev-discovery-handler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "udev-discovery-handler" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handlers/debug-echo/Cargo.toml b/discovery-handlers/debug-echo/Cargo.toml index ae23498c3..69dde96f8 100644 --- a/discovery-handlers/debug-echo/Cargo.toml +++ b/discovery-handlers/debug-echo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-debug-echo" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handlers/onvif/Cargo.toml b/discovery-handlers/onvif/Cargo.toml index 75a8073cd..7a5b6a862 100644 --- a/discovery-handlers/onvif/Cargo.toml +++ b/discovery-handlers/onvif/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-onvif" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handlers/opcua/Cargo.toml b/discovery-handlers/opcua/Cargo.toml index cf15301b6..7a8cd4b4b 100644 --- a/discovery-handlers/opcua/Cargo.toml +++ b/discovery-handlers/opcua/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-opcua" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-handlers/udev/Cargo.toml b/discovery-handlers/udev/Cargo.toml index 59ed95b24..ee56b4bc7 100644 --- a/discovery-handlers/udev/Cargo.toml +++ b/discovery-handlers/udev/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-udev" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/discovery-utils/Cargo.toml b/discovery-utils/Cargo.toml index 904f19971..fa022f7de 100644 --- a/discovery-utils/Cargo.toml +++ b/discovery-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-discovery-utils" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring "] edition = "2018" rust-version = "1.63.0" diff --git a/samples/brokers/onvif-video-broker/Akri.cs b/samples/brokers/onvif-video-broker/Akri.cs index 42fb35d35..e06ab89a5 100644 --- a/samples/brokers/onvif-video-broker/Akri.cs +++ b/samples/brokers/onvif-video-broker/Akri.cs @@ -1,9 +1,12 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using System.Xml.XPath; @@ -38,6 +41,11 @@ private static string PostSoapRequest(String requestUri, String action, String s private const String GET_PROFILES_SOAP = @""; private const String GET_STREAMING_URI_SOAP_TEMPLATE = @"RTP-UnicastRTSP{0}"; + // Regular expression pattern of environment variables that hold OPC UA DiscoveryURL + // The pattern is ONVIF_DEVICE_SERVICE_URL_ followed by 6 digit digest. e.g. + // ONVIF_DEVICE_SERVICE_URL_123456, ONVIF_DEVICE_SERVICE_URL_ABCDEF + private const string OnvifDeviceServiceUrlLabelPattern = "ONVIF_DEVICE_SERVICE_URL_[A-F0-9]{6,6}$"; + private static string GetMediaUrl(String device_service_url) { var servicesResult = PostSoapRequest( @@ -97,9 +105,29 @@ private static string GetStreamingUri(String media_url, String profile_token) return streaming_uri; } + private static List GetDeviceServiceUrls() + { + var values = new List(); + foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) + { + if (Regex.IsMatch(de.Key.ToString(), OnvifDeviceServiceUrlLabelPattern)) + { + values.Add(de.Value.ToString()); + } + } + return values; + } + public static string GetRtspUrl() { - var device_service_url = Environment.GetEnvironmentVariable("ONVIF_DEVICE_SERVICE_URL"); + // Get the first found Onvif device service url and use it + var device_service_urls = GetDeviceServiceUrls(); + foreach(var url in device_service_urls) + { + Console.WriteLine("xxx url={0}", url); + } + return ""; + var device_service_url = (device_service_urls.Count != 0) ? device_service_urls[0] : ""; if (string.IsNullOrEmpty(device_service_url)) { throw new ArgumentNullException("ONVIF_DEVICE_SERVICE_URL undefined"); diff --git a/samples/brokers/onvif-video-broker/README.md b/samples/brokers/onvif-video-broker/README.md index a11fb4a5f..61fba93cd 100644 --- a/samples/brokers/onvif-video-broker/README.md +++ b/samples/brokers/onvif-video-broker/README.md @@ -13,5 +13,5 @@ interface. ``` 1. Run the broker, passing in the ONVIF service URL for the camera it should pull frames from. ```sh - ONVIF_DEVICE_SERVICE_URL=http://10.1.2.3:1000/onvif/device_service dotnet run + ONVIF_DEVICE_SERVICE_URL_ABCDEF=http://10.1.2.3:1000/onvif/device_service dotnet run ``` \ No newline at end of file diff --git a/samples/brokers/opcua-monitoring-broker/Program.cs b/samples/brokers/opcua-monitoring-broker/Program.cs index b4893f7ac..9788e3904 100644 --- a/samples/brokers/opcua-monitoring-broker/Program.cs +++ b/samples/brokers/opcua-monitoring-broker/Program.cs @@ -31,8 +31,11 @@ using Opc.Ua.Client; using Opc.Ua.Configuration; using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Security.Cryptography.X509Certificates; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; @@ -59,8 +62,10 @@ public enum ExitCode : int public class Program { - // Name of environment variable that holds OPC UA DiscoveryURL - public const string OpcuaDiscoveryUrlLabel = "OPCUA_DISCOVERY_URL"; + // Regular expression pattern of environment variables that hold OPC UA DiscoveryURL + // The pattern is OPCUA_DISCOVERY_URL_ followed by 6 digit digest. e.g. + // OPCUA_DISCOVERY_URL_123456, OPCUA_DISCOVERY_URL_ABCDEF + public const string OpcuaDiscoveryUrlLabelPattern = "OPCUA_DISCOVERY_URL_[A-F0-9]{6,6}$"; // Name of environment variable that holds the identifier for the OPC UA Node to monitor public const string IdentifierLabel = "IDENTIFIER"; // Name of environment variable that holds the amespaceIndex for the OPC UA Node to monitor @@ -76,16 +81,17 @@ static int Main(string[] args) { Console.WriteLine(".NET Core OPC UA Console Client Start"); - // Get OPC UA Server DiscoveryURL and store it as a global variable - OpcuaServerDiscoveryURL = Environment.GetEnvironmentVariable(OpcuaDiscoveryUrlLabel); + // Get the first found OPC UA Server DiscoveryURL and store it as a global variable + var serverDiscoveryUrls = GetServerDiscoveryUrls(); + OpcuaServerDiscoveryURL = (serverDiscoveryUrls.Count != 0) ? serverDiscoveryUrls[0] : ""; if (string.IsNullOrEmpty(OpcuaServerDiscoveryURL)) { - throw new ArgumentNullException("Unable to get OPC UA endpoint in environment variable {0}", OpcuaDiscoveryUrlLabel); + throw new ArgumentNullException(OpcuaDiscoveryUrlLabelPattern, "Unable to get OPC UA endpoint in environment variable"); } string OpcuaNodeIdentifier = Environment.GetEnvironmentVariable(IdentifierLabel); if (string.IsNullOrEmpty(OpcuaNodeIdentifier)) { - throw new ArgumentNullException("Unable to get OPC UA endpoint in environment variable {0}", IdentifierLabel); + throw new ArgumentNullException(IdentifierLabel, "Unable to get OPC UA endpoint in environment variable"); } ushort OpcuaNamespaceIndex = ushort.Parse(Environment.GetEnvironmentVariable(NamespaceIndexLabel)); MonitoredNodeId = new NodeId(OpcuaNodeIdentifier, OpcuaNamespaceIndex); @@ -101,6 +107,19 @@ public static IHostBuilder CreateHostBuilder(string[] args) => { webBuilder.UseStartup(); }); + + private static List GetServerDiscoveryUrls() + { + var values = new List(); + foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) + { + if (Regex.IsMatch(de.Key.ToString(), OpcuaDiscoveryUrlLabelPattern)) + { + values.Add(de.Value.ToString()); + } + } + return values; + } } // gRPC Server which serves the latest value of the monitored Node. It assumes the value is integer type. diff --git a/samples/brokers/opcua-monitoring-broker/README.md b/samples/brokers/opcua-monitoring-broker/README.md index aeaf0a8f8..75bfd7a41 100644 --- a/samples/brokers/opcua-monitoring-broker/README.md +++ b/samples/brokers/opcua-monitoring-broker/README.md @@ -14,5 +14,5 @@ dotnet build 1. Run, passing in the OPC UA Discovery URL for the OPC UA Server it should connect to and the identifier and namespace index of the OPC UA Node to monitor. ```sh -IDENTIFIER="Thermometer_Temperature" NAMESPACE_INDEX="2" OPCUA_DISCOVERY_URL="opc.tcp://10.2.3.4:4556/Some/Path" dotnet run +IDENTIFIER="Thermometer_Temperature" NAMESPACE_INDEX="2" OPCUA_DISCOVERY_URL_ABCDEF="opc.tcp://10.2.3.4:4556/Some/Path" dotnet run ``` diff --git a/samples/brokers/udev-video-broker/Cargo.toml b/samples/brokers/udev-video-broker/Cargo.toml index b484c382e..4b4b80f72 100644 --- a/samples/brokers/udev-video-broker/Cargo.toml +++ b/samples/brokers/udev-video-broker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "udev-video-broker" -version = "0.9.5" +version = "0.10.0" authors = ["Kate Goldenring ", ""] edition = "2018" rust-version = "1.63.0" @@ -14,6 +14,7 @@ lazy_static = "1.4" log = "0.4.3" prometheus = { version = "0.12.0", features = ["process"] } prost = "0.8.0" +regex = "1" tokio = { version = "1.0.1", features = ["time", "fs", "macros", "signal"] } tonic = "0.5.2" rscam = "0.5.5" diff --git a/samples/brokers/udev-video-broker/README.md b/samples/brokers/udev-video-broker/README.md index 08e594a50..186aae4fa 100644 --- a/samples/brokers/udev-video-broker/README.md +++ b/samples/brokers/udev-video-broker/README.md @@ -1,6 +1,6 @@ # Udev USB Video Broker Sample broker for for Akri's [end to end demo](https://docs.akri.sh/demos/usb-camera-demo). It pulls video frames from -the USB camera with device node `UDEV_DEVNODE`. Then, it serves these frames over a gRPC interface. The [streaming +the USB camera with device node specified by the environment variable named with `UDEV_DEVNODE_<6 digit digest>`. Then, it serves these frames over a gRPC interface. The [streaming application](../../apps/video-streaming-app) provides an example streaming service that displays frames served by this broker. @@ -12,5 +12,5 @@ broker. 1. Build and run, connecting to the USB camera at `/dev/video0` ```sh cd akri/samples/brokers/udev-video-broker - UDEV_DEVNODE=/dev/video0 cargo run + UDEV_DEVNODE_123456=/dev/video0 cargo run ``` \ No newline at end of file diff --git a/samples/brokers/udev-video-broker/src/main.rs b/samples/brokers/udev-video-broker/src/main.rs index 407186b68..80db37e45 100644 --- a/samples/brokers/udev-video-broker/src/main.rs +++ b/samples/brokers/udev-video-broker/src/main.rs @@ -7,6 +7,7 @@ use akri_shared::{ }; use log::{info, trace}; use prometheus::IntCounter; +use regex::Regex; use tokio::signal; use util::{camera_capturer, camera_service}; @@ -16,8 +17,8 @@ lazy_static! { .expect("akri_frame_count cannot be created"); } -/// devnode environment variable id -pub const UDEV_DEVNODE_LABEL_ID: &str = "UDEV_DEVNODE"; +/// regular expression pattern of devnode environment variable id +pub const UDEV_DEVNODE_LABEL_ID_PATTERN: &str = "UDEV_DEVNODE_[A-F0-9]{6,6}$"; #[tokio::main] async fn main() -> Result<(), Box> { @@ -53,12 +54,27 @@ async fn main() -> Result<(), Box fn get_video_devnode(env_var_query: &impl EnvVarQuery) -> String { trace!("get_video_devnode - getting devnode"); - let device_devnode = env_var_query - .get_env_var(UDEV_DEVNODE_LABEL_ID) + // query UDEV_DEVNODE_LABEL_ID prefix and use the first one found as device_devnode + lazy_static! { + static ref RE: Regex = Regex::new(UDEV_DEVNODE_LABEL_ID_PATTERN).unwrap(); + } + let device_devnodes = env_var_query + .get_env_vars() + .iter() + .filter_map(|(n, v)| { + if RE.is_match(n) { + Some(v.clone()) + } else { + None + } + }) + .collect::>(); + let device_devnode = device_devnodes + .first() .expect("devnode not set in envrionment variable"); trace!("get_video_devnode - found devnode {}", device_devnode); - device_devnode + device_devnode.to_string() } #[cfg(test)] @@ -72,12 +88,16 @@ mod tests { let mut mock_query = MockEnvVarQuery::new(); const MOCK_DEVICE_PATH: &str = "/dev/video0"; - + const MOCK_DEVICE_ENV_VAR_NAME: &str = "UDEV_DEVNODE_123456"; mock_query - .expect_get_env_var() + .expect_get_env_vars() .times(1) - .withf(move |name: &str| name == UDEV_DEVNODE_LABEL_ID) - .returning(move |_| Ok(MOCK_DEVICE_PATH.to_string())); + .returning(move || { + vec![( + MOCK_DEVICE_ENV_VAR_NAME.to_string(), + MOCK_DEVICE_PATH.to_string(), + )] + }); assert_eq!(MOCK_DEVICE_PATH.to_string(), get_video_devnode(&mock_query)); } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 149ef6490..3906083a0 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "akri-shared" -version = "0.9.5" +version = "0.10.0" authors = [""] edition = "2018" rust-version = "1.63.0" diff --git a/shared/src/os/env_var.rs b/shared/src/os/env_var.rs index bb80dc5ca..384eee2d0 100644 --- a/shared/src/os/env_var.rs +++ b/shared/src/os/env_var.rs @@ -5,6 +5,7 @@ use std::{env, env::VarError}; #[automock] pub trait EnvVarQuery { fn get_env_var(&self, name: &'static str) -> Result; + fn get_env_vars(&self) -> Vec<(String, String)>; } pub struct ActualEnvVarQuery; @@ -24,4 +25,10 @@ impl EnvVarQuery for ActualEnvVarQuery { fn get_env_var(&self, name: &'static str) -> Result { env::var(name) } + + fn get_env_vars(&self) -> Vec<(String, String)> { + env::vars() + .map(|(n, v)| (n, v)) + .collect::>() + } } diff --git a/test/shared_test_code.py b/test/shared_test_code.py index b4d599141..4d30cad17 100644 --- a/test/shared_test_code.py +++ b/test/shared_test_code.py @@ -160,8 +160,9 @@ def check_pods_running(v1, pod_label_selector, count): def check_broker_pods_env_var(pods): kubectl_cmd = get_kubectl_command() for pod in pods: - if os.system('{} exec -i {} -- /bin/sh -c "printenv | grep ^DEBUG_ECHO_DESCRIPTION={} | wc -l | grep -v 0"'.format(kubectl_cmd, pod.metadata.name, DEBUG_ECHO_DESCRIPTIONS_PREFIX)): - print("Could not find a DEBUG_ECHO_DESCRIPTION environment variable in broker Pod {}".format(pod.metadata.name)) + # expect the environment variable from akri instance suffixed with a 6 digest hash id + if os.system('{} exec -i {} -- /bin/sh -c "printenv | grep \'^DEBUG_ECHO_DESCRIPTION_[A-F0-9]\\{{6,6\\}}={}\' | wc -l | grep -v 0"'.format(kubectl_cmd, pod.metadata.name, DEBUG_ECHO_DESCRIPTIONS_PREFIX)): + print("Could not find a DEBUG_ECHO_DESCRIPTION_ environment variable in broker Pod {}".format(pod.metadata.name)) return False if os.system('{} exec -i {} -- /bin/sh -c "printenv | grep ^{}={}$ | wc -l | grep -v 0"'.format(kubectl_cmd, pod.metadata.name, PROPERTIES_RESOLUTION_WIDTH_KEY, PROPERTIES_RESOLUTION_WIDTH_VALUE)): print("Could not find a {} environment variable in broker Pod {}".format(pod.metadata.name)) diff --git a/version.txt b/version.txt index b0bb87854..78bc1abd1 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.9.5 +0.10.0 diff --git a/webhooks/validating/configuration/Cargo.toml b/webhooks/validating/configuration/Cargo.toml index ce834b2d0..dde6b15fb 100644 --- a/webhooks/validating/configuration/Cargo.toml +++ b/webhooks/validating/configuration/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webhook-configuration" -version = "0.9.5" +version = "0.10.0" authors = ["DazWilkin "] edition = "2018" rust-version = "1.63.0"