Skip to content

Commit 979b82a

Browse files
aipcc-botntkathole
authored andcommitted
fix: Set FIPS cipher suites before pyarrow.flight import to prevent crash on IBM Power
RHOAIENG-78595 # What this PR does / why we need it: The Feast offline container crashes in CrashLoopBackOff on FIPS-enabled OpenShift clusters running IBM Power (ppc64le). The existing FIPS cipher suite fix (RHOAIENG-70153) set GRPC_SSL_CIPHER_SUITES in `start_server()`, but pyarrow.flight was already imported at module level. On IBM Power, gRPC reads this env var during shared-library initialization, so the late configuration had no effect. This fix moves the FIPS cipher configuration to module level — before the pyarrow.flight import — so the env var is present when gRPC initializes its SSL context. The `_configure_grpc_fips()` call in `start_server()` is retained as a safety net. # Which issue(s) this PR fixes: Fixes RHOAIENG-78595 # Checks - [x] I've made sure the tests are passing. - [x] My PR title follows conventional commits format ## Testing Strategy - [x] Unit tests Assisted-by: Claude claude-opus-4-6 <[email protected]> Signed-off-by: aipcc-bot <[email protected]> Signed-off-by: Jitendra Yejare <[email protected]>
1 parent 62db435 commit 979b82a

2 files changed

Lines changed: 65 additions & 33 deletions

File tree

‎sdk/python/feast/offline_server.py‎

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,6 @@
77
from datetime import datetime
88
from typing import Any, Dict, List, Optional, cast
99

10-
import click
11-
import pyarrow as pa
12-
import pyarrow.flight as fl
13-
from google.protobuf.json_format import Parse
14-
15-
from feast import FeatureStore, FeatureView, utils
16-
from feast.arrow_error_handler import arrow_server_error_handling_decorator
17-
from feast.data_source import DataSource
18-
from feast.errors import FeatureViewNotFoundException
19-
from feast.feature_logging import FeatureServiceLoggingSource
20-
from feast.feature_view import DUMMY_ENTITY_NAME
21-
from feast.infra.offline_stores.offline_utils import get_offline_store_from_config
22-
from feast.permissions.action import AuthzedAction
23-
from feast.permissions.security_manager import assert_permissions
24-
from feast.permissions.server.arrow import (
25-
AuthorizationMiddlewareFactory,
26-
inject_user_details_decorator,
27-
)
28-
from feast.permissions.server.utils import (
29-
AuthManagerType,
30-
ServerType,
31-
init_auth_manager,
32-
init_security_manager,
33-
str_to_auth_manager_type,
34-
)
35-
from feast.protos.feast.core.DataSource_pb2 import DataSource as DataSourceProto
36-
from feast.saved_dataset import SavedDatasetStorage
37-
38-
logger = logging.getLogger(__name__)
39-
logger.setLevel(logging.INFO)
40-
4110
_FIPS_CIPHER_SUITES = ":".join(
4211
[
4312
"ECDHE-RSA-AES128-GCM-SHA256",
@@ -55,14 +24,58 @@ def _is_fips_enabled() -> bool:
5524
with open("/proc/sys/crypto/fips_enabled") as f:
5625
return f.read().strip() == "1"
5726
except (FileNotFoundError, PermissionError, OSError):
58-
logger.debug("Could not detect FIPS mode (Linux-only feature)")
5927
return False
6028

6129

6230
def _configure_grpc_fips() -> None:
6331
if _is_fips_enabled() and "GRPC_SSL_CIPHER_SUITES" not in os.environ:
6432
os.environ["GRPC_SSL_CIPHER_SUITES"] = _FIPS_CIPHER_SUITES
65-
logger.info("FIPS mode detected, configured FIPS-compliant gRPC cipher suites.")
33+
logging.getLogger(__name__).info(
34+
"FIPS mode detected, configured FIPS-compliant gRPC cipher suites."
35+
)
36+
37+
38+
# On FIPS-enabled systems (notably IBM Power ppc64le), gRPC reads
39+
# GRPC_SSL_CIPHER_SUITES during shared-library initialization. The env var
40+
# must be set before any gRPC-linked module (pyarrow.flight) is imported.
41+
_configure_grpc_fips()
42+
43+
import click # noqa: E402
44+
import pyarrow as pa # noqa: E402
45+
import pyarrow.flight as fl # noqa: E402
46+
from google.protobuf.json_format import Parse # noqa: E402
47+
48+
from feast import FeatureStore, FeatureView, utils # noqa: E402
49+
from feast.arrow_error_handler import ( # noqa: E402
50+
arrow_server_error_handling_decorator,
51+
)
52+
from feast.data_source import DataSource # noqa: E402
53+
from feast.errors import FeatureViewNotFoundException # noqa: E402
54+
from feast.feature_logging import FeatureServiceLoggingSource # noqa: E402
55+
from feast.feature_view import DUMMY_ENTITY_NAME # noqa: E402
56+
from feast.infra.offline_stores.offline_utils import ( # noqa: E402
57+
get_offline_store_from_config,
58+
)
59+
from feast.permissions.action import AuthzedAction # noqa: E402
60+
from feast.permissions.security_manager import assert_permissions # noqa: E402
61+
from feast.permissions.server.arrow import ( # noqa: E402
62+
AuthorizationMiddlewareFactory,
63+
inject_user_details_decorator,
64+
)
65+
from feast.permissions.server.utils import ( # noqa: E402
66+
AuthManagerType,
67+
ServerType,
68+
init_auth_manager,
69+
init_security_manager,
70+
str_to_auth_manager_type,
71+
)
72+
from feast.protos.feast.core.DataSource_pb2 import ( # noqa: E402
73+
DataSource as DataSourceProto,
74+
)
75+
from feast.saved_dataset import SavedDatasetStorage # noqa: E402
76+
77+
logger = logging.getLogger(__name__)
78+
logger.setLevel(logging.INFO)
6679

6780

6881
class OfflineServer(fl.FlightServerBase):

‎sdk/python/tests/unit/test_offline_server.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import importlib
12
import os
23
from unittest.mock import MagicMock, mock_open, patch
34

@@ -137,3 +138,21 @@ def test_configure_grpc_fips_noop_without_fips():
137138
os.environ.pop("GRPC_SSL_CIPHER_SUITES", None)
138139
_configure_grpc_fips()
139140
assert "GRPC_SSL_CIPHER_SUITES" not in os.environ
141+
142+
143+
def test_module_level_fips_sets_env_before_pyarrow_import():
144+
"""GRPC_SSL_CIPHER_SUITES must be set at module load time,
145+
before pyarrow.flight (which bundles gRPC) is imported."""
146+
env_backup = os.environ.pop("GRPC_SSL_CIPHER_SUITES", None)
147+
try:
148+
with patch("builtins.open", mock_open(read_data="1\n")):
149+
import feast.offline_server as mod
150+
151+
importlib.reload(mod)
152+
assert "GRPC_SSL_CIPHER_SUITES" in os.environ
153+
assert "AES128-GCM-SHA256" in os.environ["GRPC_SSL_CIPHER_SUITES"]
154+
finally:
155+
if env_backup is not None:
156+
os.environ["GRPC_SSL_CIPHER_SUITES"] = env_backup
157+
else:
158+
os.environ.pop("GRPC_SSL_CIPHER_SUITES", None)

0 commit comments

Comments
 (0)