From c969ada452da2f0982d64bfa97c55270d2169f80 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 9 Jan 2025 10:54:19 -0800 Subject: [PATCH 1/3] UID2-4719 change azure cc starting process --- scripts/aws/ec2.py | 27 ++-- scripts/azure-cc/Dockerfile | 35 ++++-- scripts/azure-cc/azureEntryPoint.py | 189 ++++++++++++++++++++++++++++ scripts/confidential_compute.py | 5 +- 4 files changed, 230 insertions(+), 26 deletions(-) create mode 100644 scripts/azure-cc/azureEntryPoint.py diff --git a/scripts/aws/ec2.py b/scripts/aws/ec2.py index ee47f4556..f3bf15947 100644 --- a/scripts/aws/ec2.py +++ b/scripts/aws/ec2.py @@ -51,7 +51,8 @@ def get_meta_url(cls) -> str: class EC2(ConfidentialCompute): def __init__(self): - super().__init__() + self.configs: AWSConfidentialComputeConfig = {} + def __get_aws_token(self) -> str: """Fetches a temporary AWS EC2 metadata token.""" @@ -74,34 +75,32 @@ def __get_current_region(self) -> str: except requests.RequestException as e: raise RuntimeError(f"Failed to fetch region: {e}") - def __validate_aws_specific_config(self, secret): - if "enclave_memory_mb" in secret or "enclave_cpu_count" in secret: + def __validate_aws_specific_config(self): + if "enclave_memory_mb" in self.configs or "enclave_cpu_count" in self.configs: max_capacity = self.__get_max_capacity() min_capacity = {"enclave_memory_mb": 11000, "enclave_cpu_count" : 2 } for key in ["enclave_memory_mb", "enclave_cpu_count"]: - if int(secret.get(key, 0)) > max_capacity.get(key): - raise ValueError(f"{key} value ({secret.get(key, 0)}) exceeds the maximum allowed ({max_capacity.get(key)}).") - if min_capacity.get(key) > int(secret.get(key, 10**9)): - raise ValueError(f"{key} value ({secret.get(key, 0)}) needs to be higher than the minimum required ({min_capacity.get(key)}).") + if int(self.configs.get(key, 0)) > max_capacity.get(key): + raise ValueError(f"{key} value ({self.configs.get(key, 0)}) exceeds the maximum allowed ({max_capacity.get(key)}).") + if min_capacity.get(key) > int(self.configs.get(key, 10**9)): + raise ValueError(f"{key} value ({self.configs.get(key, 0)}) needs to be higher than the minimum required ({min_capacity.get(key)}).") - def _get_secret(self, secret_identifier: str) -> AWSConfidentialComputeConfig: + def _set_secret(self, secret_identifier: str) -> None: """Fetches a secret value from AWS Secrets Manager and adds defaults""" - def add_defaults(configs: Dict[str, any]) -> AWSConfidentialComputeConfig: + def add_defaults(configs: Dict[str, any]) -> None: """Adds default values to configuration if missing.""" default_capacity = self.__get_max_capacity() configs.setdefault("enclave_memory_mb", default_capacity["enclave_memory_mb"]) configs.setdefault("enclave_cpu_count", default_capacity["enclave_cpu_count"]) configs.setdefault("debug_mode", False) - return configs region = self.__get_current_region() print(f"Running in {region}") client = boto3.client("secretsmanager", region_name=region) try: - secret = add_defaults(json.loads(client.get_secret_value(SecretId=secret_identifier)["SecretString"])) - self.__validate_aws_specific_config(secret) - return secret + add_defaults(json.loads(client.get_secret_value(SecretId=secret_identifier)["SecretString"])) + self.__validate_aws_specific_config() except NoCredentialsError as _: raise MissingInstanceProfile(self.__class__.__name__) except ClientError as _: @@ -210,7 +209,7 @@ def __run_nitro_enclave(self): def run_compute(self) -> None: """Main execution flow for confidential compute.""" secret_manager_key = self.__get_secret_name_from_userdata() - self.configs = self._get_secret(secret_manager_key) + self._set_secret(secret_manager_key) print(f"Fetched configs from {secret_manager_key}") if not self.configs.get("skip_validations"): self.validate_configuration() diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index bb0c96b70..d805e3012 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -1,13 +1,24 @@ -# sha from https://hub.docker.com/layers/amd64/eclipse-temurin/21.0.4_7-jre-alpine/images/sha256-8179ddc8a6c5ac9af935020628763b9a5a671e0914976715d2b61b21881cefca +# Use Alpine-based JRE image FROM eclipse-temurin@sha256:8179ddc8a6c5ac9af935020628763b9a5a671e0914976715d2b61b21881cefca -# Install Packages -RUN apk update && apk add jq +# Install necessary packages and set up virtual environment +RUN apk update && apk add --no-cache jq python3 py3-pip && \ + python3 -m venv /venv && \ + . /venv/bin/activate && \ + pip install --no-cache-dir requests azure-identity azure-keyvault-secrets && \ + rm -rf /var/cache/apk/* +# Set virtual environment path +ENV PATH="/venv/bin:$PATH" + +# Working directory WORKDIR /app + +# Expose necessary ports EXPOSE 8080 EXPOSE 9080 +# ARG and ENV variables ARG JAR_NAME=uid2-operator ARG JAR_VERSION=1.0.0-SNAPSHOT ARG IMAGE_VERSION=1.0.0.unknownhash @@ -17,18 +28,26 @@ ENV IMAGE_VERSION=${IMAGE_VERSION} ENV REGION=default ENV LOKI_HOSTNAME=loki +# Copy application files COPY ./target/${JAR_NAME}-${JAR_VERSION}-jar-with-dependencies.jar /app/${JAR_NAME}-${JAR_VERSION}.jar COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app COPY ./target/${JAR_NAME}-${JAR_VERSION}-static.tar.gz /app/static.tar.gz COPY ./conf/*.json /app/conf/ COPY ./conf/*.xml /app/conf/ +COPY ./azureEntryPoint.py /app +COPY ./confidential_compute.py /app -RUN tar xzvf /app/static.tar.gz --no-same-owner --no-same-permissions && rm -f /app/static.tar.gz +# Extract and clean up tar.gz +RUN tar xzvf /app/static.tar.gz --no-same-owner --no-same-permissions && \ + rm -f /app/static.tar.gz -COPY ./entrypoint.sh /app/ -RUN chmod a+x /app/entrypoint.sh +# Create and configure non-root user +RUN adduser -D uid2-operator && \ + mkdir -p /opt/uid2 && chmod 777 -R /opt/uid2 && \ + chmod 705 -R /app && mkdir -p /app/file-uploads && chmod 777 -R /app/file-uploads -RUN adduser -D uid2-operator && mkdir -p /opt/uid2 && chmod 777 -R /opt/uid2 && mkdir -p /app && chmod 705 -R /app && mkdir -p /app/file-uploads && chmod 777 -R /app/file-uploads +# Switch to non-root user USER uid2-operator -CMD ["/app/entrypoint.sh"] +# Run the Python entry point +CMD ["python3", "/app/azureEntryPoint.py"] \ No newline at end of file diff --git a/scripts/azure-cc/azureEntryPoint.py b/scripts/azure-cc/azureEntryPoint.py new file mode 100644 index 000000000..dd1afce63 --- /dev/null +++ b/scripts/azure-cc/azureEntryPoint.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 + +import json +import os +import time +from typing import Dict +import sys +import shutil +import requests + +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +from confidential_compute import ConfidentialCompute, ConfidentialComputeConfig, MissingConfig, ConfidentialComputeStartupException +from azure.identity import DefaultAzureCredential, CredentialUnavailableError +from azure.keyvault.secrets import SecretClient +from azure.core.exceptions import ResourceNotFoundError, HttpResponseError + +class AzureEntryPoint(ConfidentialCompute): + + kv_name = os.getenv("VAULT_NAME") + secret_name = os.getenv("OPERATOR_KEY_SECRET_NAME") + env_name = os.getenv("DEPLOYMENT_ENVIRONMENT") + jar_name = os.getenv("JAR_NAME", "default-jar-name") + jar_version = os.getenv("JAR_VERSION", "default-jar-version") + + FINAL_CONFIG = "/tmp/final-config.json" + + def __init__(self): + super().__init__() + + def __check_env_variables(self): + if AzureEntryPoint.kv_name is None: + raise MissingConfig(self.__class__.__name__, ["VAULT_NAME"]) + if AzureEntryPoint.secret_name is None: + raise MissingConfig(self.__class__.__name__, ["OPERATOR_KEY_SECRET_NAME"]) + if AzureEntryPoint.env_name is None: + raise MissingConfig(self.__class__.__name__, ["DEPLOYMENT_ENVIRONMENT"]) + print("Env variables validation success") + + def __wait_for_sidecar(): + url = "http://169.254.169.254/ping" + delay = 2 + max_retries = 15 + + while True: + try: + response = requests.get(url, timeout=5) + if response.status_code == 200: + print("Sidecar started") + break + except requests.RequestException: + print(f"Sidecar not started. Retrying in {delay} seconds...") + time.sleep(delay) + if delay > max_retries: + print("Sidecar failed to start") + break + delay += 1 + + def __set_environment(self): + self.configs["environment"] = AzureEntryPoint.env_name + + def _set_secret(self, secret_identifier: str = None): + try: + credential = DefaultAzureCredential() + kv_URL = f"https://{AzureEntryPoint.kv_name}.vault.azure.net" + secret_client = SecretClient(vault_url=kv_URL, credential=credential) + secret = secret_client.get_secret(AzureEntryPoint.secret_name) + # print(f"Secret Value: {secret.value}") + self.configs["api_token"] = secret.value + + except CredentialUnavailableError as auth_error: + print(f"Read operator key, authentication error: {auth_error}") + raise + + except ResourceNotFoundError as not_found_error: + print(f"Read operator key, secret not found: {AzureEntryPoint.secret_name}. Error: {not_found_error}") + raise + + except HttpResponseError as http_error: + print(f"Read operator key, HTTP error occurred: {http_error}") + raise + + except Exception as e: + print(f"Read operator key, an unexpected error occurred: {e}") + raise + + def __create_final_config(self): + TARGET_CONFIG = f"/app/conf/{AzureEntryPoint.env_name}-uid2-config.json" + if not os.path.isfile(TARGET_CONFIG): + print(f"Unrecognized config {TARGET_CONFIG}") + sys.exit(1) + + FINAL_CONFIG = "/tmp/final-config.json" + print(f"-- copying {TARGET_CONFIG} to {FINAL_CONFIG}") + try: + shutil.copy(TARGET_CONFIG, FINAL_CONFIG) + except IOError as e: + print(f"Failed to create {FINAL_CONFIG} with error: {e}") + sys.exit(1) + + CORE_BASE_URL = os.getenv("CORE_BASE_URL") + OPTOUT_BASE_URL = os.getenv("OPTOUT_BASE_URL") + if CORE_BASE_URL and OPTOUT_BASE_URL and AzureEntryPoint.env_name != 'prod': + print(f"-- replacing URLs by {CORE_BASE_URL} and {OPTOUT_BASE_URL}") + with open(FINAL_CONFIG, "r") as file: + config = file.read() + + config = config.replace("https://core-integ.uidapi.com", CORE_BASE_URL) + config = config.replace("https://optout-integ.uidapi.com", OPTOUT_BASE_URL) + + with open(FINAL_CONFIG, "w") as file: + file.write(config) + + with open(FINAL_CONFIG, "r") as file: + print(file.read()) + + def __set_baseurls(self): + final_config="/tmp/final-config.json" + with open(final_config, "r") as file: + jdata = json.load(file) + self.configs["core_base_url"] = jdata["core_attest_url"] + self.configs["optout_base_url"] = jdata["optout_api_uri"] + + def __run_operator(self): + + # Start the operator + os.environ["azure_vault_name"] = AzureEntryPoint.kv_name + os.environ["azure_secret_name"] = AzureEntryPoint.secret_name + + java_command = [ + "java", + "-XX:MaxRAMPercentage=95", "-XX:-UseCompressedOops", "-XX:+PrintFlagsFinal", + "-Djava.security.egd=file:/dev/./urandom", + "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", + "-Dlogback.configurationFile=/app/conf/logback.xml", + f"-Dvertx-config-path={AzureEntryPoint.FINAL_CONFIG}", + f"-jar {AzureEntryPoint.jar_name}-{AzureEntryPoint.jar_version}.jar" + ] + print("-- starting java operator application") + self.run_command(java_command, seperate_process=False) + + def __wait_for_sidecar(self): + url = "http://169.254.169.254/ping" + delay = 1 + max_retries = 15 + + while True: + try: + response = requests.get(url, timeout=5) + if response.status_code == 200: + print("Sidecar started") + return + except requests.RequestException: + print(f"Sidecar not started. Retrying in {delay} seconds...") + time.sleep(delay) + if delay > max_retries: + print("Sidecar failed to start") + break + delay += 1 + + def run_compute(self) -> None: + """Main execution flow for confidential compute.""" + self.__check_env_variables() + self._set_secret() + self.__set_environment() + self.__create_final_config() + self.__set_baseurls() + if not self.configs.get("skip_validations"): + self.validate_configuration() + + self.__wait_for_sidecar() + self.__run_operator() + + def _setup_auxiliaries(self) -> None: + """ Sets up auxiliary processes required for confidential computing. """ + pass + + def _validate_auxiliaries(self) -> None: + """ Validates auxiliary services are running.""" + pass + +if __name__ == "__main__": + try: + operator = AzureEntryPoint() + operator.run_compute() + + except ConfidentialComputeStartupException as e: + print("Failed starting up Azure Confidential Compute. Please checks the logs for errors and retry \n", e) + except Exception as e: + print("Unexpected failure while starting up Azure Confidential Compute. Please contact UID support team with this log \n ", e) \ No newline at end of file diff --git a/scripts/confidential_compute.py b/scripts/confidential_compute.py index 4c80be659..28babdf4e 100644 --- a/scripts/confidential_compute.py +++ b/scripts/confidential_compute.py @@ -111,12 +111,9 @@ def validate_connectivity() -> None: print("Completed static validation of confidential compute config values") @abstractmethod - def _get_secret(self, secret_identifier: str) -> ConfidentialComputeConfig: + def _set_secret(self, secret_identifier: str) -> None: """ Fetches the secret from a secret store. - - Raises: - SecretNotFoundException: If the secret is not found. """ pass From abb88d65da2482bbd6df119f4a5a56e177a9f607 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Sun, 12 Jan 2025 20:54:50 -0800 Subject: [PATCH 2/3] update --- .../publish-azure-cc-enclave-docker.yaml | 1 + scripts/aws/ec2.py | 4 +- scripts/azure-cc/Dockerfile | 8 +- scripts/azure-cc/azureEntryPoint.py | 87 ++++++++----------- scripts/confidential_compute.py | 21 ++--- 5 files changed, 56 insertions(+), 65 deletions(-) diff --git a/.github/workflows/publish-azure-cc-enclave-docker.yaml b/.github/workflows/publish-azure-cc-enclave-docker.yaml index 0127a71f4..84e74f5cb 100644 --- a/.github/workflows/publish-azure-cc-enclave-docker.yaml +++ b/.github/workflows/publish-azure-cc-enclave-docker.yaml @@ -92,6 +92,7 @@ jobs: echo "jar_version=$(mvn help:evaluate -Dexpression=project.version | grep -e '^[1-9][^\[]')" >> $GITHUB_OUTPUT echo "git_commit=$(git show --format="%h" --no-patch)" >> $GITHUB_OUTPUT cp -r target ${{ env.DOCKER_CONTEXT_PATH }}/ + cp scripts/confidential_compute.py ${{ env.DOCKER_CONTEXT_PATH }}/ - name: Log in to the Docker container registry uses: docker/login-action@v3 diff --git a/scripts/aws/ec2.py b/scripts/aws/ec2.py index f3bf15947..63876cfa7 100644 --- a/scripts/aws/ec2.py +++ b/scripts/aws/ec2.py @@ -136,7 +136,7 @@ def __run_config_server(self) -> None: json.dump(self.configs, config_file) os.chdir("/opt/uid2operator/config-server") command = ["./bin/flask", "run", "--host", AuxiliaryConfig.LOCALHOST, "--port", AuxiliaryConfig.FLASK_PORT] - self.run_command(command, seperate_process=True) + self.run_command(command, separate_process=True) def __run_socks_proxy(self) -> None: """ @@ -204,7 +204,7 @@ def __run_nitro_enclave(self): if self.configs.get('debug_mode', False): print("Running in debug_mode") command += ["--debug-mode", "--attach-console"] - self.run_command(command, seperate_process=True) + self.run_command(command, separate_process=True) def run_compute(self) -> None: """Main execution flow for confidential compute.""" diff --git a/scripts/azure-cc/Dockerfile b/scripts/azure-cc/Dockerfile index d805e3012..d4a65c507 100644 --- a/scripts/azure-cc/Dockerfile +++ b/scripts/azure-cc/Dockerfile @@ -34,13 +34,15 @@ COPY ./target/${JAR_NAME}-${JAR_VERSION}-sources.jar /app COPY ./target/${JAR_NAME}-${JAR_VERSION}-static.tar.gz /app/static.tar.gz COPY ./conf/*.json /app/conf/ COPY ./conf/*.xml /app/conf/ -COPY ./azureEntryPoint.py /app -COPY ./confidential_compute.py /app # Extract and clean up tar.gz RUN tar xzvf /app/static.tar.gz --no-same-owner --no-same-permissions && \ rm -f /app/static.tar.gz +COPY ./azureEntryPoint.py /app +COPY ./confidential_compute.py /app +RUN chmod a+x /app/*.py + # Create and configure non-root user RUN adduser -D uid2-operator && \ mkdir -p /opt/uid2 && chmod 777 -R /opt/uid2 && \ @@ -50,4 +52,4 @@ RUN adduser -D uid2-operator && \ USER uid2-operator # Run the Python entry point -CMD ["python3", "/app/azureEntryPoint.py"] \ No newline at end of file +CMD python3 /app/azureEntryPoint.py \ No newline at end of file diff --git a/scripts/azure-cc/azureEntryPoint.py b/scripts/azure-cc/azureEntryPoint.py index dd1afce63..b472de8a1 100644 --- a/scripts/azure-cc/azureEntryPoint.py +++ b/scripts/azure-cc/azureEntryPoint.py @@ -7,6 +7,7 @@ import sys import shutil import requests +import logging sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from confidential_compute import ConfidentialCompute, ConfidentialComputeConfig, MissingConfig, ConfidentialComputeStartupException @@ -34,26 +35,7 @@ def __check_env_variables(self): raise MissingConfig(self.__class__.__name__, ["OPERATOR_KEY_SECRET_NAME"]) if AzureEntryPoint.env_name is None: raise MissingConfig(self.__class__.__name__, ["DEPLOYMENT_ENVIRONMENT"]) - print("Env variables validation success") - - def __wait_for_sidecar(): - url = "http://169.254.169.254/ping" - delay = 2 - max_retries = 15 - - while True: - try: - response = requests.get(url, timeout=5) - if response.status_code == 200: - print("Sidecar started") - break - except requests.RequestException: - print(f"Sidecar not started. Retrying in {delay} seconds...") - time.sleep(delay) - if delay > max_retries: - print("Sidecar failed to start") - break - delay += 1 + logging.info("Env variables validation success") def __set_environment(self): self.configs["environment"] = AzureEntryPoint.env_name @@ -68,54 +50,52 @@ def _set_secret(self, secret_identifier: str = None): self.configs["api_token"] = secret.value except CredentialUnavailableError as auth_error: - print(f"Read operator key, authentication error: {auth_error}") + logging.error(f"Read operator key, authentication error: {auth_error}") raise except ResourceNotFoundError as not_found_error: - print(f"Read operator key, secret not found: {AzureEntryPoint.secret_name}. Error: {not_found_error}") + logging.error(f"Read operator key, secret not found: {AzureEntryPoint.secret_name}. Error: {not_found_error}") raise except HttpResponseError as http_error: - print(f"Read operator key, HTTP error occurred: {http_error}") + logging.error(f"Read operator key, HTTP error occurred: {http_error}") raise except Exception as e: - print(f"Read operator key, an unexpected error occurred: {e}") + logging.error(f"Read operator key, an unexpected error occurred: {e}") raise def __create_final_config(self): TARGET_CONFIG = f"/app/conf/{AzureEntryPoint.env_name}-uid2-config.json" if not os.path.isfile(TARGET_CONFIG): - print(f"Unrecognized config {TARGET_CONFIG}") + logging.error(f"Unrecognized config {TARGET_CONFIG}") sys.exit(1) - FINAL_CONFIG = "/tmp/final-config.json" - print(f"-- copying {TARGET_CONFIG} to {FINAL_CONFIG}") + logging.info(f"-- copying {TARGET_CONFIG} to {AzureEntryPoint.FINAL_CONFIG}") try: - shutil.copy(TARGET_CONFIG, FINAL_CONFIG) + shutil.copy(TARGET_CONFIG, AzureEntryPoint.FINAL_CONFIG) except IOError as e: - print(f"Failed to create {FINAL_CONFIG} with error: {e}") + logging.error(f"Failed to create {AzureEntryPoint.FINAL_CONFIG} with error: {e}") sys.exit(1) CORE_BASE_URL = os.getenv("CORE_BASE_URL") OPTOUT_BASE_URL = os.getenv("OPTOUT_BASE_URL") if CORE_BASE_URL and OPTOUT_BASE_URL and AzureEntryPoint.env_name != 'prod': - print(f"-- replacing URLs by {CORE_BASE_URL} and {OPTOUT_BASE_URL}") - with open(FINAL_CONFIG, "r") as file: + logging.info(f"-- replacing URLs by {CORE_BASE_URL} and {OPTOUT_BASE_URL}") + with open(AzureEntryPoint.FINAL_CONFIG, "r") as file: config = file.read() config = config.replace("https://core-integ.uidapi.com", CORE_BASE_URL) config = config.replace("https://optout-integ.uidapi.com", OPTOUT_BASE_URL) - with open(FINAL_CONFIG, "w") as file: + with open(AzureEntryPoint.FINAL_CONFIG, "w") as file: file.write(config) - with open(FINAL_CONFIG, "r") as file: - print(file.read()) + with open(AzureEntryPoint.FINAL_CONFIG, "r") as file: + logging.info(file.read()) def __set_baseurls(self): - final_config="/tmp/final-config.json" - with open(final_config, "r") as file: + with open(AzureEntryPoint.FINAL_CONFIG, "r") as file: jdata = json.load(file) self.configs["core_base_url"] = jdata["core_attest_url"] self.configs["optout_base_url"] = jdata["optout_api_uri"] @@ -133,12 +113,15 @@ def __run_operator(self): "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", "-Dlogback.configurationFile=/app/conf/logback.xml", f"-Dvertx-config-path={AzureEntryPoint.FINAL_CONFIG}", - f"-jar {AzureEntryPoint.jar_name}-{AzureEntryPoint.jar_version}.jar" + "-jar", + f"{AzureEntryPoint.jar_name}-{AzureEntryPoint.jar_version}.jar" ] - print("-- starting java operator application") - self.run_command(java_command, seperate_process=False) + logging.info("-- starting java operator application") + self.run_command(java_command, separate_process=False) def __wait_for_sidecar(self): + logging.info("Waiting for sidecar ...") + url = "http://169.254.169.254/ping" delay = 1 max_retries = 15 @@ -146,15 +129,18 @@ def __wait_for_sidecar(self): while True: try: response = requests.get(url, timeout=5) - if response.status_code == 200: - print("Sidecar started") + if response.status_code in [200, 204]: + logging.info("Sidecar started") return - except requests.RequestException: - print(f"Sidecar not started. Retrying in {delay} seconds...") - time.sleep(delay) + else: + error_msg = f"Unexpected status code: {response.status_code}, response: {response.text}" + raise Exception(error_msg) + except Exception as e: if delay > max_retries: - print("Sidecar failed to start") - break + logging.error(f"Sidecar failed to start after {delay} retries with error {e}", exc_info=True) + sys.exit(1) + logging.info(f"Sidecar not started. Retrying in {delay} seconds... {e}") + time.sleep(delay) delay += 1 def run_compute(self) -> None: @@ -166,7 +152,6 @@ def run_compute(self) -> None: self.__set_baseurls() if not self.configs.get("skip_validations"): self.validate_configuration() - self.__wait_for_sidecar() self.__run_operator() @@ -179,11 +164,13 @@ def _validate_auxiliaries(self) -> None: pass if __name__ == "__main__": + + logging.basicConfig(level=logging.INFO) + logging.info("Start AzureEntryPoint") try: operator = AzureEntryPoint() operator.run_compute() - except ConfidentialComputeStartupException as e: - print("Failed starting up Azure Confidential Compute. Please checks the logs for errors and retry \n", e) + logging.error(f"Failed starting up Azure Confidential Compute. Please checks the logs for errors and retry {e}", exc_info=True) except Exception as e: - print("Unexpected failure while starting up Azure Confidential Compute. Please contact UID support team with this log \n ", e) \ No newline at end of file + logging.error(f"Unexpected failure while starting up Azure Confidential Compute. Please contact UID support team with this log {e}", exc_info=True) \ No newline at end of file diff --git a/scripts/confidential_compute.py b/scripts/confidential_compute.py index 28babdf4e..c3fcaf705 100644 --- a/scripts/confidential_compute.py +++ b/scripts/confidential_compute.py @@ -5,6 +5,7 @@ from abc import ABC, abstractmethod from typing import TypedDict, NotRequired, get_type_hints import subprocess +import logging class ConfidentialComputeConfig(TypedDict): api_token: str @@ -55,7 +56,7 @@ def __init__(self): def validate_configuration(self): """ Validates the paramters specified through configs/secret manager .""" - print("Validating configurations provided") + logging.info("Validating configurations provided") def validate_operator_key(): """ Validates the operator key format and its environment alignment.""" operator_key = self.configs.get("api_token") @@ -66,9 +67,9 @@ def validate_operator_key(): expected_env = "I" if debug_mode or env == "integ" else "P" if operator_key.split("-")[2] != expected_env: raise InvalidOperatorKey(self.__class__.__name__) - print("Validated operator key matches environment") + logging.info("Validated operator key matches environment") else: - print("Skipping operator key validation") + logging.info("Skipping operator key validation") def validate_url(url_key, environment): """URL should include environment except in prod""" @@ -77,7 +78,7 @@ def validate_url(url_key, environment): parsed_url = urlparse(self.configs[url_key]) if parsed_url.scheme != 'https' and parsed_url.path: raise InvalidConfigValue(self.__class__.__name__, url_key) - print(f"Validated {self.configs[url_key]} matches other config parameters") + logging.info(f"Validated {self.configs[url_key]} matches other config parameters") def validate_connectivity() -> None: """ Validates that the core URL is accessible.""" @@ -85,7 +86,7 @@ def validate_connectivity() -> None: core_url = self.configs["core_base_url"] core_ip = socket.gethostbyname(urlparse(core_url).netloc) requests.get(core_url, timeout=5) - print(f"Validated connectivity to {core_url}") + logging.info(f"Validated connectivity to {core_url}") except (requests.ConnectionError, requests.Timeout) as e: raise UID2ServicesUnreachable(self.__class__.__name__, core_ip) except Exception as e: @@ -108,7 +109,7 @@ def validate_connectivity() -> None: validate_url("optout_base_url", environment) validate_operator_key() validate_connectivity() - print("Completed static validation of confidential compute config values") + logging.info("Completed static validation of confidential compute config values") @abstractmethod def _set_secret(self, secret_identifier: str) -> None: @@ -133,13 +134,13 @@ def run_compute(self) -> None: pass @staticmethod - def run_command(command, seperate_process=False): - print(f"Running command: {' '.join(command)}") + def run_command(command, separate_process=False): + logging.info(f"Running command: {' '.join(command)}") try: - if seperate_process: + if separate_process: subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) else: subprocess.run(command,check=True) except Exception as e: - print(f"Failed to run command: {str(e)}") + logging.error(f"Failed to run command: {e}", exc_info=True) raise RuntimeError (f"Failed to start {' '.join(command)} ") \ No newline at end of file From b1b48156be79a7056b8ec410b65c577dc39b4724 Mon Sep 17 00:00:00 2001 From: Release Workflow Date: Mon, 13 Jan 2025 05:03:10 +0000 Subject: [PATCH 3/3] [CI Pipeline] Released Snapshot version: 5.45.7-alpha-166-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5ebed11c9..4da96fca7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.uid2 uid2-operator - 5.44.6 + 5.45.7-alpha-166-SNAPSHOT UTF-8