@effect/cluster 0.53.3 → 0.53.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/K8sHttpClient/package.json +6 -0
- package/dist/cjs/EntityResource.js +16 -1
- package/dist/cjs/EntityResource.js.map +1 -1
- package/dist/cjs/K8sHttpClient.js +164 -0
- package/dist/cjs/K8sHttpClient.js.map +1 -0
- package/dist/cjs/RunnerHealth.js +3 -63
- package/dist/cjs/RunnerHealth.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/dts/EntityResource.d.ts +9 -0
- package/dist/dts/EntityResource.d.ts.map +1 -1
- package/dist/dts/K8sHttpClient.d.ts +91 -0
- package/dist/dts/K8sHttpClient.d.ts.map +1 -0
- package/dist/dts/RunnerHealth.d.ts +3 -4
- package/dist/dts/RunnerHealth.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/EntityResource.js +15 -0
- package/dist/esm/EntityResource.js.map +1 -1
- package/dist/esm/K8sHttpClient.js +153 -0
- package/dist/esm/K8sHttpClient.js.map +1 -0
- package/dist/esm/RunnerHealth.js +3 -63
- package/dist/esm/RunnerHealth.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +14 -3
- package/src/EntityResource.ts +30 -0
- package/src/K8sHttpClient.ts +240 -0
- package/src/RunnerHealth.ts +4 -79
- package/src/index.ts +5 -0
package/src/RunnerHealth.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
|
-
import * as FileSystem from "@effect/platform/FileSystem"
|
|
5
|
-
import * as HttpClient from "@effect/platform/HttpClient"
|
|
6
|
-
import * as HttpClientRequest from "@effect/platform/HttpClientRequest"
|
|
7
|
-
import * as HttpClientResponse from "@effect/platform/HttpClientResponse"
|
|
8
4
|
import * as Context from "effect/Context"
|
|
9
5
|
import * as Effect from "effect/Effect"
|
|
10
|
-
import { identity } from "effect/Function"
|
|
11
6
|
import * as Layer from "effect/Layer"
|
|
12
7
|
import * as Schedule from "effect/Schedule"
|
|
13
|
-
import * as Schema from "effect/Schema"
|
|
14
8
|
import type * as Scope from "effect/Scope"
|
|
9
|
+
import * as K8s from "./K8sHttpClient.js"
|
|
15
10
|
import type { RunnerAddress } from "./RunnerAddress.js"
|
|
16
11
|
import * as Runners from "./Runners.js"
|
|
17
12
|
|
|
@@ -87,87 +82,17 @@ export const makeK8s = Effect.fnUntraced(function*(options?: {
|
|
|
87
82
|
readonly namespace?: string | undefined
|
|
88
83
|
readonly labelSelector?: string | undefined
|
|
89
84
|
}) {
|
|
90
|
-
const
|
|
91
|
-
const token = yield* fs.readFileString("/var/run/secrets/kubernetes.io/serviceaccount/token").pipe(
|
|
92
|
-
Effect.option
|
|
93
|
-
)
|
|
94
|
-
const client = (yield* HttpClient.HttpClient).pipe(
|
|
95
|
-
HttpClient.filterStatusOk
|
|
96
|
-
)
|
|
97
|
-
const baseRequest = HttpClientRequest.get("https://kubernetes.default.svc/api").pipe(
|
|
98
|
-
token._tag === "Some" ? HttpClientRequest.bearerToken(token.value.trim()) : identity
|
|
99
|
-
)
|
|
100
|
-
const getPods = baseRequest.pipe(
|
|
101
|
-
HttpClientRequest.appendUrl(options?.namespace ? `/v1/namespaces/${options.namespace}/pods` : "/v1/pods"),
|
|
102
|
-
HttpClientRequest.setUrlParam("fieldSelector", "status.phase=Running"),
|
|
103
|
-
options?.labelSelector ? HttpClientRequest.setUrlParam("labelSelector", options.labelSelector) : identity
|
|
104
|
-
)
|
|
105
|
-
const allPods = yield* client.execute(getPods).pipe(
|
|
106
|
-
Effect.flatMap(HttpClientResponse.schemaBodyJson(PodList)),
|
|
107
|
-
Effect.map((list) => {
|
|
108
|
-
const pods = new Map<string, Pod>()
|
|
109
|
-
for (let i = 0; i < list.items.length; i++) {
|
|
110
|
-
const pod = list.items[i]
|
|
111
|
-
pods.set(pod.status.podIP, pod)
|
|
112
|
-
}
|
|
113
|
-
return pods
|
|
114
|
-
}),
|
|
115
|
-
Effect.tapErrorCause((cause) => Effect.logWarning("Failed to fetch pods from Kubernetes API", cause)),
|
|
116
|
-
Effect.cachedWithTTL("10 seconds")
|
|
117
|
-
)
|
|
85
|
+
const allPods = yield* K8s.makeGetPods(options)
|
|
118
86
|
|
|
119
87
|
return RunnerHealth.of({
|
|
120
88
|
isAlive: (address) =>
|
|
121
89
|
allPods.pipe(
|
|
122
|
-
Effect.map((pods) => pods.get(address.host)?.
|
|
90
|
+
Effect.map((pods) => pods.get(address.host)?.isReadyOrInitializing ?? false),
|
|
123
91
|
Effect.catchAllCause(() => Effect.succeed(true))
|
|
124
92
|
)
|
|
125
93
|
})
|
|
126
94
|
})
|
|
127
95
|
|
|
128
|
-
class Pod extends Schema.Class<Pod>("effect/cluster/RunnerHealth/Pod")({
|
|
129
|
-
status: Schema.Struct({
|
|
130
|
-
phase: Schema.String,
|
|
131
|
-
conditions: Schema.Array(Schema.Struct({
|
|
132
|
-
type: Schema.String,
|
|
133
|
-
status: Schema.String,
|
|
134
|
-
lastTransitionTime: Schema.String
|
|
135
|
-
})),
|
|
136
|
-
podIP: Schema.String
|
|
137
|
-
})
|
|
138
|
-
}) {
|
|
139
|
-
get isReady(): boolean {
|
|
140
|
-
let initializedAt: string | undefined
|
|
141
|
-
let readyAt: string | undefined
|
|
142
|
-
for (let i = 0; i < this.status.conditions.length; i++) {
|
|
143
|
-
const condition = this.status.conditions[i]
|
|
144
|
-
switch (condition.type) {
|
|
145
|
-
case "Initialized": {
|
|
146
|
-
if (condition.status !== "True") {
|
|
147
|
-
return true
|
|
148
|
-
}
|
|
149
|
-
initializedAt = condition.lastTransitionTime
|
|
150
|
-
break
|
|
151
|
-
}
|
|
152
|
-
case "Ready": {
|
|
153
|
-
if (condition.status === "True") {
|
|
154
|
-
return true
|
|
155
|
-
}
|
|
156
|
-
readyAt = condition.lastTransitionTime
|
|
157
|
-
break
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// if the pod is still booting up, consider it ready as it would have
|
|
162
|
-
// already registered itself with RunnerStorage by now
|
|
163
|
-
return initializedAt === readyAt
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const PodList = Schema.Struct({
|
|
168
|
-
items: Schema.Array(Pod)
|
|
169
|
-
})
|
|
170
|
-
|
|
171
96
|
/**
|
|
172
97
|
* A layer which will check the Kubernetes API to see if a Runner is healthy.
|
|
173
98
|
*
|
|
@@ -188,5 +113,5 @@ export const layerK8s = (
|
|
|
188
113
|
): Layer.Layer<
|
|
189
114
|
RunnerHealth,
|
|
190
115
|
never,
|
|
191
|
-
|
|
116
|
+
K8s.K8sHttpClient
|
|
192
117
|
> => Layer.effect(RunnerHealth, makeK8s(options))
|