| name | openpitrix |
| description | KubeSphere OpenPitrix application management Skill. Use when users ask about KubeSphere App Store, OpenPitrix, Helm/YAML application templates, application repositories, app versions, app releases, categories, review states, repository sync, or troubleshooting application installation and upgrade issues. |
OpenPitrix Application Management
Overview
OpenPitrix is KubeSphere's application management capability for app repositories, app templates, versions, reviews, and app releases. In KubeSphere 4.x the runtime API group is application.kubesphere.io/v2; older OpenPitrix extension code used openpitrix.io/v2 CRUD APIs and openpitrix.io/v2alpha1 read/list wrappers over application.kubesphere.io/v1alpha1 resources.
Use the v2 objects and APIs first:
| Concept | KubeSphere 4.x object | Older OpenPitrix object |
|---|
| Repository | Repo | HelmRepo |
| App template | Application | HelmApplication |
| App template version | ApplicationVersion | HelmApplicationVersion |
| App release / installed app | ApplicationRelease | HelmRelease |
| Category | Category | HelmCategory |
Core namespace and labels:
| Item | Value |
|---|
| Application data namespace | extension-openpitrix |
| Repository label | application.kubesphere.io/repo-name |
| App label | application.kubesphere.io/app-id |
| App version label | application.kubesphere.io/appversion-id |
| App type label | application.kubesphere.io/app-type |
| Cluster label | kubesphere.io/cluster |
| Namespace label | kubesphere.io/namespace |
| Workspace label | kubesphere.io/workspace |
Architecture
Helm repo index or uploaded package
|
v
Repo sync / upload API
|
v
Application -> ApplicationVersion -> ApplicationRelease
|
v
Helm executor Job or YAML installer
|
v
Workloads in target cluster/namespace
Important controllers:
| Controller | Watches | Purpose |
|---|
helmrepo-controller | Repo | Loads Helm repository indexes, creates/deletes Application and ApplicationVersion, updates repository sync state. |
appversion-controller | ApplicationVersion | Cleans stored chart/YAML data after version deletion when it is no longer used. |
apprelease-helminstaller | ApplicationRelease | Creates, upgrades, verifies, and uninstalls app releases through Helm executor Jobs or YAML installer logic. |
appcategory-controller | Category | Maintains category counts and prevents deleting categories that still own apps. |
Navigation and Feature Coverage
When the user says "应用商店", first identify whether they mean the enterprise-space app management pages or the global component-dock App Store management extension. They share the same OpenPitrix/KSE v2 resources, but the intent and scope differ.
Enterprise-space application management under a workspace:
| Console area | Typical route | User intent | Main resource/API |
|---|
| 应用管理 / 应用 | /workspaces/{workspace}/deploy | List, create, edit, upgrade, or delete installed apps in projects. | ApplicationRelease; /workspaces/{workspace}/applications, /namespaces/{namespace}/applications |
| 应用管理 / 自制应用 | workspace custom app area | Work with user-created/custom applications before or outside App Store publication. | Usually app template/upload flows; verify against Application and ApplicationVersion before assuming release APIs. |
| 应用管理 / 应用模板 | /workspaces/{workspace}/app-templates | Create/upload Helm or YAML app templates, edit template metadata, submit versions for review, manage versions. | Application, ApplicationVersion; /workspaces/{workspace}/apps, /workspaces/{workspace}/apps/{app}/versions |
| 应用管理 / 应用仓库 | /workspaces/{workspace}/app-repos | Add, sync, inspect, or delete Helm repos available to the workspace. | Repo; /workspaces/{workspace}/repos |
Component-dock App Store management:
| Console area | Typical route | User intent | Main resource/API |
|---|
| 组件坞 / 应用商店管理 / 应用 | /apps-manage/store | Platform-level App Store template list, publish/unpublish, edit metadata, delete, open detail pages. | Application, ApplicationVersion; /workspaces/{workspace}/apps, /apps/{app}/action |
| 组件坞 / 应用商店管理 / 应用分类 | /apps-manage/categories | Create, edit, delete categories and assign applications to categories. | Category; /categories, /workspaces/{workspace}/apps/{app} |
| 组件坞 / 应用商店管理 / 应用审核 | /apps-manage/reviews | Review uploaded app versions submitted from enterprise spaces. | ApplicationVersion; /reviews, /workspaces/{workspace}/apps/{app}/versions/{version}/action |
| 组件坞 / 应用商店管理 / 应用仓库 | /apps-manage/repo | Manage global/platform view of App Store repositories. | Repo; /workspaces/{workspace}/repos |
| 组件坞 / 应用商店管理 / 部署管理 | /apps-manage/deploy | Manage installed app releases across workspace/cluster/namespace scope. | ApplicationRelease; /workspaces/{workspace}/applications, /namespaces/{namespace}/applications |
Resource selection rules:
- Use
Application and ApplicationVersion for app templates, App Store listings, uploaded packages, version review, screenshots, metadata, and categories.
- Use
Repo for app repositories and repository sync.
- Use
Category for App Store category management.
- Use
ApplicationRelease only for installed/deployed apps, including workspace "应用" pages and platform "部署管理" pages.
- Do not troubleshoot an App Store template with release Job/Pod commands unless the user is installing or upgrading an
ApplicationRelease.
- Uploaded/self-made app templates use the repository label value
application.kubesphere.io/repo-name=upload. Do not write uploaded.
- KSE v2 app and version action examples use
{"state":"..."} with optional message, not legacy {"action":"..."}. Legacy openpitrix.io/v2 action APIs use action.
- For
kubectl get/describe of OpenPitrix application CRDs, do not add -n extension-openpitrix by default. These resources are queried by resource kind and labels; use labels such as kubesphere.io/workspace, application.kubesphere.io/repo-name, application.kubesphere.io/app-id, or application.kubesphere.io/app-release-name. Use extension-openpitrix only when inspecting extension component Pods or storage fallback objects.
Tool Selection
Choose the tool by task. Prefer the first matching option:
| Tool | Use for | Authentication |
|---|
kubectl | Inspect CRDs/resources, events, controller state, executor Jobs/Pods/logs, and cluster-side troubleshooting. | Uses the current kubeconfig. |
ks_api.py | KubeSphere JSON KAPIs under /kapis/...; recommended for create/update/list/action calls that send JSON. | Run login once; token is cached in ~/.kubesphere_token. |
curl | Multipart uploads, package/file downloads, custom headers, reproducing exact HTTP requests, or when the user explicitly asks for curl. | Requires Authorization: Bearer $TOKEN; get the token with ks_api.py --login or set it manually. |
Set up ks_api.py first when using KubeSphere KAPIs:
cd skills/kubesphere-core/scripts
export KUBESPHERE_HOST="http://<kubesphere-host>"
python ks_api.py --login --username admin --password <password>
For curl, reuse the token cached by ks_api.py:
export KUBESPHERE_HOST="http://<kubesphere-host>"
export TOKEN=$(python -c 'import json, os; print(json.load(open(os.path.expanduser("~/.kubesphere_token")))["token"])')
If ks_api.py is unavailable, obtain an OAuth token directly:
export KUBESPHERE_HOST="http://<kubesphere-host>"
export TOKEN=$(curl -sS -X POST "$KUBESPHERE_HOST/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=<username>" \
-d "password=<password>" \
-d "client_id=kubesphere" \
-d "client_secret=kubesphere" | jq -r '.access_token')
Then pass -H "Authorization: Bearer $TOKEN" on every curl request to /kapis/....
Quick Inspection
Start with cluster resources before calling KAPIs:
kubectl get repos.application.kubesphere.io
kubectl get applications.application.kubesphere.io
kubectl get applicationversions.application.kubesphere.io
kubectl get applicationreleases.application.kubesphere.io
kubectl get categories.application.kubesphere.io
For workspace-scoped views, filter by workspace label:
kubectl get repos.application.kubesphere.io \
-l kubesphere.io/workspace=<workspace>
kubectl get applications.application.kubesphere.io \
-l kubesphere.io/workspace=<workspace>
For an installed app:
kubectl get applicationreleases.application.kubesphere.io \
-l kubesphere.io/cluster=<cluster>,kubesphere.io/namespace=<namespace>
kubectl describe applicationrelease.application.kubesphere.io <release-name>
KAPI Routes
Use /kapis/application.kubesphere.io/v2 in KubeSphere 4.x.
Repository routes:
| Operation | Route |
|---|
| List repositories | GET /workspaces/{workspace}/repos |
| Create repository | POST /workspaces/{workspace}/repos |
| Update repository | PATCH /workspaces/{workspace}/repos/{repo} |
| Delete repository | DELETE /workspaces/{workspace}/repos/{repo} |
| Manual sync | POST /workspaces/{workspace}/repos/{repo}/action |
| Repository events | GET /workspaces/{workspace}/repos/{repo}/events |
App template routes:
| Operation | Route |
|---|
| List apps | GET /workspaces/{workspace}/apps |
| Create uploaded app | POST /workspaces/{workspace}/apps |
| Describe app | GET /workspaces/{workspace}/apps/{app} |
| Create/update app metadata | POST /workspaces/{workspace}/apps/{app} |
| Patch metadata | PATCH /workspaces/{workspace}/apps/{app} |
| Delete app | DELETE /workspaces/{workspace}/apps/{app} |
| Review/action app | POST /apps/{app}/action |
Version and release routes:
| Operation | Route |
|---|
| List versions | GET /workspaces/{workspace}/apps/{app}/versions |
| Create version | POST /workspaces/{workspace}/apps/{app}/versions |
| Describe version | GET /workspaces/{workspace}/apps/{app}/versions/{version} |
| Download package | GET /workspaces/{workspace}/apps/{app}/versions/{version}/package |
| List chart/YAML files | GET /workspaces/{workspace}/apps/{app}/versions/{version}/files |
| Review/action version | POST /workspaces/{workspace}/apps/{app}/versions/{version}/action |
| List releases by workspace | GET /workspaces/{workspace}/applications |
| List releases by namespace | GET /namespaces/{namespace}/applications |
| Create release | POST /namespaces/{namespace}/applications |
| Describe release | GET /namespaces/{namespace}/applications/{application} |
| Delete release | DELETE /namespaces/{namespace}/applications/{application} |
App Store management routes:
| Operation | Route |
|---|
| List categories | GET /categories |
| Create category | POST /categories |
| Update category | POST /categories/{category} |
| Describe category | GET /categories/{category} |
| Delete category | DELETE /categories/{category} |
| List app reviews | GET /reviews |
| Upload attachment | POST /workspaces/{workspace}/attachments |
| Describe attachment | GET /workspaces/{workspace}/attachments/{attachment} |
| Delete attachments | DELETE /workspaces/{workspace}/attachments/{attachment} |
Older OpenPitrix extension routes use /kapis/openpitrix.io/v2alpha1, primarily as read/list wrappers around HelmRepo, HelmApplication, HelmApplicationVersion, HelmRelease, and HelmCategory.
Assume KUBESPHERE_HOST, ks_api.py login, and TOKEN have already been set up from Tool Selection before using the examples below.
KSE Application API examples
Use these examples for KubeSphere 4.x application.kubesphere.io/v2.
python ks_api.py POST /kapis/application.kubesphere.io/v2/workspaces/<workspace>/repos '{
"metadata": {
"name": "<repo-name>",
"labels": {
"kubesphere.io/workspace": "<workspace>"
},
"annotations": {
"kubesphere.io/display-name": "<display-name>"
}
},
"spec": {
"url": "https://example.com/charts",
"description": "<description>",
"syncPeriod": 0
}
}'
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/repos/<repo-name>/action
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions/<version>/action \
'{"state":"active","message":"publish"}'
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/apps/<app>/action \
'{"state":"suspended","message":"suspend from App Store"}'
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/namespaces/<namespace>/applications '{
"metadata": {
"name": "<release-name>",
"labels": {
"application.kubesphere.io/app-id": "<app-id>",
"application.kubesphere.io/appversion-id": "<app-version-id>",
"application.kubesphere.io/app-type": "helm",
"kubesphere.io/cluster": "<cluster>",
"kubesphere.io/namespace": "<namespace>",
"kubesphere.io/workspace": "<workspace>"
},
"annotations": {
"kubesphere.io/creator": "<username>"
}
},
"spec": {
"appID": "<app-id>",
"appVersionID": "<app-version-id>",
"appType": "helm",
"values": ""
}
}'
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/namespaces/<namespace>/applications
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/applications
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/namespaces/<namespace>/applications/<release-name>
python ks_api.py GET /kapis/application.kubesphere.io/v2/categories
python ks_api.py GET /kapis/application.kubesphere.io/v2/reviews
Use curl only when the API needs multipart upload, streaming download, or custom headers that ks_api.py does not support.
Curl equivalents for JSON KAPIs:
export KUBESPHERE_HOST="http://<kubesphere-host>"
export TOKEN="<kubesphere-access-token>"
curl -sS -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/repos" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "<repo-name>",
"labels": {
"kubesphere.io/workspace": "<workspace>"
},
"annotations": {
"kubesphere.io/display-name": "<display-name>"
}
},
"spec": {
"url": "https://example.com/charts",
"description": "<description>",
"syncPeriod": 0
}
}'
curl -sS -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/repos/<repo-name>/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
curl -sS \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps" \
-H "Authorization: Bearer $TOKEN"
curl -sS -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions/<version>/action" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"state":"active","message":"publish"}'
curl -sS -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/namespaces/<namespace>/applications" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"name": "<release-name>",
"labels": {
"application.kubesphere.io/app-id": "<app-id>",
"application.kubesphere.io/appversion-id": "<app-version-id>",
"application.kubesphere.io/app-type": "helm",
"kubesphere.io/cluster": "<cluster>",
"kubesphere.io/namespace": "<namespace>",
"kubesphere.io/workspace": "<workspace>"
}
},
"spec": {
"appID": "<app-id>",
"appVersionID": "<app-version-id>",
"appType": "helm",
"values": ""
}
}'
Legacy OpenPitrix API examples
Use these only when the installed OpenPitrix extension exposes the old openpitrix.io KAPIs. Prefer application.kubesphere.io/v2 for KubeSphere 4.x. The legacy request/response fields use OpenPitrix-style snake_case names such as repo_id, version_id, sync_period, and app_default_status.
Read/list wrappers from /kapis/openpitrix.io/v2alpha1:
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/repos
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/repos/<repo-id>
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/apps
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/apps/<app-id>
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/apps/<app-id>/versions
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/apps/<app-id>/versions/<version-id>
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/clusters/<cluster>/namespaces/<namespace>/applications
python ks_api.py GET \
/kapis/openpitrix.io/v2alpha1/workspaces/<workspace>/clusters/<cluster>/namespaces/<namespace>/applications/<application-id>
python ks_api.py GET /kapis/openpitrix.io/v2alpha1/categories
python ks_api.py GET /kapis/openpitrix.io/v2alpha1/categories/<category-id>
Older CRUD-style APIs from /kapis/openpitrix.io/v2:
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/repos?validate=true '{
"name": "<repo-name>",
"url": "https://example.com/charts",
"type": "helm",
"visibility": "public",
"providers": ["kubernetes"],
"sync_period": "0s",
"app_default_status": "active",
"credential": ""
}'
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/repos/<repo-id>/action \
'{"action":"index","workspace":"<workspace>"}'
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/apps '{
"name": "<app-name>",
"version_name": "0.1.0",
"version_type": "helm",
"version_package": "<base64-chart-tgz>"
}'
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/apps/<app-id>/versions '{
"app_id": "<app-id>",
"name": "0.2.0",
"type": "helm",
"package": "<base64-chart-tgz>"
}'
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/apps/<app-id>/versions/<version-id>/action \
'{"action":"submit","message":"submit for review"}'
python ks_api.py POST \
/kapis/openpitrix.io/v2/workspaces/<workspace>/clusters/<cluster>/namespaces/<namespace>/applications '{
"name": "<release-name>",
"app_id": "<app-id>",
"version_id": "<version-id>",
"runtime_id": "<cluster>",
"conf": "{}",
"advanced_param": []
}'
App Store and Workspace App Management Workflow
KubeSphere's OpenPitrix extension serves both enterprise-space application management and component-dock App Store management. Map the console area to the KSE v2 APIs before choosing commands:
| UI area | Main purpose | Primary APIs |
|---|
/workspaces/{workspace}/deploy | Enterprise-space installed apps. | /workspaces/{workspace}/applications, /namespaces/{namespace}/applications |
/workspaces/{workspace}/app-templates | Enterprise-space app templates created from Helm/YAML packages. | /workspaces/{workspace}/apps, /workspaces/{workspace}/apps/{app}/versions, /workspaces/{workspace}/attachments |
/workspaces/{workspace}/app-repos | Enterprise-space app repositories. | /workspaces/{workspace}/repos |
/apps-manage/store | Manage application templates in the App Store: list, create/upload, edit metadata, delete, open detail pages. | /workspaces/{workspace}/apps, /workspaces/{workspace}/apps/{app}, /workspaces/{workspace}/attachments |
/apps-manage/store/{app} | Inspect template details, versions, audit records, and deployed instances. | /workspaces/{workspace}/apps/{app}, /workspaces/{workspace}/apps/{app}/versions, /workspaces/{workspace}/applications |
/apps-manage/categories | Manage categories and assign apps to categories. | /categories, /categories/{category}, /workspaces/{workspace}/apps/{app} |
/apps-manage/reviews | Review uploaded app versions. | /reviews, /workspaces/{workspace}/apps/{app}/versions/{version}/action |
/apps-manage/repo | Manage Helm repositories that feed App Store templates. | /workspaces/{workspace}/repos |
/apps-manage/deploy | Manage installed app releases. | /namespaces/{namespace}/applications, /workspaces/{workspace}/applications |
List and filter behavior:
- App template and App Store pages list
Application templates, not installed ApplicationRelease objects.
- Workspace "应用" and App Store "部署管理" pages list installed
ApplicationRelease objects.
- The UI filters list queries through KubeSphere list query parameters such as
conditions, status, order, limit, and workspace query scope.
- Public store display commonly focuses on
active|suspended apps; management views include draft, passed, active, and suspended states.
- Uploaded apps are identified with
application.kubesphere.io/repo-name=upload.
Inspect app templates:
python ks_api.py GET \
"/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps?conditions=status=draft|active|suspended|passed&sortBy=create_time"
kubectl get applications.application.kubesphere.io \
-l kubesphere.io/workspace=<workspace>
Inspect installed apps/releases:
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/applications
python ks_api.py GET \
/kapis/application.kubesphere.io/v2/namespaces/<namespace>/applications
kubectl get applicationreleases.application.kubesphere.io \
-l kubesphere.io/workspace=<workspace>
Patch app template metadata. This is how the enterprise-space template page and App Store management page edit alias, description, icon, category, screenshots/attachments, abstraction, and home URL:
python ks_api.py PATCH \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app> '{
"aliasName": "<display-name>",
"description": "<description>",
"categoryName": "<category>",
"icon": "<base64-icon-or-url>",
"attachments": ["<attachment-id>"],
"abstraction": "<short-summary>",
"appHome": "https://example.com"
}'
The patch handler writes these fields to:
| Request field | Stored as |
|---|
categoryName | metadata.labels["application.kubesphere.io/app-category-name"] |
aliasName | metadata.annotations["kubesphere.io/display-name"] |
description | metadata.annotations["kubesphere.io/description"] |
icon | spec.icon |
attachments | spec.attachments |
abstraction | spec.abstraction |
appHome | spec.appHome |
Manage attachments for App Store screenshots and other assets. This API is multipart, so prefer curl with the bearer token:
curl -sS -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/attachments" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@./screenshot.png"
curl -sS \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/attachments/<attachment-id>" \
-H "Authorization: Bearer $TOKEN"
curl -sS -X DELETE \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/attachments/<attachment-id>" \
-H "Authorization: Bearer $TOKEN"
Manage categories:
python ks_api.py GET /kapis/application.kubesphere.io/v2/categories
python ks_api.py POST /kapis/application.kubesphere.io/v2/categories '{
"metadata": {
"name": "<category>",
"annotations": {
"kubesphere.io/display-name": "<display-name>",
"kubesphere.io/description": "<description>"
}
},
"spec": {
"icon": "database"
}
}'
python ks_api.py POST /kapis/application.kubesphere.io/v2/categories/<category> '{
"metadata": {
"name": "<category>",
"annotations": {
"kubesphere.io/display-name": "<display-name>",
"kubesphere.io/description": "<description>"
}
},
"spec": {
"icon": "database"
}
}'
python ks_api.py DELETE /kapis/application.kubesphere.io/v2/categories/<category>
Do not delete kubesphere-app-uncategorized, and do not delete a category whose status.total is greater than zero. To move apps between categories, patch each app's categoryName through /workspaces/{workspace}/apps/{app}.
Review uploaded app versions:
python ks_api.py GET \
"/kapis/application.kubesphere.io/v2/reviews?conditions=status=submitted"
python ks_api.py GET \
"/kapis/application.kubesphere.io/v2/reviews?conditions=status=active|rejected|passed|submitted|suspended"
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions/<version>/action \
'{"state":"passed","message":"approve"}'
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions/<version>/action \
'{"state":"rejected","message":"reject reason"}'
/reviews lists uploaded app versions only; the handler selects versions whose repo label is application.kubesphere.io/repo-name=upload. If a review item is missing, first verify that the ApplicationVersion belongs to the upload repo and is in a review state such as submitted.
Important KSE v2 App Store API shapes:
kubectl get applicationversions.application.kubesphere.io \
-l application.kubesphere.io/repo-name=upload
python ks_api.py POST /kapis/application.kubesphere.io/v2/categories '{
"metadata": {
"name": "<category>",
"annotations": {
"kubesphere.io/display-name": "<display-name>",
"kubesphere.io/description": "<description>"
}
},
"spec": {
"icon": "database"
}
}'
python ks_api.py POST /kapis/application.kubesphere.io/v2/workspaces/<workspace>/repos '{
"metadata": {
"name": "<repo-name>",
"labels": {
"kubesphere.io/workspace": "<workspace>"
},
"annotations": {
"kubesphere.io/display-name": "<display-name>"
}
},
"spec": {
"url": "https://example.com/charts",
"description": "<description>",
"syncPeriod": 0
}
}'
python ks_api.py POST \
/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps/<app>/versions/<version>/action \
'{"state":"passed","message":"approve"}'
Avoid these common mistakes for application.kubesphere.io/v2:
- Do not use
application.kubesphere.io/repo-name=uploaded; the built-in upload repo key is upload.
- Do not send top-level category bodies such as
{"name":"...","displayName":"..."}; send a Category object with metadata and spec.
- Do not send top-level repo bodies such as
{"name":"...","url":"..."}; send a Repo object with metadata and spec.
- Do not send
{"action":"approve"}, {"action":"reject"}, or {"action":"sync"} to KSE v2 action routes; use state for app/version actions and an empty body for repository manual sync.
Repository Workflow
Create or update a repository with a valid Helm repository URL. The API validates the URL by loading the repository index before persisting it. User info embedded in the URL is copied into spec.credential.
apiVersion: application.kubesphere.io/v2
kind: Repo
metadata:
name: <repo-name>
labels:
kubesphere.io/workspace: <workspace>
annotations:
kubesphere.io/display-name: <display-name>
spec:
url: https://example.com/charts
description: <description>
syncPeriod: 0
Sync behavior:
spec.syncPeriod: 0 means no periodic sync.
- Manual sync sets
status.state to manualTrigger.
- Successful sync sets
status.state to successful.
- Repo sync creates app IDs as
<repo-name>-<short-hash-of-chart-name>.
- Repo versions become active automatically because they came from a trusted repository.
Troubleshoot repository sync:
kubectl describe repo.application.kubesphere.io <repo-name>
kubectl get events --field-selector involvedObject.name=<repo-name>
kubectl logs -n kubesphere-system deploy/ks-controller-manager \
| grep -E "helmrepo-controller|<repo-name>"
Common checks:
- Confirm
.spec.url has a reachable index.yaml.
- Confirm credentials, CA, cert/key, and
insecureSkipTLSVerify when using private HTTPS repositories.
- If apps disappeared after sync, check whether the chart was removed from the upstream index; the controller deletes apps no longer present for that repo.
- If sync loops, check whether the workspace label points to a deleted
WorkspaceTemplate; the controller deletes workspace repos for deleted workspaces.
Uploaded App Workflow
Uploaded apps are stored as Repo=upload and start in review state draft. Helm charts and YAML packages share the same API path; appType distinguishes helm and yaml.
Validation-only upload:
Authenticate through KubeSphere first. Prefer the kubesphere-core ks_api.py helper for JSON KAPIs because it handles login and cached tokens consistently with other KubeSphere skills. File uploads are multipart requests, so use ks_api.py to login and then curl with the cached token:
cd skills/kubesphere-core/scripts
export KUBESPHERE_HOST="http://<kubesphere-host>"
python ks_api.py --login --username admin --password <password>
TOKEN=$(python -c 'import json, os; print(json.load(open(os.path.expanduser("~/.kubesphere_token")))["token"])')
curl -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps?validate=true" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: multipart/form-data" \
-F 'jsonData={"appType":"helm","workspace":"<workspace>"}' \
-F "file=@./chart.tgz"
If the helper is unavailable, use curl with an explicit bearer token:
TOKEN=<kubesphere-access-token>
curl -X POST \
"$KUBESPHERE_HOST/kapis/application.kubesphere.io/v2/workspaces/<workspace>/apps?validate=true" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: multipart/form-data" \
-F 'jsonData={"appType":"helm","workspace":"<workspace>"}' \
-F "file=@./chart.tgz"
After upload:
kubectl get applications.application.kubesphere.io \
-l application.kubesphere.io/repo-name=upload,kubesphere.io/workspace=<workspace>
kubectl get applicationversions.application.kubesphere.io \
-l application.kubesphere.io/repo-name=upload,application.kubesphere.io/app-id=<app>
Review states:
| State | Meaning |
|---|
draft | Uploaded but not published. |
submitted | Submitted for review. |
passed | Review passed. |
active | Published/visible. |
rejected | Review rejected. |
suspended | Temporarily hidden. |
Use app or version action routes to move review state. App activation requires at least one active or passed version.
Release Workflow
An ApplicationRelease installs a selected ApplicationVersion into a target cluster and namespace.
Minimal Helm release object:
apiVersion: application.kubesphere.io/v2
kind: ApplicationRelease
metadata:
name: <release-name>
labels:
application.kubesphere.io/app-id: <app-id>
application.kubesphere.io/appversion-id: <app-version-id>
application.kubesphere.io/app-type: helm
kubesphere.io/cluster: <cluster>
kubesphere.io/namespace: <namespace>
kubesphere.io/workspace: <workspace>
annotations:
kubesphere.io/creator: <username>
spec:
appID: <app-id>
appVersionID: <app-version-id>
appType: helm
values: <base64-or-api-provided-bytes>
Release states:
| State | Meaning |
|---|
creating | First reconciliation started. |
created | Helm/YAML executor Job was created. |
upgrading | Spec changed and upgrade started. |
upgraded | Upgrade Job was created. |
active | Helm release deployed or YAML install completed. |
timeout | Helm reported timeout; controller performs limited rechecks. |
deployFailed | Executor Job failed or disappeared. |
failed | Helm/YAML install, upgrade, or status verification failed. |
deleting | Uninstall started. |
clusterDeleted | Target cluster was deleted. |
Troubleshoot releases:
kubectl describe applicationrelease.application.kubesphere.io <release-name>
TARGET_NS=$(kubectl get applicationrelease.application.kubesphere.io <release-name> \
-o jsonpath="{.metadata.labels['kubesphere.io/namespace']}")
kubectl -n "$TARGET_NS" get jobs \
-l application.kubesphere.io/app-release-name=<release-name>
kubectl -n "$TARGET_NS" get pods \
-l application.kubesphere.io/app-release-name=<release-name>
Always prefer the application.kubesphere.io/app-release-name=<release-name> label selector for executor Jobs and Pods. Do not use broad kubectl get jobs -A | grep <release-name> or kubectl get pods -A | grep <release-name> as the primary path; use grep only as a fallback when labels are missing or suspected to be wrong.
Then inspect the executor Job pod logs:
POD=$(kubectl -n "$TARGET_NS" get pods \
-l application.kubesphere.io/app-release-name=<release-name> \
-o jsonpath='{.items[0].metadata.name}')
kubectl -n "$TARGET_NS" logs "$POD" --all-containers
Common checks:
- Ensure
spec.appVersionID exists and points to an ApplicationVersion.
- Ensure target cluster and namespace labels are correct; missing namespace defaults to
default, missing cluster defaults to host.
- For Helm apps, check whether stored chart data can be loaded from S3 or the ConfigMap fallback.
- For YAML apps, verify
spec.values contains valid YAML documents and the target cluster RESTMapper recognizes every GVR.
- For upgrade loops, compare
.status.specHash with the current .spec; spec changes drive upgrades.
- For timeout, inspect annotation
application.kubesphere.io/timeout-recheck; the controller only performs limited timeout rechecks.
Categories
Categories are cluster-scoped resources. Application category is carried by application.kubesphere.io/app-category-name; uncategorized apps use kubesphere-app-uncategorized.
kubectl get categories.application.kubesphere.io
kubectl get applications.application.kubesphere.io \
-l application.kubesphere.io/app-category-name=<category>
Do not delete a category until no applications reference it.
Development Notes
When changing implementation:
- Prefer
application.kubesphere.io/v2 CRDs and KAPIs for new KubeSphere code.
- Keep backward compatibility in mind when touching older OpenPitrix extension paths under
/kapis/openpitrix.io/v2 and /kapis/openpitrix.io/v2alpha1.
- Preserve the object relationship:
Repo owns synced apps, Application owns versions, and releases reference app/version through labels and spec fields.
- Status updates are subresource updates or merge patches; avoid normal spec updates for status-only changes.
- Uploaded package storage uses S3 when configured and falls back to ConfigMaps in
extension-openpitrix.
- Keep review state transitions consistent with app and app-version action handlers.