Compare commits
8 Commits
cli/fix/up
...
module-app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afc30bf263 | ||
|
|
b990d7a021 | ||
|
|
ee44bb773d | ||
|
|
e6a77e5c5a | ||
|
|
03d9b0016c | ||
|
|
7ca2cadb2d | ||
|
|
106ebaf41f | ||
|
|
39f55b6681 |
@@ -170,7 +170,7 @@ spec:
|
||||
priorityClassName: "system-cluster-critical"
|
||||
containers:
|
||||
- name: app-service
|
||||
image: beclab/app-service:0.4.62
|
||||
image: beclab/app-service:0.4.63
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
@@ -393,7 +393,7 @@ spec:
|
||||
priorityClassName: "system-cluster-critical"
|
||||
containers:
|
||||
- name: image-service
|
||||
image: beclab/image-service:0.4.48
|
||||
image: beclab/image-service:0.4.63
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
|
||||
@@ -72,6 +72,9 @@ func (h *Handler) uninstall(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
am.Spec.OpType = v1alpha1.UninstallOp
|
||||
if am.Annotations == nil {
|
||||
am.Annotations = make(map[string]string)
|
||||
}
|
||||
am.Annotations[api.AppTokenKey] = token
|
||||
am.Annotations[api.AppUninstallAllKey] = fmt.Sprintf("%t", request.All)
|
||||
err = h.ctrlClient.Update(req.Request.Context(), &am)
|
||||
|
||||
@@ -56,6 +56,7 @@ type ApplicationConfig struct {
|
||||
APIVersion APIVersion
|
||||
CfgFileVersion string
|
||||
Namespace string
|
||||
MiddlewareName string
|
||||
ChartsName string
|
||||
RepoURL string
|
||||
Title string
|
||||
|
||||
@@ -2,11 +2,16 @@ package appstate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
appsv1 "bytetrade.io/web3os/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
"bytetrade.io/web3os/app-service/pkg/constants"
|
||||
"bytetrade.io/web3os/app-service/pkg/images"
|
||||
apputils "bytetrade.io/web3os/app-service/pkg/utils/app"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
@@ -40,28 +45,47 @@ func NewDownloadingCancelingApp(c client.Client,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *DownloadingCancelingApp) Exec(ctx context.Context) (StatefulInProgressApp, error) {
|
||||
func (p *DownloadingCancelingApp) exec(ctx context.Context) error {
|
||||
err := p.imageClient.UpdateStatus(ctx, p.manager.Name, appsv1.DownloadingCanceled.String(), appsv1.DownloadingCanceled.String())
|
||||
if err != nil {
|
||||
klog.Errorf("update im name=%s to downloadingCanceled state failed %v", p.manager.Name, err)
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if ok := appFactory.cancelOperation(p.manager.Name); !ok {
|
||||
klog.Errorf("app %s operation is not ", p.manager.Name)
|
||||
}
|
||||
message := constants.OperationCanceledByUserTpl
|
||||
if p.manager.Status.Message == constants.OperationCanceledByTerminusTpl {
|
||||
message = constants.OperationCanceledByTerminusTpl
|
||||
}
|
||||
opRecord := makeRecord(p.manager, appsv1.DownloadingCanceled, message)
|
||||
|
||||
// FIXME: should check if the image downloading is canceled successfully
|
||||
updateErr := p.updateStatus(ctx, p.manager, appsv1.DownloadingCanceled, opRecord, message, "")
|
||||
if updateErr != nil {
|
||||
klog.Errorf("update app manager %s to %s state failed %v", p.manager.Name, appsv1.DownloadingCanceled.String(), updateErr)
|
||||
return nil, updateErr
|
||||
if !apputils.IsProtectedNamespace(p.manager.Spec.AppNamespace) {
|
||||
var ns corev1.Namespace
|
||||
err = p.client.Get(ctx, types.NamespacedName{Name: p.manager.Spec.AppNamespace}, &ns)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
klog.Errorf("failed to get namespace %s, %v", p.manager.Spec.AppNamespace, err)
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
if delErr := p.client.Delete(ctx, &ns); delErr != nil && !apierrors.IsNotFound(delErr) {
|
||||
klog.Errorf("failed to delete namespace %s, %v", p.manager.Spec.AppNamespace, delErr)
|
||||
return delErr
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *DownloadingCancelingApp) Exec(ctx context.Context) (StatefulInProgressApp, error) {
|
||||
err := p.exec(ctx)
|
||||
if err != nil {
|
||||
updateErr := p.updateStatus(ctx, p.manager, appsv1.DownloadingCancelFailed, nil, err.Error(), "")
|
||||
if updateErr != nil {
|
||||
klog.Errorf("update app manager %s to %s state failed %v", p.manager.Name, appsv1.DownloadingCancelFailed.String(), updateErr)
|
||||
return nil, updateErr
|
||||
}
|
||||
}
|
||||
|
||||
return &downloadingCancelInProgressApp{
|
||||
DownloadingCancelingApp: p,
|
||||
basePollableStatefulInProgressApp: &basePollableStatefulInProgressApp{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *DownloadingCancelingApp) Cancel(ctx context.Context) error {
|
||||
@@ -72,3 +96,58 @@ func (p *DownloadingCancelingApp) Cancel(ctx context.Context) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ PollableStatefulInProgressApp = &downloadingCancelInProgressApp{}
|
||||
|
||||
type downloadingCancelInProgressApp struct {
|
||||
*DownloadingCancelingApp
|
||||
*basePollableStatefulInProgressApp
|
||||
}
|
||||
|
||||
func (p *downloadingCancelInProgressApp) Exec(ctx context.Context) (StatefulInProgressApp, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *downloadingCancelInProgressApp) poll(ctx context.Context) error {
|
||||
if apputils.IsProtectedNamespace(p.manager.Spec.AppNamespace) {
|
||||
return nil
|
||||
}
|
||||
|
||||
timer := time.NewTicker(time.Second)
|
||||
defer timer.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
var ns corev1.Namespace
|
||||
err := p.client.Get(ctx, types.NamespacedName{Name: p.manager.Spec.AppNamespace}, &ns)
|
||||
klog.Infof("downloading cancel poll namespace %s err %v", p.manager.Spec.AppNamespace, err)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("app %s execute cancel operation failed %w", p.manager.Spec.AppName, ctx.Err())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *downloadingCancelInProgressApp) WaitAsync(ctx context.Context) {
|
||||
appFactory.waitForPolling(ctx, p, func(err error) {
|
||||
if err != nil {
|
||||
updateErr := p.updateStatus(context.TODO(), p.manager, appsv1.DownloadingCancelFailed, nil, appsv1.DownloadingCancelFailed.String(), "")
|
||||
if updateErr != nil {
|
||||
klog.Errorf("update app manager %s to %s state failed %v", p.manager.Name, appsv1.DownloadingCancelFailed.String(), updateErr)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
updateErr := p.updateStatus(context.TODO(), p.manager, appsv1.DownloadingCanceled, nil, appsv1.DownloadingCanceled.String(), "")
|
||||
if updateErr != nil {
|
||||
klog.Errorf("update app manager %s to %s state failed %v", p.manager.Name, appsv1.InstallingCanceled.String(), updateErr)
|
||||
return
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -174,12 +174,6 @@ func (p *DownloadingApp) exec(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
values["sysVersion"] = terminus.Spec.Version
|
||||
|
||||
refs, err := p.getRefsForImageManager(appConfig, values)
|
||||
if err != nil {
|
||||
klog.Errorf("get image refs from resources failed %v", err)
|
||||
return err
|
||||
}
|
||||
nodeInfo, err := utils.GetNodeInfo(ctx)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to get node info %v", err)
|
||||
@@ -187,6 +181,12 @@ func (p *DownloadingApp) exec(ctx context.Context) error {
|
||||
}
|
||||
values["nodes"] = nodeInfo
|
||||
|
||||
refs, err := p.getRefsForImageManager(appConfig, values)
|
||||
if err != nil {
|
||||
klog.Errorf("get image refs from resources failed %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.imageClient.Create(ctx, p.manager, refs)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package appstate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
appsv1 "bytetrade.io/web3os/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
"bytetrade.io/web3os/app-service/pkg/images"
|
||||
apputils "bytetrade.io/web3os/app-service/pkg/utils/app"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// FIXME: impossible state
|
||||
|
||||
var _ StatefulApp = &DownloadingCancelFailedApp{}
|
||||
var _ OperationApp = &DownloadingCancelFailedApp{}
|
||||
|
||||
type DownloadingCancelFailedApp struct {
|
||||
*DoNothingApp
|
||||
*baseOperationApp
|
||||
imageClient images.ImageManager
|
||||
}
|
||||
|
||||
func NewDownloadingCancelFailedApp(c client.Client,
|
||||
@@ -20,12 +29,49 @@ func NewDownloadingCancelFailedApp(c client.Client,
|
||||
return appFactory.New(c, manager, 0,
|
||||
func(c client.Client, manager *appsv1.ApplicationManager, ttl time.Duration) StatefulApp {
|
||||
return &DownloadingCancelFailedApp{
|
||||
DoNothingApp: &DoNothingApp{
|
||||
baseOperationApp: &baseOperationApp{
|
||||
ttl: ttl,
|
||||
baseStatefulApp: &baseStatefulApp{
|
||||
manager: manager,
|
||||
client: c,
|
||||
},
|
||||
},
|
||||
imageClient: images.NewImageManager(c),
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func (p *DownloadingCancelFailedApp) Exec(ctx context.Context) (StatefulInProgressApp, error) {
|
||||
if !apputils.IsProtectedNamespace(p.manager.Spec.AppNamespace) {
|
||||
var ns corev1.Namespace
|
||||
err := p.client.Get(ctx, types.NamespacedName{Name: p.manager.Spec.AppNamespace}, &ns)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil {
|
||||
e := p.client.Delete(ctx, &ns)
|
||||
if e != nil {
|
||||
klog.Errorf("failed to delete ns %s, err=%v", p.manager.Spec.AppNamespace, e)
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
}
|
||||
var im appsv1.ImageManager
|
||||
err := p.client.Get(ctx, types.NamespacedName{Name: p.manager.Name}, &im)
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
if im.Status.State != appsv1.DownloadingCanceled.String() {
|
||||
err = p.imageClient.UpdateStatus(ctx, p.manager.Name, appsv1.DownloadingCanceled.String(), appsv1.DownloadingCanceled.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (p *DownloadingCancelFailedApp) Cancel(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var _ OperationApp = &UpgradeFailedApp{}
|
||||
var _ OperationApp = &InstallingCancelFailedApp{}
|
||||
|
||||
type InstallingCancelFailedApp struct {
|
||||
UninstallFailedApp
|
||||
|
||||
@@ -67,9 +67,12 @@ func (p *PendingApp) Exec(ctx context.Context) (StatefulInProgressApp, error) {
|
||||
if success, err := appFactory.addLimitedStatefulApp(ctx,
|
||||
// limit
|
||||
func() (bool, error) {
|
||||
|
||||
var apps appsv1.ApplicationManagerList
|
||||
err := p.client.List(ctx, &apps)
|
||||
clientset, err := utils.GetClient()
|
||||
if err != nil {
|
||||
klog.Errorf("failed to get clientset %v", err)
|
||||
return false, err
|
||||
}
|
||||
apps, err := clientset.AppV1alpha1().ApplicationManagers().List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
klog.Errorf("list application managers error: %v", err)
|
||||
return false, err
|
||||
|
||||
@@ -12,11 +12,15 @@ import (
|
||||
"bytetrade.io/web3os/app-service/pkg/appinstaller"
|
||||
"bytetrade.io/web3os/app-service/pkg/appinstaller/versioned"
|
||||
appevent "bytetrade.io/web3os/app-service/pkg/event"
|
||||
"bytetrade.io/web3os/app-service/pkg/middlewareinstaller"
|
||||
"bytetrade.io/web3os/app-service/pkg/utils"
|
||||
apputils "bytetrade.io/web3os/app-service/pkg/utils/app"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -118,6 +122,10 @@ func (p *baseStatefulApp) forceDeleteApp(ctx context.Context) error {
|
||||
klog.Errorf("get kube config failed %v", err)
|
||||
return err
|
||||
}
|
||||
if appCfg.MiddlewareName == "mongodb" && appCfg.Namespace == "os-platform" {
|
||||
return p.oldMongodbUninstall(ctx, kubeConfig)
|
||||
}
|
||||
|
||||
ops, err := versioned.NewHelmOps(ctx, kubeConfig, appCfg, token, appinstaller.Opt{MarketSource: p.manager.GetMarketSource()})
|
||||
if err != nil {
|
||||
klog.Errorf("make helm ops failed %v", err)
|
||||
@@ -244,3 +252,31 @@ func (p *basePollableStatefulInProgressApp) CreatePollContext() context.Context
|
||||
|
||||
return pollCtx
|
||||
}
|
||||
|
||||
func (b *baseStatefulApp) oldMongodbUninstall(ctx context.Context, kubeConfig *rest.Config) error {
|
||||
mc := &middlewareinstaller.MiddlewareConfig{
|
||||
MiddlewareName: b.manager.Spec.AppName,
|
||||
Namespace: b.manager.Spec.AppNamespace,
|
||||
OwnerName: b.manager.Spec.AppOwner,
|
||||
}
|
||||
err := middlewareinstaller.Uninstall(ctx, kubeConfig, mc)
|
||||
if err != nil && err.Error() != "failed to delete release: mongodb" {
|
||||
klog.Errorf("failed to uninstall old mongodb %v", err)
|
||||
return err
|
||||
}
|
||||
var secret corev1.Secret
|
||||
|
||||
err = b.client.Get(ctx, types.NamespacedName{Name: "sh.helm.release.v1.mongodb.v1", Namespace: mc.Namespace}, &secret)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = b.client.Delete(ctx, &secret); err != nil && !apierrors.IsNotFound(err) {
|
||||
klog.Errorf("failed to delete mongodb release secret: %s", secret.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (p *UninstallingApp) Exec(ctx context.Context) (StatefulInProgressApp, erro
|
||||
err := p.exec(c)
|
||||
if err != nil {
|
||||
p.finally = func() {
|
||||
klog.Infof("uninstalling app %s failed,", p.manager.Spec.AppName)
|
||||
klog.Infof("uninstalling app %s failed %v", p.manager.Spec.AppName, err)
|
||||
opRecord := makeRecord(p.manager, appsv1.UninstallFailed, fmt.Sprintf(constants.OperationFailedTpl, p.manager.Spec.OpType, err.Error()))
|
||||
updateErr := p.updateStatus(context.TODO(), p.manager, appsv1.UninstallFailed, opRecord, err.Error(), "")
|
||||
if updateErr != nil {
|
||||
@@ -178,6 +178,10 @@ func (p *UninstallingApp) exec(ctx context.Context) error {
|
||||
klog.Errorf("get kube config failed %v", err)
|
||||
return err
|
||||
}
|
||||
if appCfg.MiddlewareName == "mongodb" && appCfg.Namespace == "os-platform" {
|
||||
klog.Infof("delete old mongodb ..........")
|
||||
return p.oldMongodbUninstall(ctx, kubeConfig)
|
||||
}
|
||||
ops, err := versioned.NewHelmOps(ctx, kubeConfig, appCfg, token, appinstaller.Opt{MarketSource: p.manager.GetMarketSource()})
|
||||
if err != nil {
|
||||
klog.Errorf("make helm ops failed %v", err)
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var _ OperationApp = &UpgradeFailedApp{}
|
||||
var _ StatefulApp = &UpgradeFailedApp{}
|
||||
|
||||
type UpgradeFailedApp struct {
|
||||
SuspendFailedApp
|
||||
*DoNothingApp
|
||||
}
|
||||
|
||||
func NewUpgradeFailedApp(c client.Client,
|
||||
@@ -18,13 +18,10 @@ func NewUpgradeFailedApp(c client.Client,
|
||||
return appFactory.New(c, manager, 0,
|
||||
func(c client.Client, manager *appsv1.ApplicationManager, ttl time.Duration) StatefulApp {
|
||||
return &UpgradeFailedApp{
|
||||
SuspendFailedApp: SuspendFailedApp{
|
||||
&baseOperationApp{
|
||||
ttl: ttl,
|
||||
baseStatefulApp: &baseStatefulApp{
|
||||
manager: manager,
|
||||
client: c,
|
||||
},
|
||||
DoNothingApp: &DoNothingApp{
|
||||
baseStatefulApp: &baseStatefulApp{
|
||||
manager: manager,
|
||||
client: c,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ func UpgradeCharts(ctx context.Context, actionConfig *action.Configuration, sett
|
||||
client.Namespace = namespace
|
||||
client.Timeout = 300 * time.Second
|
||||
client.Recreate = false
|
||||
client.Atomic = true
|
||||
if reuseValue {
|
||||
client.ReuseValues = true
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (imc *ImageManagerClient) PollDownloadProgress(ctx context.Context, am *app
|
||||
|
||||
}
|
||||
err = imc.updateProgress(ctx, am, &lastProgress, ret*100, am.Spec.OpType == appv1alpha1.UpgradeOp)
|
||||
if err == nil {
|
||||
if err == nil && im.Status.State == "completed" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,14 @@ func Uninstall(ctx context.Context, kubeConfig *rest.Config, middleware *Middlew
|
||||
return err
|
||||
}
|
||||
|
||||
if installed, err := helmClient.IsInstalled(middleware.MiddlewareName); err != nil {
|
||||
installed, err := helmClient.IsInstalled(middleware.MiddlewareName)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to get install history middlewareName=%s err=%v", middleware.MiddlewareName, err)
|
||||
return err
|
||||
} else if !installed {
|
||||
return errors.New("middleware not installed")
|
||||
}
|
||||
if !installed {
|
||||
klog.Infof("middleware %s is not installed", middleware.MiddlewareName)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = helmClient.Uninstall(middleware.MiddlewareName)
|
||||
|
||||
@@ -3,12 +3,12 @@ package security
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/pkg/constants"
|
||||
"bytetrade.io/web3os/app-service/pkg/utils"
|
||||
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/pointer"
|
||||
netv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user