Skip to content

Commit c1187c1

Browse files
[SNOW-2114104] Config generator and update dockerfile (#2350)
Co-authored-by: Maxim Mishchenko <[email protected]>
1 parent 56fffab commit c1187c1

File tree

7 files changed

+157
-60
lines changed

7 files changed

+157
-60
lines changed

prober/Dockerfile

100644100755
Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,48 +17,61 @@ RUN apk add --no-cache \
1717
g++ \
1818
zlib-dev \
1919
openssl-dev \
20-
libffi-dev
20+
libffi-dev \
21+
jq
2122

22-
ENV HOME="/root"
23+
ENV HOME="/home/driveruser"
24+
25+
# Create a group with GID=1000 and a user with UID=1000
26+
RUN addgroup -g 1000 drivergroup && \
27+
adduser -u 1000 -G drivergroup -D driveruser
28+
29+
# Set permissions for the non-root user
30+
RUN mkdir -p ${HOME} && \
31+
chown -R driveruser:drivergroup ${HOME}
32+
33+
# Switch to the non-root user
34+
USER driveruser
2335
WORKDIR ${HOME}
24-
RUN git clone --depth=1 https://github.com/pyenv/pyenv.git .pyenv
36+
37+
# Set environment variables
2538
ENV PYENV_ROOT="${HOME}/.pyenv"
2639
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"
2740

2841

42+
# Install pyenv
43+
RUN git clone --depth=1 https://github.com/pyenv/pyenv.git ${PYENV_ROOT}
44+
2945
# Build arguments for Python versions and Snowflake connector versions
30-
ARG PYTHON_VERSIONS="3.8.20 3.9.22 3.10.17"
31-
ARG SNOWFLAKE_CONNECTOR_VERSIONS="3.14.0 3.13.2 3.13.1"
46+
ARG MATRIX_VERSION='{"3.10.17": ["3.14.0", "3.13.2", "3.13.1"], "3.9.22": ["3.14.0", "3.13.2", "3.13.1"], "3.8.20": ["3.14.0", "3.13.2", "3.13.1"]}'
3247

3348

34-
# Install Python versions
49+
# Install Python versions from ARG MATRIX_VERSION
3550
RUN eval "$(pyenv init --path)" && \
36-
for version in $PYTHON_VERSIONS; do \
37-
pyenv install $version || echo "Failed to install Python $version"; \
51+
for python_version in $(echo $MATRIX_VERSION | jq -r 'keys[]'); do \
52+
pyenv install $python_version || echo "Failed to install Python $python_version"; \
3853
done
3954

40-
4155
# Create virtual environments for each combination of Python and Snowflake connector versions
42-
RUN for python_version in $PYTHON_VERSIONS; do \
43-
for connector_version in $SNOWFLAKE_CONNECTOR_VERSIONS; do \
44-
venv_path="/venvs/python_${python_version}_connector_${connector_version}"; \
56+
RUN for python_version in $(echo $MATRIX_VERSION | jq -r 'keys[]'); do \
57+
for connector_version in $(echo $MATRIX_VERSION | jq -r ".\"${python_version}\"[]"); do \
58+
venv_path="${HOME}/venvs/python_${python_version}_connector_${connector_version}"; \
4559
$PYENV_ROOT/versions/$python_version/bin/python -m venv $venv_path && \
4660
$venv_path/bin/pip install --upgrade pip && \
4761
$venv_path/bin/pip install snowflake-connector-python==$connector_version; \
4862
done; \
4963
done
5064

5165
# Copy the prober script into the container
52-
RUN mkdir -p /prober/probes/
53-
COPY __init__.py /prober
54-
# COPY parameters.json /prober
55-
COPY setup.py /prober
56-
COPY entrypoint.sh /prober
57-
COPY probes/* /prober/probes
66+
RUN mkdir -p prober/probes/
67+
COPY __init__.py prober
68+
COPY setup.py prober
69+
COPY entrypoint.sh prober
70+
COPY probes/* prober/probes
5871

5972
# Install /prober in editable mode for each virtual environment
60-
RUN for venv in /venvs/*; do \
73+
RUN for venv in ${HOME}/venvs/*; do \
6174
source $venv/bin/activate && \
62-
pip install -e /prober && \
75+
pip install -e ${HOME}/prober && \
6376
deactivate; \
6477
done

prober/entrypoint.sh

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,45 @@
11
#!/bin/bash
22

33
# Initialize an empty string to hold all parameters
4+
python_version=""
5+
connector_version=""
46
params=""
57

6-
# Parse command-line arguments dynamically
8+
# Parse command-line arguments
79
while [[ "$#" -gt 0 ]]; do
8-
params="$params $1 $2"
9-
shift 2
10+
if [[ "$1" == "--python_version" ]]; then
11+
python_version="$2"
12+
shift 2
13+
elif [[ "$1" == "--connector_version" ]]; then
14+
connector_version="$2"
15+
shift 2
16+
else
17+
params+="$1 $2 "
18+
shift 2
19+
fi
1020
done
1121

12-
# Run main.py with all available virtual environments
13-
for venv in /venvs/*; do
14-
echo "Running main.py with virtual environment: $(basename "$venv")"
15-
source "$venv/bin/activate"
16-
prober $params
17-
deactivate
18-
done
22+
# Construct the virtual environment path
23+
venv_path="${HOME}/venvs/python_${python_version}_connector_${connector_version}"
24+
25+
# Check if the virtual environment exists
26+
if [[ ! -d "$venv_path" ]]; then
27+
echo "Error: Virtual environment not found at $venv_path"
28+
exit 1
29+
fi
30+
31+
# Run main.py with given venv
32+
echo "Running main.py with virtual environment: $venv_path"
33+
source "$venv_path/bin/activate"
34+
prober $params
35+
status=$?
36+
deactivate
37+
38+
# Check the exit status of prober
39+
if [[ $status -ne 0 ]]; then
40+
echo "Error: prober returned failure."
41+
exit 1
42+
else
43+
echo "Success: prober returned success."
44+
exit 0
45+
fi

prober/probes/login.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import sys
2+
13
from probes.logging_config import initialize_logger
24
from probes.registry import prober_function
35

@@ -30,11 +32,10 @@ def connect(connection_parameters: dict):
3032
schema=connection_parameters["schema"],
3133
role=connection_parameters["role"],
3234
authenticator=connection_parameters["authenticator"],
33-
private_key_file=connection_parameters["private_key_file"],
35+
private_key=connection_parameters["private_key"],
3436
)
3537
return connection
3638
except Exception as e:
37-
logger.info({f"success_login={False}"})
3839
logger.error(f"Error connecting to Snowflake: {e}")
3940

4041

@@ -54,13 +55,22 @@ def perform_login(connection_parameters: dict):
5455
# Connect to Snowflake
5556
connection = connect(connection_parameters)
5657

58+
# Log the connection details
59+
python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
60+
driver_version = snowflake.connector.__version__
61+
5762
# Perform a simple query to test the connection
5863
cursor = connection.cursor()
5964
cursor.execute("SELECT 1;")
6065
result = cursor.fetchone()
61-
logger.error(f"Logging: {result}")
6266
assert result == (1,)
63-
print({"success_login": True})
67+
print(
68+
f"cloudprober_driver_python_perform_login{{python_version={python_version}, driver_version={driver_version}}} 0"
69+
)
70+
sys.exit(0)
6471
except Exception as e:
65-
print({"success_login": False})
72+
print(
73+
f"cloudprober_driver_python_perform_login{{python_version={python_version}, driver_version={driver_version}}} 1"
74+
)
6675
logger.error(f"Error during login: {e}")
76+
sys.exit(1)

prober/probes/main.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import argparse
22
import logging
3+
import sys
34

45
from probes import login, put_fetch_get # noqa
56
from probes.logging_config import initialize_logger
@@ -23,13 +24,23 @@ def main():
2324
parser.add_argument("--database", required=True, help="Database")
2425
parser.add_argument("--user", required=True, help="Username")
2526
parser.add_argument(
26-
"--auth", required=True, help="Authenticator (e.g., KEY_PAIR_AUTHENTICATOR)"
27+
"--authenticator",
28+
required=True,
29+
help="Authenticator (e.g., KEY_PAIR_AUTHENTICATOR)",
30+
)
31+
parser.add_argument(
32+
"--private_key_file",
33+
required=True,
34+
help="Private key file in DER format base64-encoded and '/' -> '_', '+' -> '-' replacements",
2735
)
28-
parser.add_argument("--private_key_file", required=True, help="Private key pwd")
2936

3037
# Parse arguments
3138
args = parser.parse_args()
3239

40+
private_key = (
41+
open(args.private_key_file).read().strip().replace("_", "/").replace("-", "+")
42+
)
43+
3344
connection_params = {
3445
"host": args.host,
3546
"port": args.port,
@@ -39,16 +50,22 @@ def main():
3950
"warehouse": args.warehouse,
4051
"database": args.database,
4152
"user": args.user,
42-
"authenticator": args.auth,
43-
"private_key_file": args.private_key_file,
53+
"authenticator": args.authenticator,
54+
"private_key": private_key,
4455
}
4556

46-
for function_name, function in PROBES_FUNCTIONS.items():
57+
if args.scope not in PROBES_FUNCTIONS:
58+
logging.error(
59+
f"Invalid scope: {args.scope}. Available scopes: {list(PROBES_FUNCTIONS.keys())}"
60+
)
61+
sys.exit(1)
62+
else:
63+
logging.info(f"Running probe for scope: {args.scope}")
4764
try:
48-
logging.error(f"Running probe: {function_name}")
49-
function(connection_params)
65+
PROBES_FUNCTIONS[args.scope](connection_params)
5066
except Exception as e:
51-
logging.error(f"Error running probe {function_name}: {e}")
67+
logging.error(f"Error running probe {args.scope}: {e}")
68+
sys.exit(1)
5269

5370

5471
if __name__ == "__main__":

prober/probes/testing_matrix.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

prober/testing_matrix.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"python-version": [
3+
{
4+
"version": "3.10.17",
5+
"snowflake-connector-python": ["3.14.0", "3.13.2", "3.13.1"]
6+
},
7+
{
8+
"version": "3.9.22",
9+
"snowflake-connector-python": ["3.14.0", "3.13.2", "3.13.1"]
10+
},
11+
{
12+
"version": "3.8.20",
13+
"snowflake-connector-python": ["3.14.0", "3.13.2", "3.13.1"]
14+
}
15+
]
16+
}

prober/version_generator.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import json
2+
3+
4+
def extract_versions():
5+
with open("testing_matrix.json") as file:
6+
data = json.load(file)
7+
version_mapping = {}
8+
for entry in data["python-version"]:
9+
python_version = str(entry["version"])
10+
version_mapping[python_version] = entry["snowflake-connector-python"]
11+
return version_mapping
12+
13+
14+
def update_dockerfile(version_mapping):
15+
dockerfile_path = "Dockerfile"
16+
new_matrix_version = json.dumps(version_mapping)
17+
18+
with open(dockerfile_path) as file:
19+
lines = file.readlines()
20+
21+
with open(dockerfile_path, "w") as file:
22+
for line in lines:
23+
if line.startswith("ARG MATRIX_VERSION"):
24+
file.write(f"ARG MATRIX_VERSION='{new_matrix_version}'\n")
25+
else:
26+
file.write(line)
27+
28+
29+
if __name__ == "__main__":
30+
extracted_mapping = extract_versions()
31+
update_dockerfile(extracted_mapping)

0 commit comments

Comments
 (0)