Skip to content

Commit 9f80892

Browse files
clarkxuyangRelease Workflow
andauthored
xyang-UID2-4369-enable-nitro-logging (#1403)
* xyang-UID2-4369-enable-nitro-logging Co-authored-by: Release Workflow <unifiedid-admin+release@thetradedesk.com>
1 parent caeb948 commit 9f80892

File tree

5 files changed

+72
-26
lines changed

5 files changed

+72
-26
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.uid2</groupId>
88
<artifactId>uid2-operator</artifactId>
9-
<version>5.47.75-alpha-168-SNAPSHOT</version>
9+
<version>5.47.76-alpha-183-SNAPSHOT</version>
1010

1111
<properties>
1212
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -22,7 +22,7 @@
2222
<enclave-aws.version>2.1.0</enclave-aws.version>
2323
<enclave-azure.version>2.1.0</enclave-azure.version>
2424
<enclave-gcp.version>2.1.0</enclave-gcp.version>
25-
<uid2-shared.version>8.1.10</uid2-shared.version>
25+
<uid2-shared.version>8.1.15</uid2-shared.version>
2626
<image.version>${project.version}</image.version>
2727
<maven.compiler.source>21</maven.compiler.source>
2828
<maven.compiler.target>21</maven.compiler.target>

scripts/aws/UID_CloudFormation.template.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,11 @@ Resources:
189189
SecretString: !Join
190190
- ''
191191
- - '{'
192-
- '"core_base_url": '
192+
- '"core_base_url": "'
193193
- !If [IsIntegEnvironment, 'https://core-integ.uidapi.com', 'https://core.uidapi.com']
194-
- ', "optout_base_url": '
194+
- '", "optout_base_url": "'
195195
- !If [IsIntegEnvironment, 'https://optout-integ.uidapi.com', 'https://optout.uidapi.com']
196-
- ', "operator_key": "'
196+
- '", "operator_key": "'
197197
- Ref: APIToken
198198
- '"'
199199
- ', "service_instances": 6'

scripts/aws/ec2.py

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import argparse
1212
import logging
1313
from botocore.exceptions import ClientError, NoCredentialsError
14-
from typing import Dict
14+
from typing import Dict, List
1515
import sys
1616
import time
1717
import yaml
@@ -105,6 +105,8 @@ def add_defaults(configs: Dict[str, any]) -> AWSConfidentialComputeConfig:
105105
try:
106106
self.configs = add_defaults(json.loads(client.get_secret_value(SecretId=secret_identifier)["SecretString"]))
107107
self.__validate_aws_specific_config()
108+
except json.JSONDecodeError as e:
109+
raise OperatorKeyNotFoundError(self.__class__.__name__, f"Can not parse secret {secret_identifier} in {region}")
108110
except NoCredentialsError as _:
109111
raise InstanceProfileMissingError(self.__class__.__name__)
110112
except ClientError as _:
@@ -119,38 +121,80 @@ def __get_max_capacity():
119121
except Exception as e:
120122
raise RuntimeError("/etc/nitro_enclaves/allocator.yaml does not have CPU, memory allocated")
121123

122-
def __setup_vsockproxy(self, log_level: int) -> None:
123-
"""
124-
Sets up the vsock proxy service.
125-
"""
124+
def __setup_vsockproxy(self) -> None:
125+
logging.info("Sets up the vSock proxy service")
126126
thread_count = (multiprocessing.cpu_count() + 1) // 2
127127
command = [
128128
"/usr/bin/vsockpx", "-c", "/etc/uid2operator/proxy.yaml",
129-
"--workers", str(thread_count), "--log-level", str(log_level), "--daemon"
129+
"--workers", str(thread_count), "--daemon"
130+
]
131+
132+
debug_command = [
133+
"/usr/bin/vsockpx", "-c", "/etc/uid2operator/proxy.yaml",
134+
"--workers", str(thread_count), "--log-level", "0"
130135
]
131-
self.run_command(command)
136+
137+
self.run_service([command, debug_command], "vsock_proxy")
132138

133139
def __run_config_server(self) -> None:
134-
"""
135-
Starts the Flask configuration server.
136-
"""
140+
logging.info("Starts the Flask configuration server")
137141
os.makedirs("/etc/secret/secret-value", exist_ok=True)
138142
config_path = "/etc/secret/secret-value/config"
143+
144+
# Save configs to a file
139145
with open(config_path, 'w') as config_file:
140146
json.dump(self.configs, config_file)
147+
141148
os.chdir("/opt/uid2operator/config-server")
142149
command = ["./bin/flask", "run", "--host", AuxiliaryConfig.LOCALHOST, "--port", AuxiliaryConfig.FLASK_PORT]
143-
self.run_command(command, separate_process=True)
150+
151+
self.run_service([command, command], "flask_config_server", separate_process=True)
144152

145153
def __run_socks_proxy(self) -> None:
154+
logging.info("Starts the SOCKS proxy service")
155+
command = ["sockd", "-D"]
156+
157+
# -d specifies debug level
158+
debug_command = ["sockd", "-d", "0"]
159+
160+
self.run_service([command, debug_command], "socks_proxy")
161+
162+
def run_service(self, command: List[List[str]], log_filename: str, separate_process: bool = False) -> None:
146163
"""
147-
Starts the SOCKS proxy service.
164+
Runs a service command with logging if debug_mode is enabled.
165+
166+
:param command: command[0] regular command, command[1] debug mode command
167+
:param log_filename: Base name of the log file (e.g., "flask_config_server", "socks_proxy", "vsock_proxy")
168+
:param separate_process: Whether to run in a separate process
148169
"""
149-
command = ["sockd", "-D"]
150-
self.run_command(command)
170+
log_file = f"/var/log/{log_filename}.log"
171+
172+
if self.configs.get("debug_mode") is True:
173+
174+
# Remove old log file to start fresh
175+
if os.path.exists(log_file):
176+
os.remove(log_file)
177+
178+
# Set up logging
179+
logging.basicConfig(
180+
filename=log_file,
181+
filemode="w",
182+
level=logging.DEBUG,
183+
format="%(asctime)s %(levelname)s: %(message)s"
184+
)
185+
186+
logging.info(f"Debug mode is on, logging into {log_file}")
187+
188+
# Run debug mode command
189+
with open(log_file, "a") as log:
190+
self.run_command(command[1], separate_process=True, stdout=log, stderr=log)
191+
else:
192+
# Run regular command, possibly daemon
193+
self.run_command(command[0], separate_process=separate_process)
151194

152195
def __get_secret_name_from_userdata(self) -> str:
153196
"""Extracts the secret name from EC2 user data."""
197+
logging.info("Extracts the secret name from EC2 user data")
154198
token = self.__get_aws_token()
155199
response = requests.get(AuxiliaryConfig.get_user_data_url(), headers={"X-aws-ec2-metadata-token": token})
156200
user_data = response.text
@@ -165,8 +209,7 @@ def __get_secret_name_from_userdata(self) -> str:
165209

166210
def _setup_auxiliaries(self) -> None:
167211
"""Sets up the vsock tunnel, socks proxy and flask server"""
168-
log_level = 1 if self.configs["debug_mode"] else 3
169-
self.__setup_vsockproxy(log_level)
212+
self.__setup_vsockproxy()
170213
self.__run_config_server()
171214
self.__run_socks_proxy()
172215
logging.info("Finished setting up all auxiliaries")
@@ -206,7 +249,7 @@ def __run_nitro_enclave(self):
206249
"--enclave-name", "uid2operator"
207250
]
208251
if self.configs.get('debug_mode', False):
209-
logging.info("Running in debug_mode")
252+
logging.info("Running nitro in debug_mode")
210253
command += ["--debug-mode", "--attach-console"]
211254
self.run_command(command, separate_process=False)
212255

