Skip to content

Commit 496b8c1

Browse files
feat: Knative deployment support
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 0b8d777 commit 496b8c1

File tree

9 files changed

+857
-1
lines changed

9 files changed

+857
-1
lines changed

config/systems.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,5 +234,44 @@
234234
}
235235
}
236236
}
237+
},
238+
"knative": {
239+
"languages": {
240+
"python": {
241+
"base_images": {
242+
"3.9": "python:3.9-slim",
243+
"3.10": "python:3.10-slim"
244+
},
245+
"images": [
246+
"build",
247+
"run"
248+
],
249+
"username": "docker_user",
250+
"deployment": {
251+
"files": [
252+
"handler.py",
253+
"storage.py"
254+
],
255+
"packages": []
256+
}
257+
},
258+
"nodejs": {
259+
"base_images": {
260+
"latest": "node:latest"
261+
},
262+
"images": [
263+
"build",
264+
"run"
265+
],
266+
"username": "docker_user",
267+
"deployment": {
268+
"files": [
269+
"handler.js",
270+
"storage.js"
271+
],
272+
"packages": []
273+
}
274+
}
275+
}
237276
}
238277
}

sebs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def common_params(func):
8888
@click.option(
8989
"--deployment",
9090
default=None,
91-
type=click.Choice(["azure", "aws", "gcp", "local", "openwhisk"]),
91+
type=click.Choice(["azure", "aws", "gcp", "local", "openwhisk", "knative"]),
9292
help="Cloud deployment to use.",
9393
)
9494
@click.option(

sebs/faas/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ def deserialize(config: dict, cache: Cache, handlers: LoggingHandlers) -> Config
204204
from sebs.openwhisk.config import OpenWhiskConfig
205205

206206
implementations["openwhisk"] = OpenWhiskConfig.deserialize
207+
if has_platform("knative"):
208+
from sebs.knative.config import KnativeConfig
209+
210+
implementations["knative"] = KnativeConfig.deserialize
207211
func = implementations.get(name)
208212
assert func, "Unknown config type!"
209213
return func(config[name] if name in config else config, cache, handlers)

sebs/knative/config.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
from sebs.cache import Cache
2+
from sebs.faas.config import Credentials, Resources, Config
3+
from sebs.utils import LoggingHandlers
4+
from sebs.storage.config import MinioConfig
5+
6+
from typing import cast, Optional
7+
8+
9+
class KnativeCredentials(Credentials):
10+
@staticmethod
11+
def deserialize(config: dict, cache: Cache, handlers: LoggingHandlers) -> Credentials:
12+
return KnativeCredentials()
13+
14+
def serialize(self) -> dict:
15+
return {}
16+
17+
18+
class KnativeResources(Resources):
19+
def __init__(
20+
self,
21+
registry: Optional[str] = None,
22+
username: Optional[str] = None,
23+
password: Optional[str] = None,
24+
registry_updated: bool = False,
25+
):
26+
super().__init__(name="knative")
27+
self._docker_registry = registry if registry != "" else None
28+
self._docker_username = username if username != "" else None
29+
self._docker_password = password if password != "" else None
30+
self._registry_updated = registry_updated
31+
self._storage: Optional[MinioConfig] = None
32+
self._storage_updated = False
33+
34+
@staticmethod
35+
def typename() -> str:
36+
return "Knative.Resources"
37+
38+
@property
39+
def docker_registry(self) -> Optional[str]:
40+
return self._docker_registry
41+
42+
@property
43+
def docker_username(self) -> Optional[str]:
44+
return self._docker_username
45+
46+
@property
47+
def docker_password(self) -> Optional[str]:
48+
return self._docker_password
49+
50+
@property
51+
def storage_config(self) -> Optional[MinioConfig]:
52+
return self._storage
53+
54+
@property
55+
def storage_updated(self) -> bool:
56+
return self._storage_updated
57+
58+
@property
59+
def registry_updated(self) -> bool:
60+
return self._registry_updated
61+
62+
@staticmethod
63+
def initialize(res: Resources, dct: dict):
64+
ret = cast(KnativeResources, res)
65+
ret._docker_registry = dct["registry"]
66+
ret._docker_username = dct["username"]
67+
ret._docker_password = dct["password"]
68+
69+
@staticmethod
70+
def deserialize(config: dict, cache: Cache, handlers: LoggingHandlers) -> Resources:
71+
72+
cached_config = cache.get_config("knative")
73+
ret = KnativeResources()
74+
if cached_config:
75+
super(KnativeResources, KnativeResources).initialize(
76+
ret, cached_config["resources"]
77+
)
78+
79+
# Check for new config - overrides but check if it's different
80+
if "docker_registry" in config:
81+
82+
KnativeResources.initialize(ret, config["docker_registry"])
83+
ret.logging.info("Using user-provided Docker registry for Knative.")
84+
ret.logging_handlers = handlers
85+
86+
# check if there has been an update
87+
if not (
88+
cached_config
89+
and "resources" in cached_config
90+
and "docker" in cached_config["resources"]
91+
and cached_config["resources"]["docker"] == config["docker_registry"]
92+
):
93+
ret._registry_updated = True
94+
95+
# Load cached values
96+
elif (
97+
cached_config
98+
and "resources" in cached_config
99+
and "docker" in cached_config["resources"]
100+
):
101+
KnativeResources.initialize(ret, cached_config["resources"]["docker"])
102+
ret.logging_handlers = handlers
103+
ret.logging.info("Using cached Docker registry for Knative")
104+
else:
105+
ret = KnativeResources()
106+
ret.logging.info("Using default Docker registry for Knative.")
107+
ret.logging_handlers = handlers
108+
ret._registry_updated = True
109+
110+
# Check for new config
111+
if "storage" in config:
112+
ret._storage = MinioConfig.deserialize(config["storage"])
113+
ret.logging.info("Using user-provided configuration of storage for Knative.")
114+
115+
# check if there has been an update
116+
if not (
117+
cached_config
118+
and "resources" in cached_config
119+
and "storage" in cached_config["resources"]
120+
and cached_config["resources"]["storage"] == config["storage"]
121+
):
122+
ret.logging.info(
123+
"User-provided configuration is different from cached storage, "
124+
"we will update existing Knative actions."
125+
)
126+
ret._storage_updated = True
127+
128+
# Load cached values
129+
elif (
130+
cached_config
131+
and "resources" in cached_config
132+
and "storage" in cached_config["resources"]
133+
):
134+
ret._storage = MinioConfig.deserialize(cached_config["resources"]["storage"])
135+
ret.logging.info("Using cached configuration of storage for Knative.")
136+
137+
return ret
138+
139+
def update_cache(self, cache: Cache):
140+
super().update_cache(cache)
141+
cache.update_config(
142+
val=self.docker_registry, keys=["knative", "resources", "docker", "registry"]
143+
)
144+
cache.update_config(
145+
val=self.docker_username, keys=["knative", "resources", "docker", "username"]
146+
)
147+
cache.update_config(
148+
val=self.docker_password, keys=["knative", "resources", "docker", "password"]
149+
)
150+
if self._storage:
151+
self._storage.update_cache(["knative", "resources", "storage"], cache)
152+
153+
def serialize(self) -> dict:
154+
out: dict = {
155+
**super().serialize(),
156+
"docker_registry": self.docker_registry,
157+
"docker_username": self.docker_username,
158+
"docker_password": self.docker_password,
159+
}
160+
if self._storage:
161+
out = {**out, "storage": self._storage.serialize()}
162+
return out
163+
164+
165+
class KnativeConfig(Config):
166+
name: str
167+
shutdownStorage: bool
168+
cache: Cache
169+
170+
def __init__(self, config: dict, cache: Cache):
171+
super().__init__(name="knative")
172+
self._credentials = KnativeCredentials()
173+
self._resources = KnativeResources()
174+
self.shutdownStorage = config["shutdownStorage"]
175+
self.removeCluster = config["removeCluster"]
176+
self.knative_exec = config["knativeExec"]
177+
self.knative_bypass_security = config["knativeBypassSecurity"]
178+
self.experimentalManifest = config["experimentalManifest"]
179+
self.cache = cache
180+
181+
@property
182+
def credentials(self) -> KnativeCredentials:
183+
return self._credentials
184+
185+
@property
186+
def resources(self) -> KnativeResources:
187+
return self._resources
188+
189+
@staticmethod
190+
def initialize(cfg: Config, dct: dict):
191+
cfg._region = dct["region"]
192+
193+
def serialize(self) -> dict:
194+
return {
195+
"name": self._name,
196+
"region": self._region,
197+
"shutdownStorage": self.shutdownStorage,
198+
"removeCluster": self.removeCluster,
199+
"knativeExec": self.knative_exec,
200+
"knativeBypassSecurity": self.knative_bypass_security,
201+
"experimentalManifest": self.experimentalManifest,
202+
"credentials": self._credentials.serialize(),
203+
"resources": self._resources.serialize(),
204+
}
205+
206+
@staticmethod
207+
def deserialize(config: dict, cache: Cache, handlers: LoggingHandlers) -> Config:
208+
cached_config = cache.get_config("knative")
209+
resources = cast(
210+
KnativeResources, KnativeResources.deserialize(config, cache, handlers)
211+
)
212+
213+
res = KnativeConfig(config, cached_config)
214+
res.logging_handlers = handlers
215+
res._resources = resources
216+
return res
217+
218+
def update_cache(self, cache: Cache):
219+
cache.update_config(val=self.shutdownStorage, keys=["knative", "shutdownStorage"])
220+
cache.update_config(val=self.removeCluster, keys=["knative", "removeCluster"])
221+
cache.update_config(val=self.knative_exec, keys=["knative", "knativeExec"])
222+
cache.update_config(val=self.knative_bypass_security, keys=["knative", "knativeBypassSecurity"])
223+
cache.update_config(
224+
val=self.experimentalManifest, keys=["knative", "experimentalManifest"]
225+
)
226+
self.resources.update_cache(cache)

0 commit comments

Comments
 (0)