Add experimental support for kagent agents (#4399)

Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Signed-off-by: Cintia Sánchez García <cynthiasg@icloud.com>
Co-authored-by: Cintia Sánchez García <cynthiasg@icloud.com>
This commit is contained in:
Sergio Castaño Arteaga 2025-05-20 14:35:50 +02:00 committed by GitHub
parent 940ee344af
commit 9d6e03d0ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
54 changed files with 437 additions and 72 deletions

View File

@ -17,7 +17,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version: "1.24"
- name: Install TensorFlow C library
run: |
FILENAME=libtensorflow-cpu-linux-x86_64-2.11.0.tar.gz
@ -104,7 +104,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version: "1.24"
- name: Cache Go modules
uses: actions/cache@v4
with:
@ -183,7 +183,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version: "1.24"
- name: Cache Go modules
uses: actions/cache@v4
with:

View File

@ -18,7 +18,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"
go-version: "1.24"
- name: Login to Docker Hub
uses: docker/login-action@v3
with:

View File

@ -25,6 +25,7 @@ At the moment, the following artifacts kinds are supported *(with plans to suppo
- [Helm charts](https://helm.sh/)
- [Helm plugins](https://helm.sh/docs/topics/plugins/)
- [Inspektor Gadgets](https://www.inspektor-gadget.io)
- [Kagent agents](https://kagent.dev)
- [KCL modules](https://kcl-lang.io)
- [KEDA scalers](https://keda.sh/)
- [Keptn integrations](https://keptn.sh)

View File

@ -2,7 +2,7 @@ apiVersion: v2
name: artifact-hub
description: Artifact Hub is a web-based application that enables finding, installing, and publishing Cloud Native packages.
type: application
version: 1.21.0
version: 1.21.1-0
appVersion: 1.21.0
kubeVersion: ">= 1.19.0-0"
home: https://artifacthub.io
@ -34,6 +34,7 @@ keywords:
- opencost
- radius
- bootable containers
- kagent
maintainers:
- name: Sergio
email: tegioz@icloud.com

View File

@ -1224,7 +1224,7 @@
},
"repositoriesKinds": {
"title": "Repositories kinds to process ([] = all)",
"description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin, backstage, argo-template, kubearmor, kcl, headlamp, inspektor-gadget, tekton-stepaction, meshery, opencost, radius, bootc",
"description": "The following kinds are supported at the moment: falco, helm, olm, opa, tbaction, krew, helm-plugin, tekton-task, keda-scaler, coredns, keptn, tekton-pipeline, container, kubewarden, gatekeeper, kyverno, knative-client-plugin, backstage, argo-template, kubearmor, kcl, headlamp, inspektor-gadget, tekton-stepaction, meshery, opencost, radius, bootc, kagent",
"type": "array",
"items": {
"type": "string"

View File

@ -97,7 +97,7 @@ func newLintCmd() *cobra.Command {
return lint(opts, &output{cmd.OutOrStdout()})
},
}
lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: argo-template, backstage, bootc, coredns, falco, gatekeeper, headlamp, helm, helm-plugin, inspektor-gadget, kcl, keda-scaler, keptn, knative-client-plugin, krew, kubearmor, kubewarden, kyverno, meshery, olm, opa, opencost, radius, tbaction, tekton-pipeline, tekton-stepaction, tekton-task")
lintCmd.Flags().StringVarP(&opts.kind, "kind", "k", "helm", "repository kind: argo-template, backstage, bootc, coredns, falco, gatekeeper, headlamp, helm, helm-plugin, inspektor-gadget, kagent, kcl, keda-scaler, keptn, knative-client-plugin, krew, kubearmor, kubewarden, kyverno, meshery, olm, opa, opencost, radius, tbaction, tekton-pipeline, tekton-stepaction, tekton-task")
lintCmd.Flags().StringVarP(&opts.path, "path", "p", ".", "repository's packages path")
lintCmd.Flags().StringVarP(&opts.tektonVersioning, "tekton-versioning", "", hub.TektonDirBasedVersioning, "tekton versioning option: directory, git")
return lintCmd
@ -138,8 +138,8 @@ func lint(opts *lintOptions, out *output) error {
hub.Radius,
hub.TBAction:
report = lintGeneric(opts.path, kind)
case hub.Helm:
report = lintHelm(opts.path)
case hub.Helm, hub.Kagent:
report = lintHelm(opts.path, kind)
case hub.HelmPlugin:
report = lintHelmPlugin(opts.path)
case hub.Krew:
@ -216,7 +216,7 @@ func lintGeneric(basePath string, kind hub.RepositoryKind) *lintReport {
// lintHelm checks if the Helm charts available in the path provided are ready
// to be processed by the Helm tracker source and listed on Artifact Hub.
func lintHelm(basePath string) *lintReport {
func lintHelm(basePath string, kind hub.RepositoryKind) *lintReport {
report := &lintReport{}
// Walk the path provided looking for available charts
@ -252,7 +252,7 @@ func lintHelm(basePath string) *lintReport {
Name: chrt.Metadata.Name,
Version: chrt.Metadata.Version,
LogoURL: chrt.Metadata.Icon,
Repository: &hub.Repository{Kind: hub.Helm},
Repository: &hub.Repository{Kind: kind},
}
helm.EnrichPackageFromChart(e.pkg, chrt)
err = helm.EnrichPackageFromAnnotations(e.pkg, chrt.Metadata.Annotations)
@ -788,7 +788,7 @@ func (out *output) printPkgDetails(pkg *hub.Package) {
fmt.Fprintf(out, " - %s\n", name)
}
}
case hub.Helm:
case hub.Helm, hub.Kagent:
out.print("Sign key", pkg.SignKey)
// Values schema

View File

@ -0,0 +1,5 @@
insert into repository_kind values (28, 'Kagent agents');
---- create above / drop below ----
delete from repository_kind where repository_kind_id = 28;

View File

@ -570,7 +570,8 @@ select results_eq(
(24, 'Meshery designs'),
(25, 'OpenCost plugins'),
(26, 'Radius recipes'),
(27, 'Bootable containers')
(27, 'Bootable containers'),
(28, 'Kagent agents')
$$,
'Repository kinds should exist'
);

View File

@ -1368,6 +1368,29 @@ paths:
$ref: "#/components/responses/TooManyRequests"
"500":
$ref: "#/components/responses/InternalServerError"
"/packages/kagent/{repoName}/{packageName}":
get:
tags:
- Packages
summary: Get package details
description: Get package details
operationId: getKagentPackageDetails
parameters:
- $ref: "#/components/parameters/RepoNameParam"
- $ref: "#/components/parameters/PackageNameParam"
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: "#/components/schemas/KagentPackage"
"404":
$ref: "#/components/responses/NotFoundResponse"
"429":
$ref: "#/components/responses/TooManyRequests"
"500":
$ref: "#/components/responses/InternalServerError"
"/packages/kcl/{repoName}/{packageName}":
get:
tags:
@ -2024,6 +2047,30 @@ paths:
$ref: "#/components/responses/TooManyRequests"
"500":
$ref: "#/components/responses/InternalServerError"
"/packages/kagent/{repoName}/{packageName}/{version}":
get:
tags:
- Packages
summary: Get package version details
description: Get package version details
operationId: getKagentVersionDetails
parameters:
- $ref: "#/components/parameters/RepoNameParam"
- $ref: "#/components/parameters/PackageNameParam"
- $ref: "#/components/parameters/VersionParam"
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: "#/components/schemas/KagentPackage"
"404":
$ref: "#/components/responses/NotFoundResponse"
"429":
$ref: "#/components/responses/TooManyRequests"
"500":
$ref: "#/components/responses/InternalServerError"
"/packages/kcl/{repoName}/{packageName}/{version}":
get:
tags:
@ -4321,6 +4368,94 @@ components:
example: "sha256:123456..."
InspektorGadgetPackage:
$ref: "#/components/schemas/Package"
KagentPackage:
allOf:
- $ref: "#/components/schemas/Package"
- type: object
properties:
sign_key:
type: object
nullable: false
properties:
fingerprint:
type: string
nullable: false
example: "0011223344"
url:
type: string
format: uri
example: https://key.url
crds:
type: array
nullable: false
items:
type: object
required:
- kind
- name
- version
- description
- displayName
properties:
kind:
type: string
nullable: false
name:
type: string
nullable: false
version:
type: string
nullable: false
description:
type: string
nullable: false
displayName:
type: string
nullable: false
crds_examples:
type: array
nullable: false
items:
type: object
additionalProperties: true
data:
type: object
nullable: false
properties:
apiVersion:
type: string
example: v2
nullable: false
type:
type: string
example: application
nullable: false
kubeVersion:
type: string
example: ">=1.16.0-0"
nullable: false
dependencies:
type: array
items:
type: object
nullable: false
required:
- name
- version
- repository
properties:
name:
type: string
nullable: false
example: mysql
version:
type: string
nullable: false
example: 1.6.4
repository:
type: string
nullable: false
example: "http://repo.url"
KCLPackage:
$ref: "#/components/schemas/Package"
KedaScalerPackage:
@ -5134,6 +5269,7 @@ components:
* `25` - Opencost plugins
* `26` - Radius recipes
* `27` - Bootable containers
* `28` - Kagent agents
RepositoryKindParam:
type: string
enum:
@ -5165,6 +5301,7 @@ components:
- opencost
- radius
- bootc
- kagent
description: |
Repository kind name:
* `helm` - Helm charts
@ -5195,6 +5332,7 @@ components:
* `opencost` - Opencost plugins
* `radius` - Radius recipes
* `bootc` - Bootable containers
* `kagent` - Kagent agents
RepositorySummary:
type: object
required:
@ -5742,6 +5880,7 @@ components:
* `25` - Opencost plugins
* `26` - Radius recipes
* `27` - Bootable containers
* `28` - Kagent agents
PackageNameParam:
in: path
name: packageName

View File

@ -0,0 +1,3 @@
## Kagent agents repositories
Kagent agents are expected to be hosted in Helm chart repositories. Please see the Helm chart repositories section for more details about how to add your repository to Artifact Hub.

View File

@ -14,6 +14,7 @@ The following repositories kinds are supported at the moment:
- [Helm charts repositories](https://github.com/artifacthub/hub/blob/master/docs/helm_charts_repositories.md)
- [Helm plugins repositories](https://github.com/artifacthub/hub/blob/master/docs/helm_plugins_repositories.md)
- [Inspektor gadgets repositories](https://github.com/artifacthub/hub/blob/master/docs/inspektor_gadgets_repositories.md)
- [Kagent agents repositories](https://github.com/artifacthub/hub/blob/master/docs/kagents_agents_repositories.md)
- [KCL modules repositories](https://github.com/artifacthub/hub/blob/master/docs/kcl_modules_repositories.md)
- [KEDA scalers repositories](https://github.com/artifacthub/hub/blob/master/docs/keda_scalers_repositories.md)
- [Keptn integrations repositories](https://github.com/artifacthub/hub/blob/master/docs/keptn_integrations_repositories.md)

View File

@ -0,0 +1,6 @@
---
title: "Kagent agents"
aliases: [
"/kagent_agents_repositories",
]
---

View File

@ -265,7 +265,7 @@ func (h *Handlers) setupRouter() {
r.Get("/stats", h.Packages.GetStats)
r.With(corsMW).Get("/search", h.Packages.Search)
r.With(h.Users.RequireLogin).Get("/starred", h.Packages.GetStarredByUser)
r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction|^meshery|^opencost|^radius|^bootc$}/{repoName}/{packageName}", func(r chi.Router) {
r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction|^meshery|^opencost|^radius|^bootc|^kagent$}/{repoName}/{packageName}", func(r chi.Router) {
r.Get("/feed/rss", h.Packages.RssFeed)
r.With(corsMW).Get("/summary", h.Packages.GetSummary)
r.Get("/{version}", h.Packages.Get)
@ -430,7 +430,7 @@ func (h *Handlers) setupRouter() {
// Index special entry points
r.Route("/packages", func(r chi.Router) {
r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction|^meshery|^opencost|^radius|^bootc$}/{repoName}/{packageName}", func(r chi.Router) {
r.Route("/{^helm$|^falco$|^opa$|^olm|^tbaction|^krew|^helm-plugin|^tekton-task|^keda-scaler|^coredns|^keptn|^tekton-pipeline|^container|^kubewarden|^gatekeeper|^kyverno|^knative-client-plugin|^backstage|^argo-template|^kubearmor|^kcl|^headlamp|^inspektor-gadget|^tekton-stepaction|^meshery|^opencost|^radius|^bootc|^kagent$}/{repoName}/{packageName}", func(r chi.Router) {
r.With(h.Packages.InjectIndexMeta).Get("/{version}", h.Static.Index)
r.With(h.Packages.InjectIndexMeta).Get("/", h.Static.Index)
})

View File

@ -598,7 +598,8 @@ func (h *Handlers) getChartArchive(ctx context.Context, packageID, version strin
}
// Only Helm charts packages can have templates
if p.Repository.Kind != hub.Helm {
// (Kagent agents are distributed as Helm charts)
if p.Repository.Kind != hub.Helm && p.Repository.Kind != hub.Kagent {
return nil, fmt.Errorf("%w: operation not supported for this repository kind", hub.ErrInvalidInput)
}

View File

@ -2221,6 +2221,17 @@ func TestBuildURL(t *testing.T) {
"2.0.0",
baseURL + "/packages/bootc/repo1/pkg1/2.0.0",
},
{
&hub.Package{
NormalizedName: "pkg1",
Repository: &hub.Repository{
Kind: hub.Kagent,
Name: "repo1",
},
},
"2.0.0",
baseURL + "/packages/kagent/repo1/pkg1/2.0.0",
},
}
for _, tc := range testCases {
t.Run(tc.expectedPkgURL, func(t *testing.T) {

View File

@ -130,6 +130,9 @@ const (
// Bootc represents a repository with Bootable containers.
Bootc RepositoryKind = 27
// Kagent represents a repository with Kagent agents.
Kagent RepositoryKind = 28
)
// GetKindName returns the name of the provided repository kind.
@ -157,6 +160,8 @@ func GetKindName(kind RepositoryKind) string {
return "helm-plugin"
case InspektorGadget:
return "inspektor-gadget"
case Kagent:
return "kagent"
case KCL:
return "kcl"
case KedaScaler:
@ -222,6 +227,8 @@ func GetKindFromName(kind string) (RepositoryKind, error) {
return HelmPlugin, nil
case "inspektor-gadget":
return InspektorGadget, nil
case "kagent":
return Kagent, nil
case "kcl":
return KCL, nil
case "keda-scaler":

View File

@ -90,6 +90,7 @@ var (
hub.Helm,
hub.HelmPlugin,
hub.InspektorGadget,
hub.Kagent,
hub.KCL,
hub.KedaScaler,
hub.Keptn,
@ -462,7 +463,7 @@ func (m *Manager) locateMetadataFile(r *hub.Repository, basePath string) string
switch r.Kind {
case hub.Container:
mdFile = r.URL
case hub.Helm:
case hub.Helm, hub.Kagent:
switch u.Scheme {
case "http", "https":
u.Path = path.Join(u.Path, hub.RepositoryMetadataFile)
@ -562,7 +563,7 @@ func (m *Manager) GetRemoteDigest(ctx context.Context, r *hub.Repository) (strin
u, _ := url.Parse(r.URL)
switch {
case r.Kind == hub.Helm:
case r.Kind == hub.Helm || r.Kind == hub.Kagent:
switch {
case SchemeIsHTTP(u):
// Digest is obtained by hashing the repository index.yaml file
@ -833,7 +834,7 @@ func (m *Manager) validateURL(r *hub.Repository) error {
if !SchemeIsOCI(u) {
return errors.New("invalid url format")
}
case hub.Helm:
case hub.Helm, hub.Kagent:
if SchemeIsHTTP(u) {
if _, _, err := m.il.LoadIndex(r); err != nil {
log.Error().Err(err).Str("url", r.URL).Msg("error loading index")

View File

@ -104,7 +104,7 @@ func SetupSource(i *hub.TrackerSourceInput) hub.TrackerSource {
} else {
source = generic.NewTrackerSource(i)
}
case hub.Helm:
case hub.Helm, hub.Kagent:
source = helm.NewTrackerSource(i)
case hub.HelmPlugin:
source = helmplugin.NewTrackerSource(i)

View File

@ -175,7 +175,8 @@ func (t *Tracker) cloneRepository() (string, string, error) {
switch t.r.Kind {
case
hub.Container,
hub.Helm:
hub.Helm,
hub.Kagent:
// These repositories are not cloned
case hub.OLM:
if strings.HasPrefix(t.r.URL, hub.RepositoryOCIPrefix) {

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Categories on </title>
<link>/categories/</link>
<description>Recent content in Categories on </description>
<generator>Hugo</generator>
<language>en</language>
<atom:link href="/categories/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

11
public/index.xml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title></title>
<link>/</link>
<description>Recent content on </description>
<generator>Hugo</generator>
<language>en</language>
<atom:link href="/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

11
public/sitemap.xml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>/</loc>
</url><url>
<loc>/categories/</loc>
</url><url>
<loc>/tags/</loc>
</url>
</urlset>

11
public/tags/index.xml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Tags on </title>
<link>/tags/</link>
<description>Recent content in Tags on </description>
<generator>Hugo</generator>
<language>en</language>
<atom:link href="/tags/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View File

@ -17,6 +17,7 @@ cat docs/www/headers/headlamp_plugins_repositories docs/headlamp_plugins_reposit
cat docs/www/headers/helm_charts_repositories docs/helm_charts_repositories.md > docs/www/content/topics/repositories/helm-charts.md
cat docs/www/headers/helm_plugins_repositories docs/helm_plugins_repositories.md > docs/www/content/topics/repositories/helm-plugins.md
cat docs/www/headers/inspektor_gadgets_repositories docs/inspektor_gadgets_repositories.md > docs/www/content/topics/repositories/inspektor-gadgets.md
cat docs/www/headers/kagent_agents_repositories docs/kagent_agents_repositories.md > docs/www/content/topics/repositories/kagent-agents.md
cat docs/www/headers/kcl_modules_repositories docs/kcl_modules_repositories.md > docs/www/content/topics/repositories/kcl-modules.md
cat docs/www/headers/keda_scalers_repositories docs/keda_scalers_repositories.md > docs/www/content/topics/repositories/keda-scalers.md
cat docs/www/headers/keptn_integrations_repositories docs/keptn_integrations_repositories.md > docs/www/content/topics/repositories/keptn-integrations.md

View File

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<!-- Generator: imaengine 6.0 -->
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0,0,123,123" style="enable-background:new 0 0 123 123;" version="1.1">
<defs/>
<g id="layer0">
<path d="M92.0513,60.3285L76.7751,60.3285L76.7751,75.7025L92.0513,75.7025L92.0513,60.3285L92.0513,60.3285Z" fill="#FFFFFF"/>
<path d="M61.5229,60.3285L46.2468,60.3285L46.2468,75.7025L61.5229,75.7025L61.5229,60.3285L61.5229,60.3285Z" fill="#FFFFFF"/>
<path d="M107.303,29.6045L92.0274,14.2305L76.7752,14.2305L61.499,14.2305L46.2468,14.2305L30.9707,14.2305L30.9707,29.6045L15.7184,29.6045L15.7184,44.9545L0.442314,44.9545L0.442314,60.3285L0.442314,75.6784L15.7184,91.0525L30.9707,106.402L46.2468,106.402L61.499,106.402L76.7752,106.402L92.0274,106.402L107.303,106.402L107.303,91.0525L92.0274,91.0525L76.7752,91.0525L61.499,91.0525L46.2468,91.0525L30.9707,91.0525L30.9707,75.6784L30.9707,60.3285L30.9707,44.9545L46.2468,44.9545L61.499,44.9545L76.7752,44.9545L92.0274,44.9545L107.303,44.9545L107.303,60.3285L107.303,75.6784L107.303,91.0525L122.555,91.0525L122.555,75.6784L122.555,60.3285L122.555,44.9545L107.303,29.6045L107.303,29.6045Z" fill="#FFFFFF"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<!-- Generator: imaengine 6.0 -->
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0,0,123,123" style="enable-background:new 0 0 123 123;" version="1.1">
<defs/>
<g id="layer0">
<path d="M92.0513,60.3285L76.7751,60.3285L76.7751,75.7025L92.0513,75.7025L92.0513,60.3285L92.0513,60.3285Z" fill="#942DE7"/>
<path d="M61.5229,60.3285L46.2468,60.3285L46.2468,75.7025L61.5229,75.7025L61.5229,60.3285L61.5229,60.3285Z" fill="#942DE7"/>
<path d="M107.303,29.6045L92.0274,14.2305L76.7752,14.2305L61.499,14.2305L46.2468,14.2305L30.9707,14.2305L30.9707,29.6045L15.7184,29.6045L15.7184,44.9545L0.442314,44.9545L0.442314,60.3285L0.442314,75.6784L15.7184,91.0525L30.9707,106.402L46.2468,106.402L61.499,106.402L76.7752,106.402L92.0274,106.402L107.303,106.402L107.303,91.0525L92.0274,91.0525L76.7752,91.0525L61.499,91.0525L46.2468,91.0525L30.9707,91.0525L30.9707,75.6784L30.9707,60.3285L30.9707,44.9545L46.2468,44.9545L61.499,44.9545L76.7752,44.9545L92.0274,44.9545L107.303,44.9545L107.303,60.3285L107.303,75.6784L107.303,91.0525L122.555,91.0525L122.555,75.6784L122.555,60.3285L122.555,44.9545L107.303,29.6045L107.303,29.6045Z" fill="#942DE7"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -83,6 +83,8 @@ const Image = (props: Props) => {
return '/static/media/placeholder_pkg_radius.png';
case RepositoryKind.Bootc:
return '/static/media/placeholder_pkg_bootc.png';
case RepositoryKind.Kagent:
return '/static/media/placeholder_pkg_kagent.png';
default:
return PLACEHOLDER_SRC;
}

View File

@ -274,7 +274,7 @@ const PackageCard = (props: Props) => {
<div className="d-flex flex-row ms-auto">
{props.package.deprecated && <Deprecated className="d-inline mt-3 ms-2" />}
{(props.package.cncf || props.package.repository.cncf) && <CNCF className="d-inline mt-3 ms-2" />}
{props.package.repository.kind === RepositoryKind.Helm && (
{[RepositoryKind.Helm, RepositoryKind.Kagent].includes(props.package.repository.kind) && (
<ValuesSchemaBadge
hasValuesSchema={props.package.hasValuesSchema || false}
className="d-inline mt-3 ms-2"

View File

@ -121,6 +121,10 @@ const ICONS = {
default: '/static/media/bootc.svg',
white: '/static/media/bootc-light.svg',
},
[RepositoryKind.Kagent]: {
default: '/static/media/kagent.svg',
white: '/static/media/kagent-light.svg',
},
};
const RepositoryIcon = (props: Props) => {

View File

@ -33,6 +33,7 @@ const Signed = (props: Props) => {
RepositoryKind.TektonTask,
RepositoryKind.TektonStepAction,
RepositoryKind.Bootc,
RepositoryKind.Kagent,
].includes(props.repoKind);
return (

View File

@ -559,6 +559,17 @@ const RepositoryModal = (props: Props) => {
</ExternalLink>
);
break;
case RepositoryKind.Kagent:
link = (
<ExternalLink
href="/docs/topics/repositories/kagent-agents"
className="text-primary fw-bold"
label="Open documentation"
>
Kagent agents
</ExternalLink>
);
break;
}
if (isUndefined(link)) return;
@ -594,6 +605,7 @@ const RepositoryModal = (props: Props) => {
case RepositoryKind.OpenCost:
case RepositoryKind.RadiusRecipe:
case RepositoryKind.Bootc:
case RepositoryKind.Kagent:
return (
<>
<p
@ -667,6 +679,7 @@ const RepositoryModal = (props: Props) => {
const getURLPattern = (): string | undefined => {
switch (selectedKind) {
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
return undefined;
case RepositoryKind.OLM:
return `^((https?://)|${OCI_PREFIX}).*`;
@ -682,6 +695,7 @@ const RepositoryModal = (props: Props) => {
{(() => {
switch (selectedKind) {
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
case RepositoryKind.Container:
return (
<div className="row">
@ -1148,6 +1162,7 @@ const RepositoryModal = (props: Props) => {
RepositoryKind.OpenCost,
RepositoryKind.RadiusRecipe,
RepositoryKind.Bootc,
RepositoryKind.Kagent,
].includes(selectedKind) && (
<div className="mt-4 mb-3">
<div className="form-check form-switch ps-0">

View File

@ -114,6 +114,11 @@ exports[`Repository Modal - repositories section creates snapshot 1`] = `
>
Inspektor gadgets
</option>
<option
value="28"
>
Kagent agents
</option>
<option
value="20"
>

View File

@ -310,7 +310,7 @@ exports[`Home index creates snapshot 1`] = `
<div
class="text-center px-3 px-xs-0"
>
Artifact Hub is a web-based application that enables finding, installing, and publishing Cloud Native packages and configurations. For example, this could include Helm charts and plugins, Falco configurations, Open Policy Agent (OPA) and Gatekeeper policies, OLM operators, Tinkerbell actions, kubectl plugins, Tekton tasks, pipelines and stepactions, KEDA scalers, CoreDNS plugins, Keptn integrations, container images, Kubewarden policies, Kyverno policies, Knative client, Backstage plugins, Argo templates, KubeArmor policies, KCL modules, Headlamp plugins, Inspektor gadgets, Meshery designs, OpenCost plugins, Radius recipes and Bootable Containers.
Artifact Hub is a web-based application that enables finding, installing, and publishing Cloud Native packages and configurations. For example, this could include Helm charts and plugins, Falco configurations, Open Policy Agent (OPA) and Gatekeeper policies, OLM operators, Tinkerbell actions, kubectl plugins, Tekton tasks, pipelines and stepactions, KEDA scalers, CoreDNS plugins, Keptn integrations, container images, Kubewarden policies, Kyverno policies, Knative client, Backstage plugins, Argo templates, KubeArmor policies, KCL modules, Headlamp plugins, Inspektor gadgets, Meshery designs, OpenCost plugins, Radius recipes, Bootable Containers and Kagent agents.
<div
class="py-0 py-lg-5"
>
@ -557,6 +557,36 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
<a
aria-label="Open Kagent agents web"
class="link col iconLink"
href="https://kagent.dev/agents"
rel="noopener noreferrer"
role="button"
tabindex="-1"
target="_blank"
>
<div
class="d-flex flex-column justify-content-between align-items-center h-100"
>
<img
alt="Icon"
class="aboutIcon"
src="/static/media/kagent-light.svg"
/>
<div
class="d-none d-sm-block text-light mt-2 legendIcon"
>
<small>
Kagent agents
</small>
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open KCL site"
class="link col iconLink"
@ -583,10 +613,6 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open KEDA site"
class="link col iconLink"
@ -691,6 +717,10 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open KubeArmor policies web"
class="link col iconLink"
@ -717,10 +747,6 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open Kubewarden site"
class="link col iconLink"
@ -825,6 +851,10 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open Policy Agent site"
class="link col iconLink"
@ -851,10 +881,6 @@ exports[`Home index creates snapshot 1`] = `
</div>
</div>
</a>
</div>
<div
class="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around"
>
<a
aria-label="Open Policy Agent site"
class="link col iconLink"

View File

@ -127,7 +127,7 @@ describe('Home index', () => {
await waitFor(() => expect(API.getStats).toHaveBeenCalledTimes(1));
const links = await screen.findAllByRole('button');
expect(links).toHaveLength(31);
expect(links).toHaveLength(32);
expect(links[2]).toHaveProperty('href', 'https://github.com/artifacthub/hub');
expect(links[3]).toHaveProperty('href', 'https://cloud-native.slack.com/channels/artifact-hub');
@ -146,23 +146,24 @@ describe('Home index', () => {
expect(links[12]).toHaveProperty('href', 'https://headlamp.dev/');
expect(links[13]).toHaveProperty('href', 'https://helm.sh/');
expect(links[14]).toHaveProperty('href', 'https://www.inspektor-gadget.io/');
expect(links[15]).toHaveProperty('href', 'https://kcl-lang.io/');
expect(links[16]).toHaveProperty('href', 'https://keda.sh/');
expect(links[17]).toHaveProperty('href', 'https://keptn.sh/');
expect(links[18]).toHaveProperty('href', 'https://github.com/knative/client');
expect(links[19]).toHaveProperty('href', 'https://krew.sigs.k8s.io/');
expect(links[20]).toHaveProperty('href', 'https://kubearmor.io/');
expect(links[21]).toHaveProperty('href', 'https://www.kubewarden.io/');
expect(links[22]).toHaveProperty('href', 'https://www.kyverno.io/');
expect(links[23]).toHaveProperty('href', 'https://meshery.io/');
expect(links[24]).toHaveProperty('href', 'https://github.com/operator-framework');
expect(links[25]).toHaveProperty('href', 'https://www.openpolicyagent.org/');
expect(links[26]).toHaveProperty('href', 'https://www.opencost.io/');
expect(links[27]).toHaveProperty('href', 'https://radapp.io/');
expect(links[28]).toHaveProperty('href', 'https://tekton.dev/');
expect(links[29]).toHaveProperty('href', 'https://tinkerbell.org/');
expect(links[15]).toHaveProperty('href', 'https://kagent.dev/agents');
expect(links[16]).toHaveProperty('href', 'https://kcl-lang.io/');
expect(links[17]).toHaveProperty('href', 'https://keda.sh/');
expect(links[18]).toHaveProperty('href', 'https://keptn.sh/');
expect(links[19]).toHaveProperty('href', 'https://github.com/knative/client');
expect(links[20]).toHaveProperty('href', 'https://krew.sigs.k8s.io/');
expect(links[21]).toHaveProperty('href', 'https://kubearmor.io/');
expect(links[22]).toHaveProperty('href', 'https://www.kubewarden.io/');
expect(links[23]).toHaveProperty('href', 'https://www.kyverno.io/');
expect(links[24]).toHaveProperty('href', 'https://meshery.io/');
expect(links[25]).toHaveProperty('href', 'https://github.com/operator-framework');
expect(links[26]).toHaveProperty('href', 'https://www.openpolicyagent.org/');
expect(links[27]).toHaveProperty('href', 'https://www.opencost.io/');
expect(links[28]).toHaveProperty('href', 'https://radapp.io/');
expect(links[29]).toHaveProperty('href', 'https://tekton.dev/');
expect(links[30]).toHaveProperty('href', 'https://tinkerbell.org/');
expect(links[30]).toHaveProperty('href', 'https://www.cncf.io/projects/');
expect(links[31]).toHaveProperty('href', 'https://www.cncf.io/projects/');
});
});
});

View File

@ -233,7 +233,7 @@ const HomeView = () => {
kubectl plugins, Tekton tasks, pipelines and stepactions, KEDA scalers, CoreDNS plugins, Keptn
integrations, container images, Kubewarden policies, Kyverno policies, Knative client, Backstage
plugins, Argo templates, KubeArmor policies, KCL modules, Headlamp plugins, Inspektor gadgets, Meshery
designs, OpenCost plugins, Radius recipes and Bootable Containers.
designs, OpenCost plugins, Radius recipes, Bootable Containers and Kagent agents.
<div className="py-0 py-lg-5">
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink
@ -342,6 +342,20 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
<ExternalLink
href="https://kagent.dev/agents"
className={`col ${styles.iconLink}`}
label="Open Kagent agents web"
>
<div className="d-flex flex-column justify-content-between align-items-center h-100">
<RepositoryIcon kind={RepositoryKind.Kagent} type="white" className={styles.aboutIcon} />
<div className={`d-none d-sm-block text-light mt-2 ${styles.legendIcon}`}>
<small>Kagent agents</small>
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink href="https://kcl-lang.io" className={`col ${styles.iconLink}`} label="Open KCL site">
<div className="d-flex flex-column justify-content-between align-items-center h-100">
<RepositoryIcon kind={RepositoryKind.KCL} type="white" className={styles.aboutIcon} />
@ -350,8 +364,6 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink href="https://keda.sh" className={`col ${styles.iconLink}`} label="Open KEDA site">
<div className="d-flex flex-column justify-content-between align-items-center h-100">
<RepositoryIcon kind={RepositoryKind.KedaScaler} type="white" className={styles.aboutIcon} />
@ -396,6 +408,8 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink
href="https://kubearmor.io"
className={`col ${styles.iconLink}`}
@ -408,8 +422,6 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink
href="https://www.kubewarden.io"
className={`col ${styles.iconLink}`}
@ -458,6 +470,8 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink
href="https://www.openpolicyagent.org"
className={`col ${styles.iconLink}`}
@ -470,8 +484,6 @@ const HomeView = () => {
</div>
</div>
</ExternalLink>
</div>
<div className="mx-0 mx-md-3 mx-lg-5 my-4 my-sm-5 d-flex flex-row align-items-stretch justify-content-around">
<ExternalLink
href="https://www.opencost.io"
className={`col ${styles.iconLink}`}

View File

@ -52,6 +52,7 @@ interface Props {
const getVersionsTitle = (repoKind: RepositoryKind): string => {
switch (repoKind) {
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
return 'Chart versions';
case RepositoryKind.Container:
return 'Tags';
@ -81,6 +82,7 @@ const Details = (props: Props) => {
case RepositoryKind.OpenCost:
case RepositoryKind.RadiusRecipe:
case RepositoryKind.Bootc:
case RepositoryKind.Kagent:
return (
<>
{props.package.appVersion && (
@ -155,6 +157,7 @@ const Details = (props: Props) => {
switch (props.package.repository.kind) {
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
return (
<>
{props.package.data && (

View File

@ -14,7 +14,7 @@ interface Props {
}
export const URL_regex =
/^https:\/\/([^\/?]+)\/packages\/(helm|falco|opa|olm|tbaction|krew|helm-plugin|tekton-task|keda-scaler|coredns|keptn|tekton-pipeline|kubewarden|gatekeeper|kyverno|knative-client-plugin|backstage|argo-template|kubearmor|inspektor-gadget|tekton-stepaction|meshery|opencost|radius|bootc|container)\/([a-z0-9-]+)\/([a-z0-9-]+)$/; // eslint-disable-line
/^https:\/\/([^\/?]+)\/packages\/(helm|falco|opa|olm|tbaction|krew|helm-plugin|tekton-task|keda-scaler|coredns|keptn|tekton-pipeline|kubewarden|gatekeeper|kyverno|knative-client-plugin|backstage|argo-template|kubearmor|inspektor-gadget|tekton-stepaction|meshery|opencost|radius|bootc|kagent|container)\/([a-z0-9-]+)\/([a-z0-9-]+)$/; // eslint-disable-line
const prepareRecommendations = (recommendations?: Recommendation[]): RecommendedPackage[] => {
const list: RecommendedPackage[] = [];

View File

@ -33,7 +33,11 @@ const SignKeyInfo = (props: Props) => {
};
const onOpen = useCallback(() => {
if (props.signed && props.repoKind === RepositoryKind.Helm && !isUndefined(props.signKey)) {
if (
props.signed &&
[RepositoryKind.Helm, RepositoryKind.Kagent].includes(props.repoKind) &&
!isUndefined(props.signKey)
) {
setOpenStatus(true);
navigate('?modal=key-info', {
state: location.state,
@ -54,7 +58,7 @@ const SignKeyInfo = (props: Props) => {
if (
isNull(props.signed) ||
!props.signed ||
props.repoKind !== RepositoryKind.Helm ||
![RepositoryKind.Helm, RepositoryKind.Kagent].includes(props.repoKind) ||
(isUndefined(props.signKey) && onlyCosignSignature)
)
return null;

View File

@ -118,7 +118,7 @@ const ChartTemplatesModal = (props: Props) => {
useEffect(() => {
if (props.visibleChartTemplates) {
if (!openStatus && props.repoKind === RepositoryKind.Helm) {
if (!openStatus && [RepositoryKind.Helm, RepositoryKind.Kagent].includes(props.repoKind)) {
onOpenModal();
} else {
cleanUrl();
@ -132,7 +132,7 @@ const ChartTemplatesModal = (props: Props) => {
}
}, [props.packageId]);
if (props.repoKind !== RepositoryKind.Helm) return null;
if (![RepositoryKind.Helm, RepositoryKind.Kagent].includes(props.repoKind)) return null;
async function getChartTemplates() {
try {

View File

@ -1000,7 +1000,7 @@ const PackageView = () => {
<div className="d-flex flex-row mt-3 me-4">
{detail.deprecated && <Deprecated className="me-2" dropdownAlignment="start" />}
{(detail.cncf || detail.repository.cncf) && <CNCF className="me-2" dropdownAlignment="start" />}
{detail.repository.kind === RepositoryKind.Helm && (
{[RepositoryKind.Helm, RepositoryKind.Kagent].includes(detail.repository.kind) && (
<ValuesSchemaBagde
hasValuesSchema={detail.hasValuesSchema || false}
className="me-2"
@ -1214,6 +1214,7 @@ const PackageView = () => {
);
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
return (
<>
<div className="mb-2">

View File

@ -29,6 +29,7 @@ export enum RepositoryKind {
OpenCost,
RadiusRecipe,
Bootc,
Kagent,
}
export enum PackageCategory {

View File

@ -186,6 +186,15 @@ export const REPOSITORY_KINDS: RepoKindDef[] = [
icon: <RepositoryIcon kind={RepositoryKind.InspektorGadget} className="mw-100 mh-100" />,
active: true,
},
{
kind: RepositoryKind.Kagent,
label: 'kagent',
name: 'Kagent agents',
singular: 'Kagent agent',
plural: 'Kagent agents',
icon: <RepositoryIcon kind={RepositoryKind.Kagent} className="mw-100 mh-100" />,
active: true,
},
{
kind: RepositoryKind.KCL,
label: 'kcl',
@ -840,7 +849,7 @@ export const CVSS_V3_VECTORS: { [key: string]: CVSSVectorMetric[] } = {
export const OCI_PREFIX = 'oci://';
export const PKG_DETAIL_PATH =
/^\/packages\/(helm|falco|opa|olm|tbaction|krew|helm-plugin|tekton-task|keda-scaler|coredns|keptn|tekton-pipeline|kubewarden|gatekeeper|kyverno|knative-client-plugin|backstage|argo-template|kubearmor|kcl|headlamp|inspektor-gadget|tekton-stepaction|meshery|opencost|radius|bootc|container)\//;
/^\/packages\/(helm|falco|opa|olm|tbaction|krew|helm-plugin|tekton-task|keda-scaler|coredns|keptn|tekton-pipeline|kubewarden|gatekeeper|kyverno|knative-client-plugin|backstage|argo-template|kubearmor|kcl|headlamp|inspektor-gadget|tekton-stepaction|meshery|opencost|radius|bootc|kagent|container)\//;
export const HOME_ROUTES = [
'/verify-email',

View File

@ -85,6 +85,7 @@ const getInstallMethods = (props: PackageInfo): InstallMethodOutput => {
}
break;
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
if (pkg.data && pkg.data.type && pkg.data.type === HelmChartType.Library) {
output.errorMessage = 'A library chart is not installable';
hasError = true;
@ -142,6 +143,7 @@ const getInstallMethods = (props: PackageInfo): InstallMethodOutput => {
switch (pkg.repository.kind) {
case RepositoryKind.Helm:
case RepositoryKind.Kagent:
if (pkg.repository.url.startsWith(OCI_PREFIX)) {
output.methods.push({
label: 'v3',

View File

@ -58,6 +58,8 @@ const getRepoKind = (repoName: string): RepositoryKind | null => {
return RepositoryKind.RadiusRecipe;
case 'bootc':
return RepositoryKind.Bootc;
case 'kagent':
return RepositoryKind.Kagent;
default:
return null;
}
@ -121,6 +123,8 @@ const getRepoKindName = (repoKind: RepositoryKind): string | null => {
return 'radius';
case RepositoryKind.Bootc:
return 'bootc';
case RepositoryKind.Kagent:
return 'kagent';
default:
return null;
}

View File

@ -11,7 +11,7 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div class="artifacthub-widget-group" data-url="http://localhost:8000/packages/search?kind=25&sort=relevance&page=1" data-theme="light"></div>
<div class="artifacthub-widget-group" data-url="http://localhost:8000/packages/search?kind=28&sort=relevance&page=1" data-theme="light"></div>
<div class="artifacthub-widget-group" data-url="http://localhost:8000/packages/search?user=cynthia-sg&sort=relevance&page=1" data-theme="dark" data-header="false" data-stars="true" data-color="#417598" data-responsive="true" data-loading="true"></div>
<div class="artifacthub-widget-group" data-url="http://localhost:8000/packages/search?kind=22&sort=relevance&page=1" data-theme="light" data-header="false" data-stars="true" data-color="#417598" data-responsive="true" data-loading="true"></div>
<div class="artifacthub-widget-group" data-url="http://localhost:8000/packages/search?kind=21&sort=relevance&page=1" data-theme="light" data-header="false" data-stars="true" data-color="#417598" data-responsive="true" data-loading="true"></div>

View File

@ -56,7 +56,7 @@ const hasBadges = (packages: PackageSummary[] | null): boolean => {
pkg.official ||
pkg.repository.official ||
pkg.repository.verifiedPublisher ||
(pkg.repository.kind === RepositoryKind.Helm && pkg.hasValuesSchema)
([RepositoryKind.Helm, RepositoryKind.Kagent].includes(pkg.repository.kind) && pkg.hasValuesSchema)
);
}

View File

@ -105,6 +105,8 @@ const getRepoKindName = (repoKind: RepositoryKind): string | null => {
return 'radius';
case RepositoryKind.Bootc:
return 'bootc';
case RepositoryKind.Kagent:
return 'kagent';
default:
return null;
}
@ -477,15 +479,15 @@ export default function Widget(props: Props) {
{(packageSummary.official ||
packageSummary.repository.official ||
packageSummary.repository.verifiedPublisher ||
(packageSummary.repository.kind === RepositoryKind.Helm && packageSummary.hasValuesSchema)) && (
([RepositoryKind.Helm, RepositoryKind.Kagent].includes(packageSummary.repository.kind) &&
packageSummary.hasValuesSchema)) && (
<BadgesWrapper>
{packageSummary.deprecated && <Label type="deprecated" />}
{(packageSummary.cncf || packageSummary.repository.cncf) && <Label type="cncf" />}
{packageSummary.repository.kind === RepositoryKind.Helm && packageSummary.hasValuesSchema && (
<Label type="valuesSchema" />
)}
{[RepositoryKind.Helm, RepositoryKind.Kagent].includes(packageSummary.repository.kind) &&
packageSummary.hasValuesSchema && <Label type="valuesSchema" />}
{packageSummary.signed && <Label type="signed" />}

View File

@ -84,6 +84,8 @@ const Image = (props: Props) => {
return '/static/media/placeholder_pkg_radius.png';
case RepositoryKind.Bootc:
return '/static/media/placeholder_pkg_bootc.png';
case RepositoryKind.Kagent:
return '/static/media/placeholder_pkg_kagent.png';
default:
return PLACEHOLDER_SRC;
}

View File

@ -42,6 +42,7 @@ const ICONS: IconsList = {
[RepositoryKind.OpenCost]: <SVGIcons name="opencost" />,
[RepositoryKind.RadiusRecipe]: <SVGIcons name="radius" />,
[RepositoryKind.Bootc]: <SVGIcons name="bootc" />,
[RepositoryKind.Kagent]: <SVGIcons name="kagent" />,
};
const RepositoryIcon = (props: Props) => (

View File

@ -128,6 +128,10 @@ const REPOSITORY_KINDS: RepoKindDef[] = [
kind: RepositoryKind.Bootc,
name: 'Bootable container',
},
{
kind: RepositoryKind.Kagent,
name: 'Kagent agent',
},
];
const Wrapper = styled('span')`

View File

@ -1313,6 +1313,28 @@ const SVGIcons = (props: Props) => (
</g>
</svg>
);
case 'kagent':
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0,0,123,123" version="1.1">
<title>{props.name}</title>
<g id="layer0">
<path
d="M92.0513,60.3285L76.7751,60.3285L76.7751,75.7025L92.0513,75.7025L92.0513,60.3285L92.0513,60.3285Z"
fill="#942DE7"
/>
<path
d="M61.5229,60.3285L46.2468,60.3285L46.2468,75.7025L61.5229,75.7025L61.5229,60.3285L61.5229,60.3285Z"
fill="#942DE7"
/>
<path
d="M107.303,29.6045L92.0274,14.2305L76.7752,14.2305L61.499,14.2305L46.2468,14.2305L30.9707,14.2305L30.9707,29.6045L15.7184,29.6045L15.7184,44.9545L0.442314,44.9545L0.442314,60.3285L0.442314,75.6784L15.7184,91.0525L30.9707,106.402L46.2468,106.402L61.499,106.402L76.7752,106.402L92.0274,106.402L107.303,106.402L107.303,91.0525L92.0274,91.0525L76.7752,91.0525L61.499,91.0525L46.2468,91.0525L30.9707,91.0525L30.9707,75.6784L30.9707,60.3285L30.9707,44.9545L46.2468,44.9545L61.499,44.9545L76.7752,44.9545L92.0274,44.9545L107.303,44.9545L107.303,60.3285L107.303,75.6784L107.303,91.0525L122.555,91.0525L122.555,75.6784L122.555,60.3285L122.555,44.9545L107.303,29.6045L107.303,29.6045Z"
fill="#942DE7"
/>
</g>
</svg>
);
default:
return null;
}

View File

@ -56,6 +56,7 @@ export enum RepositoryKind {
OpenCost,
RadiusRecipe,
Bootc,
Kagent,
}
export interface SearchResults {