@@ -248,6 +291,7 @@ def __kill_auxiliaries(self) -> None:
248291
parser = argparse.ArgumentParser(description="Manage EC2-based confidential compute workflows.")
249292
parser.add_argument("-o", "--operation", choices=["stop", "start"], default="start", help="Operation to perform.")
250293
args = parser.parse_args()
294+
251295
try:
252296
ec2 = EC2EntryPoint()
253297
if args.operation == "stop":

scripts/aws/sockd.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ external: ens5
33
user.notprivileged: ec2-user
44
clientmethod: none
55
socksmethod: none
6+
logoutput: stderr
67

78
client pass {
89
from: 127.0.0.1/32 to: 127.0.0.1/32
9-
log: error # connect disconnect iooperation
10+
log: error connect # disconnect iooperation
1011
}
1112

1213
socks pass {

scripts/confidential_compute.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,14 @@ def run_compute(self) -> None:
138138
pass
139139

140140
@staticmethod
141-
def run_command(command, separate_process=False):
141+
def run_command(command, separate_process=False, stdout=None, stderr=None):
142142
logging.info(f"Running command: {' '.join(command)}")
143143
try:
144144
if separate_process:
145-
subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
145+
subprocess.Popen(command, stdout=stdout, stderr=stderr)
146146
else:
147-
subprocess.run(command,check=True,text=True)
147+
subprocess.run(command, check=True, stdout=stdout, stderr=stderr)
148+
148149
except Exception as e:
149150
logging.error(f"Failed to run command: {e}", exc_info=True)
150151
raise RuntimeError (f"Failed to start {' '.join(command)} ")

0 commit comments

Comments
 (0)