Skip to content

Commit 36039a3

Browse files
authored
feat: more provider status (#48)
The CR status field will now report the provider's health and configuration. Approved-by: VaishnaviHire Approved-by: mfleader
1 parent 54fabed commit 36039a3

File tree

9 files changed

+167
-10
lines changed

9 files changed

+167
-10
lines changed

.github/workflows/run-e2e-test.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,21 @@ jobs:
8686
- name: Run e2e tests
8787
run: |
8888
make test-e2e
89+
90+
- name: Get logs
91+
if: ${{ always() }}
92+
run: |
93+
kubectl -n llama-stack-test get all -o yaml > all.log
94+
kubectl -n llama-stack-k8s-operator-system logs deployment.apps/llama-stack-k8s-operator-controller-manager > controller-manager.log
95+
kubectl -n llama-stack-test describe all > all-describe.log
96+
kubectl -n llama-stack-test describe events > events.log
97+
kubectl get llamastackdistributions --all-namespaces -o yaml > llamastackdistributions.log
98+
99+
- name: Upload all logs to artifacts
100+
if: ${{ always() }}
101+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
102+
with:
103+
name: logs-${{ github.run_id }}-${{ github.run_attempt }}
104+
path: |
105+
*.log
106+
retention-days: 1

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ api-docs: crd-ref-docs ## Creates API docs using https://github.com/elastic/crd-
301301
mkdir -p docs
302302
$(CRD_REF_DOCS) --source-path ./ --output-path $(API_DOCS_PATH) --renderer markdown --config ./crd-ref-docs.config.yaml
303303
@# Combined command to remove .io links, ensure a trailing newline, and collapse multiple blank lines.
304-
@sed -i.bak -e '/\.io\/[^v][^1].*)/d' -e '/^$$/N;/^\n$$/D' $(API_DOCS_PATH)
304+
@sed -i.bak -e '/^$$/N;/^\n$$/D' $(API_DOCS_PATH)
305305
@# BSD sed doesn't generate trailing newlines, so no need to remove them.
306306
@# BSD sed does not have a '--version' flag, so we need to check for it.
307307
@if sed --version >/dev/null 2>&1; then \

api/v1alpha1/llamastackdistribution_types.go

Lines changed: 12 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/llamastack.io_llamastackdistributions.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,12 +2008,28 @@ spec:
20082008
properties:
20092009
api:
20102010
type: string
2011+
config:
2012+
x-kubernetes-preserve-unknown-fields: true
2013+
health:
2014+
description: HealthStatus represents the health status of
2015+
a provider
2016+
properties:
2017+
message:
2018+
type: string
2019+
status:
2020+
type: string
2021+
required:
2022+
- message
2023+
- status
2024+
type: object
20112025
provider_id:
20122026
type: string
20132027
provider_type:
20142028
type: string
20152029
required:
20162030
- api
2031+
- config
2032+
- health
20172033
- provider_id
20182034
- provider_type
20192035
type: object

docs/api-overview.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ _Appears in:_
2222
| --- | --- | --- | --- |
2323
| `name` _string_ | | llama-stack | |
2424
| `port` _integer_ | | | |
25+
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#resourcerequirements-v1-core)_ | | | |
26+
| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#envvar-v1-core) array_ | | | |
2527

2628
#### DistributionConfig
2729

@@ -59,6 +61,7 @@ _Appears in:_
5961
| `kind` _string_ | `LlamaStackDistribution` | | |
6062
| `kind` _string_ | Kind is a string value representing the REST resource this object represents.<br />Servers may infer this from the endpoint the client submits requests to.<br />Cannot be updated.<br />In CamelCase.<br />More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds | | |
6163
| `apiVersion` _string_ | APIVersion defines the versioned schema of this representation of an object.<br />Servers should convert recognized schemas to the latest internal value, and<br />may reject unrecognized values.<br />More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources | | |
64+
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
6265
| `spec` _[LlamaStackDistributionSpec](#llamastackdistributionspec)_ | | | |
6366
| `status` _[LlamaStackDistributionStatus](#llamastackdistributionstatus)_ | | | |
6467

@@ -72,6 +75,7 @@ LlamaStackDistributionList contains a list of LlamaStackDistribution.
7275
| `kind` _string_ | `LlamaStackDistributionList` | | |
7376
| `kind` _string_ | Kind is a string value representing the REST resource this object represents.<br />Servers may infer this from the endpoint the client submits requests to.<br />Cannot be updated.<br />In CamelCase.<br />More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds | | |
7477
| `apiVersion` _string_ | APIVersion defines the versioned schema of this representation of an object.<br />Servers should convert recognized schemas to the latest internal value, and<br />may reject unrecognized values.<br />More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources | | |
78+
| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | |
7579
| `items` _[LlamaStackDistribution](#llamastackdistribution) array_ | | | |
7680

7781
#### LlamaStackDistributionSpec
@@ -108,6 +112,20 @@ _Appears in:_
108112

109113
| Field | Description | Default | Validation |
110114
| --- | --- | --- | --- |
115+
| `volumes` _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#volume-v1-core) array_ | | | |
116+
| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#volumemount-v1-core) array_ | | | |
117+
118+
#### ProviderHealthStatus
119+
120+
HealthStatus represents the health status of a provider
121+
122+
_Appears in:_
123+
- [ProviderInfo](#providerinfo)
124+
125+
| Field | Description | Default | Validation |
126+
| --- | --- | --- | --- |
127+
| `status` _string_ | | | |
128+
| `message` _string_ | | | |
111129

112130
#### ProviderInfo
113131

@@ -121,6 +139,8 @@ _Appears in:_
121139
| `api` _string_ | | | |
122140
| `provider_id` _string_ | | | |
123141
| `provider_type` _string_ | | | |
142+
| `config` _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#json-v1-apiextensions-k8s-io)_ | | | |
143+
| `health` _[ProviderHealthStatus](#providerhealthstatus)_ | | | |
124144

125145
#### ServerSpec
126146

@@ -145,4 +165,5 @@ _Appears in:_
145165

146166
| Field | Description | Default | Validation |
147167
| --- | --- | --- | --- |
168+
| `size` _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#quantity-resource-api)_ | Size is the size of the persistent volume claim created for holding persistent data of the llama-stack server | | |
148169
| `mountPath` _string_ | MountPath is the path where the storage will be mounted in the container | | |

release/operator.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,12 +2017,28 @@ spec:
20172017
properties:
20182018
api:
20192019
type: string
2020+
config:
2021+
x-kubernetes-preserve-unknown-fields: true
2022+
health:
2023+
description: HealthStatus represents the health status of
2024+
a provider
2025+
properties:
2026+
message:
2027+
type: string
2028+
status:
2029+
type: string
2030+
required:
2031+
- message
2032+
- status
2033+
type: object
20202034
provider_id:
20212035
type: string
20222036
provider_type:
20232037
type: string
20242038
required:
20252039
- api
2040+
- config
2041+
- health
20262042
- provider_id
20272043
- provider_type
20282044
type: object

tests/e2e/creation_test.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package e2e
33

44
import (
55
"context"
6+
"os"
67
"testing"
78
"time"
89

910
"github.com/llamastack/llama-stack-k8s-operator/api/v1alpha1"
1011
"github.com/stretchr/testify/require"
12+
"gopkg.in/yaml.v2"
1113
appsv1 "k8s.io/api/apps/v1"
1214
corev1 "k8s.io/api/core/v1"
1315
k8serrors "k8s.io/apimachinery/pkg/api/errors"
@@ -202,9 +204,22 @@ func testDistributionStatus(t *testing.T, llsdistributionCR *v1alpha1.LlamaStack
202204
return false, nil
203205
}
204206

207+
// Verify that providers have config and health info
208+
if len(updatedDistribution.Status.DistributionConfig.Providers) == 0 {
209+
return false, nil
210+
}
211+
205212
return true, nil
206213
})
207-
require.NoError(t, err, "Failed to wait for distribution status update")
214+
if err != nil {
215+
// Get the final state to print on error
216+
finalDistribution := &v1alpha1.LlamaStackDistribution{}
217+
TestEnv.Client.Get(TestEnv.Ctx, client.ObjectKey{
218+
Namespace: llsdistributionCR.Namespace,
219+
Name: llsdistributionCR.Name,
220+
}, finalDistribution)
221+
require.NoError(t, err, "Failed to wait for distribution status update", finalDistribution.Status)
222+
}
208223

209224
// Get final state and verify
210225
updatedDistribution := &v1alpha1.LlamaStackDistribution{}
@@ -220,6 +235,39 @@ func testDistributionStatus(t *testing.T, llsdistributionCR *v1alpha1.LlamaStack
220235
require.Equal(t, updatedDistribution.Spec.Server.Distribution.Name,
221236
updatedDistribution.Status.DistributionConfig.ActiveDistribution,
222237
"Active distribution should match the spec")
238+
239+
// Verify provider config and health
240+
require.NotEmpty(t, updatedDistribution.Status.DistributionConfig.Providers,
241+
"Providers should be populated")
242+
243+
// Verify that each provider has config and health info
244+
for _, provider := range updatedDistribution.Status.DistributionConfig.Providers {
245+
require.NotEmpty(t, provider.API, "Provider should have API info")
246+
require.NotEmpty(t, provider.ProviderID, "Provider should have ProviderID info")
247+
require.NotEmpty(t, provider.ProviderType, "Provider should have ProviderType info")
248+
require.NotNil(t, provider.Config, "Provider should have config info")
249+
// If Ollama test it returns OK status
250+
if provider.ProviderID == "ollama" {
251+
require.Equal(t, "OK", provider.Health.Status, "Provider should have OK health status")
252+
}
253+
// Check that status is one of the allowed values
254+
require.Contains(t, []string{"OK", "Error", "Not Implemented"}, provider.Health.Status, "Provider health status should be one of: OK, Error, Not Implemented")
255+
// There is no message for OK status
256+
if provider.Health.Status != "OK" {
257+
require.NotEmpty(t, provider.Health.Message, "Provider should have health message")
258+
}
259+
require.NotEmpty(t, provider.Config, "Provider config should not be empty")
260+
}
261+
262+
// Write the final distribution status to a file for CI to collect
263+
yaml, err := yaml.Marshal(updatedDistribution)
264+
if err != nil {
265+
t.Fatalf("Failed to marshal distribution: %v", err)
266+
}
267+
// Weak - do this better to write to a temp file and then move it to the right place at the
268+
// repo's root so the CI agent can collect it
269+
err = os.WriteFile("../../distribution.log", yaml, 0644)
270+
require.NoError(t, err)
223271
}
224272

225273
func testPVCConfiguration(t *testing.T, distribution *v1alpha1.LlamaStackDistribution) {

tests/e2e/e2e_test.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@ func TestE2E(t *testing.T) {
1010
// Run validation tests
1111
t.Run("validation", TestValidationSuite)
1212

13-
// // Run creation tests
14-
t.Run("creation", TestCreationSuite)
13+
// Track if creation tests passed
14+
creationFailed := false
1515

16-
// Run deletion tests if not skipped
17-
t.Run("deletion", TestDeletionSuite)
16+
// Run creation tests
17+
t.Run("creation", func(t *testing.T) {
18+
TestCreationSuite(t)
19+
creationFailed = t.Failed()
20+
})
21+
22+
// Run deletion tests only if creation passed
23+
if !creationFailed {
24+
t.Run("deletion", TestDeletionSuite)
25+
} else {
26+
t.Log("Skipping deletion tests due to creation test failures")
27+
}
1828
}

0 commit comments

Comments
 (0)