Skip to content

Commit 0715c8b

Browse files
author
Patrick J. McNerthney
committed
Implement ConfigMap and Secret based python packages.
1 parent fb6f050 commit 0715c8b

25 files changed

+780
-301
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,6 @@ cython_debug/
209209
marimo/_static/
210210
marimo/_lsp/
211211
__marimo__/
212+
213+
# function-pythonic
214+
pythonic-packages/

Dockerfile

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,21 @@
1-
# syntax=docker/dockerfile:1
1+
FROM python:3.13-slim-trixie AS image
22

3-
# It's important that this is Debian 12 to match the distroless image.
4-
FROM debian:12-slim AS build
5-
6-
#RUN --mount=type=cache,target=/var/lib/apt/lists \
7-
# --mount=type=cache,target=/var/cache/apt \
8-
RUN \
9-
rm -f /etc/apt/apt.conf.d/docker-clean \
10-
&& apt-get update \
11-
&& apt-get install --no-install-recommends --yes python3-venv git
12-
13-
# Don't write .pyc bytecode files. These speed up imports when the program is
14-
# loaded. There's no point doing that in a container where they'll never be
15-
# persisted across restarts.
16-
ENV PYTHONDONTWRITEBYTECODE=true
17-
18-
# Use Hatch to build a wheel. The build stage must do this in a venv because
19-
# Debian doesn't have a hatch package, and it won't let you install one globally
20-
# using pip.
21-
WORKDIR /build
22-
#RUN --mount=target=. \
23-
# --mount=type=cache,target=/root/.cache/pip \
24-
COPY . /build
25-
RUN \
26-
python3 -m venv /venv/build \
27-
&& /venv/build/bin/pip install hatch \
28-
&& /venv/build/bin/hatch build -t wheel /whl
29-
30-
# Create a fresh venv and install only the pythonic wheel into it.
31-
#RUN --mount=type=cache,target=/root/.cache/pip \
3+
WORKDIR /root/pythonic
4+
COPY pyproject.toml /root/pythonic
5+
COPY crossplane /root/pythonic/crossplane
6+
WORKDIR /
327
RUN \
33-
python3 -m venv /venv/fn \
34-
&& /venv/fn/bin/pip install /whl/*.whl
8+
set -eux && \
9+
cd /root/pythonic && \
10+
pip install --root-user-action ignore --no-build-isolation setuptools==80.9.0 && \
11+
pip install --root-user-action ignore --no-build-isolation . && \
12+
pip uninstall --root-user-action ignore --yes setuptools && \
13+
cd .. && \
14+
rm -rf .cache pythonic && \
15+
groupadd --gid 2000 pythonic && \
16+
useradd --uid 2000 --gid pythonic --home-dir /opt/pythonic --create-home --shell /usr/sbin/nologin pythonic
3517

36-
# Copy the pythonic venv to our runtime stage. It's important that the path be
37-
# the same as in the build stage, to avoid shebang paths and symlinks breaking.
38-
FROM gcr.io/distroless/python3-debian12 AS image
39-
WORKDIR /
40-
USER nonroot:nonroot
41-
COPY --from=build --chown=nonroot:nonroot /venv/fn /venv/fn
18+
USER pythonic:pythonic
19+
WORKDIR /opt/pythonic
4220
EXPOSE 9443
43-
ENTRYPOINT ["/venv/fn/bin/pythonic"]
21+
ENTRYPOINT ["python", "-m", "crossplane.pythonic.main"]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ The BaseComposite class provides the following fields for manipulating the Compo
181181
| self.status | Map | The composite desired and observed status, read from observed if not in desired |
182182
| self.conditions | Conditions | The composite desired and observed conditions, read from observed if not in desired |
183183
| self.connection | Connection | The composite desired and observed connection detials, read from observed if not in desired |
184-
| self.results | Results | Returned results on the Composite and optionally on the Claim |
184+
| self.events | Events | Returned events against the Composite and optionally on the Claim |
185185
| self.ready | Boolean | The composite desired ready state |
186186

187187
The BaseComposite also provides access to the following Crossplane Function level features:

crossplane/pythonic/__version__.py

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

crossplane/pythonic/composite.py

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, request, response, logger):
3232
self.status = Status(self.observed.status, self.desired.status)
3333
self.conditions = Conditions(observed, self.response)
3434
self.connection = Connection(observed, desired)
35-
self.results = Results(self.response)
35+
self.events = Events(self.response)
3636

3737
@property
3838
def ttl(self):
@@ -235,6 +235,33 @@ def __getattr__(self, key):
235235
def __getitem__(self, key):
236236
return RequiredResources(self._composite, key)
237237

238+
def __bool__(self):
239+
return bool(len(self))
240+
241+
def __len__(self):
242+
names = set()
243+
for name, resource in self._composite.request.extra_resources:
244+
names.add(name)
245+
for name, resource in self._composite.response.requirements.extra_resources:
246+
names.add(name)
247+
return len(names)
248+
249+
def __contains__(self, key):
250+
if key in self._composite.request.extra_resources:
251+
return True
252+
if key in self._composite.response.desired.resources:
253+
return True
254+
return False
255+
256+
def __iter__(self):
257+
names = set()
258+
for name, resource in self._composite.request.extra_resources:
259+
names.add(name)
260+
for name, resource in self._composite.response.requirements.extra_resources:
261+
names.add(name)
262+
for name in sorted(names):
263+
yield name, self[name]
264+
238265

239266
class RequiredResources:
240267
def __init__(self, composite, name):
@@ -384,14 +411,14 @@ def _protobuf_value(self):
384411
value['lastTransitionTime'] = time.isoformat().replace('+00:00', 'Z')
385412
return value
386413

387-
def __call__(self, status=_notset, reason=_notset, message=_notset, claim=_notset):
414+
def __call__(self, reason=_notset, message=_notset, status=_notset, claim=_notset):
388415
self._find_condition(True)
389-
if status != _notset:
390-
self.status = status
391416
if reason != _notset:
392417
self.reason = reason
393418
if message != _notset:
394419
self.message = message
420+
if status != _notset:
421+
self.status = status
395422
if claim != _notset:
396423
self.claim = claim
397424
return self
@@ -514,39 +541,42 @@ def __setitem__(self, key, value):
514541
self._desired.connection_details[key] = value
515542

516543

517-
class Results:
544+
class Events:
518545
def __init__(self, response):
519546
self._results = response.results
520547

521-
def info(self, message, reason=_notset, claim=_notset):
522-
result = Result(self._results.append())
523-
result.info = True
524-
result.message = message
548+
def info(self, reason=_notset, message=_notset, claim=_notset):
549+
event = Event(self._results.append())
550+
event.info = True
525551
if reason != _notset:
526-
result.reason = reason
552+
event.reason = reason
553+
if message != _notset:
554+
event.message = message
527555
if claim != _notset:
528-
result.claim = claim
529-
return result
556+
event.claim = claim
557+
return event
530558

531-
def warning(self, message, reason=_notset, claim=_notset):
532-
result = Result(self._results.append())
533-
result.warning = True
534-
result.message = message
559+
def warning(self, reason=_notset, message=_notset, claim=_notset):
560+
event = Event(self._results.append())
561+
event.warning = True
535562
if reason != _notset:
536-
result.reason = reason
563+
event.reason = reason
564+
if message != _notset:
565+
event.message = message
537566
if claim != _notset:
538-
result.claim = claim
539-
return result
567+
event.claim = claim
568+
return event
540569

541-
def fatal(self, message, reason=_notset, claim=_notset):
542-
result = Result(self._results.append())
543-
result.fatal = True
544-
result.message = message
570+
def fatal(self, reason=_notset, message=_notset, claim=_notset):
571+
event = Event(self._results.append())
572+
event.fatal = True
545573
if reason != _notset:
546-
result.reason = reason
574+
event.reason = reason
575+
if message != _notset:
576+
event.message = message
547577
if claim != _notset:
548-
result.claim = claim
549-
return result
578+
event.claim = claim
579+
return event
550580

551581
def __bool__(self):
552582
return len(self) > 0
@@ -556,15 +586,15 @@ def __len__(self):
556586

557587
def __getitem__(self, key):
558588
if key >= len(self._results):
559-
return Result()
560-
return Result(self._results[ix])
589+
return Event()
590+
return Event(self._results[ix])
561591

562592
def __iter__(self):
563593
for ix in range(len(self._results)):
564594
yield self[ix]
565595

566596

567-
class Result:
597+
class Event:
568598
def __init__(self, result=None):
569599
self._result = result
570600

0 commit comments

Comments
 (0)