Merge branch 'delete-third-party-service' of https://github.com/GLYASAI/rainbond into delete-third-party-service

This commit is contained in:
GLYASAI 2020-09-16 10:11:29 +08:00
commit e0c329319d
30 changed files with 678 additions and 201 deletions

View File

@ -25,6 +25,11 @@ import (
// ClusterInterface -
type ClusterInterface interface {
GetClusterInfo(w http.ResponseWriter, r *http.Request)
MavenSettingList(w http.ResponseWriter, r *http.Request)
MavenSettingAdd(w http.ResponseWriter, r *http.Request)
MavenSettingUpdate(w http.ResponseWriter, r *http.Request)
MavenSettingDelete(w http.ResponseWriter, r *http.Request)
MavenSettingDetail(w http.ResponseWriter, r *http.Request)
}
//TenantInterface interface

View File

@ -82,6 +82,11 @@ func (v2 *V2) eventsRouter() chi.Router {
func (v2 *V2) clusterRouter() chi.Router {
r := chi.NewRouter()
r.Get("/", controller.GetManager().GetClusterInfo)
r.Get("/builder/mavensetting", controller.GetManager().MavenSettingList)
r.Post("/builder/mavensetting", controller.GetManager().MavenSettingAdd)
r.Get("/builder/mavensetting/{name}", controller.GetManager().MavenSettingDetail)
r.Put("/builder/mavensetting/{name}", controller.GetManager().MavenSettingUpdate)
r.Delete("/builder/mavensetting/{name}", controller.GetManager().MavenSettingDelete)
return r
}

View File

@ -22,6 +22,7 @@ import (
"net/http"
"github.com/Sirupsen/logrus"
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/api/handler"
httputil "github.com/goodrain/rainbond/util/http"
@ -42,3 +43,61 @@ func (t *ClusterController) GetClusterInfo(w http.ResponseWriter, r *http.Reques
httputil.ReturnSuccess(r, w, nodes)
}
//MavenSettingList maven setting list
func (t *ClusterController) MavenSettingList(w http.ResponseWriter, r *http.Request) {
httputil.ReturnSuccess(r, w, handler.GetClusterHandler().MavenSettingList())
}
//MavenSettingAdd maven setting add
func (t *ClusterController) MavenSettingAdd(w http.ResponseWriter, r *http.Request) {
var set handler.MavenSetting
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &set, nil); !ok {
return
}
if err := handler.GetClusterHandler().MavenSettingAdd(&set); err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, &set)
}
//MavenSettingUpdate maven setting file update
func (t *ClusterController) MavenSettingUpdate(w http.ResponseWriter, r *http.Request) {
type SettingUpdate struct {
Content string `json:"content" validate:"required"`
}
var su SettingUpdate
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &su, nil); !ok {
return
}
set := &handler.MavenSetting{
Name: chi.URLParam(r, "name"),
Content: su.Content,
}
if err := handler.GetClusterHandler().MavenSettingUpdate(set); err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, set)
}
//MavenSettingDelete maven setting file delete
func (t *ClusterController) MavenSettingDelete(w http.ResponseWriter, r *http.Request) {
err := handler.GetClusterHandler().MavenSettingDelete(chi.URLParam(r, "name"))
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, nil)
}
//MavenSettingDetail maven setting file delete
func (t *ClusterController) MavenSettingDetail(w http.ResponseWriter, r *http.Request) {
c, err := handler.GetClusterHandler().MavenSettingDetail(chi.URLParam(r, "name"))
if err != nil {
err.Handle(r, w)
return
}
httputil.ReturnSuccess(r, w, c)
}

View File

@ -3,11 +3,14 @@ package handler
import (
"fmt"
"runtime"
"time"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/api/model"
"github.com/goodrain/rainbond/api/util"
"github.com/shirou/gopsutil/disk"
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/fields"
"k8s.io/client-go/kubernetes"
@ -16,16 +19,23 @@ import (
// ClusterHandler -
type ClusterHandler interface {
GetClusterInfo() (*model.ClusterResource, error)
MavenSettingAdd(ms *MavenSetting) *util.APIHandleError
MavenSettingList() (re []MavenSetting)
MavenSettingUpdate(ms *MavenSetting) *util.APIHandleError
MavenSettingDelete(name string) *util.APIHandleError
MavenSettingDetail(name string) (*MavenSetting, *util.APIHandleError)
}
// NewClusterHandler -
func NewClusterHandler(clientset *kubernetes.Clientset) ClusterHandler {
func NewClusterHandler(clientset *kubernetes.Clientset, RbdNamespace string) ClusterHandler {
return &clusterAction{
namespace: RbdNamespace,
clientset: clientset,
}
}
type clusterAction struct {
namespace string
clientset *kubernetes.Clientset
}
@ -184,3 +194,113 @@ func (c *clusterAction) listPods(nodeName string) (pods []corev1.Pod, err error)
return podList.Items, nil
}
//MavenSetting maven setting
type MavenSetting struct {
Name string `json:"name" validate:"required"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
Content string `json:"content" validate:"required"`
}
//MavenSettingList maven setting list
func (c *clusterAction) MavenSettingList() (re []MavenSetting) {
cms, err := c.clientset.CoreV1().ConfigMaps(c.namespace).List(metav1.ListOptions{
LabelSelector: "configtype=mavensetting",
})
if err != nil {
logrus.Errorf("list maven setting config list failure %s", err.Error())
}
for _, sm := range cms.Items {
re = append(re, MavenSetting{
Name: sm.Name,
CreateTime: sm.CreationTimestamp.Format(time.RFC3339),
UpdateTime: sm.Labels["updateTime"],
Content: sm.Data["mavensetting"],
})
}
return
}
//MavenSettingAdd maven setting add
func (c *clusterAction) MavenSettingAdd(ms *MavenSetting) *util.APIHandleError {
config := &corev1.ConfigMap{}
config.Name = ms.Name
config.Namespace = c.namespace
config.Labels = map[string]string{
"creator": "Rainbond",
"configtype": "mavensetting",
}
config.Annotations = map[string]string{
"updateTime": time.Now().Format(time.RFC3339),
}
config.Data = map[string]string{
"mavensetting": ms.Content,
}
_, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Create(config)
if err != nil {
if apierrors.IsAlreadyExists(err) {
return &util.APIHandleError{Code: 400, Err: fmt.Errorf("setting name is exist")}
}
logrus.Errorf("create maven setting configmap failure %s", err.Error())
return &util.APIHandleError{Code: 500, Err: fmt.Errorf("create setting config failure")}
}
ms.CreateTime = time.Now().Format(time.RFC3339)
ms.UpdateTime = time.Now().Format(time.RFC3339)
return nil
}
//MavenSettingUpdate maven setting file update
func (c *clusterAction) MavenSettingUpdate(ms *MavenSetting) *util.APIHandleError {
sm, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Get(ms.Name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return &util.APIHandleError{Code: 404, Err: fmt.Errorf("setting name is not exist")}
}
logrus.Errorf("get maven setting config list failure %s", err.Error())
return &util.APIHandleError{Code: 400, Err: fmt.Errorf("get setting failure")}
}
if sm.Data == nil {
sm.Data = make(map[string]string)
}
if sm.Annotations == nil {
sm.Annotations = make(map[string]string)
}
sm.Data["mavensetting"] = ms.Content
sm.Annotations["updateTime"] = time.Now().Format(time.RFC3339)
if _, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Update(sm); err != nil {
logrus.Errorf("update maven setting configmap failure %s", err.Error())
return &util.APIHandleError{Code: 500, Err: fmt.Errorf("update setting config failure")}
}
ms.UpdateTime = sm.Annotations["updateTime"]
ms.CreateTime = sm.CreationTimestamp.Format(time.RFC3339)
return nil
}
//MavenSettingDelete maven setting file delete
func (c *clusterAction) MavenSettingDelete(name string) *util.APIHandleError {
err := c.clientset.CoreV1().ConfigMaps(c.namespace).Delete(name, &metav1.DeleteOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
return &util.APIHandleError{Code: 404, Err: fmt.Errorf("setting not found")}
}
logrus.Errorf("delete maven setting config list failure %s", err.Error())
return &util.APIHandleError{Code: 500, Err: fmt.Errorf("setting delete failure")}
}
return nil
}
//MavenSettingDetail maven setting file delete
func (c *clusterAction) MavenSettingDetail(name string) (*MavenSetting, *util.APIHandleError) {
sm, err := c.clientset.CoreV1().ConfigMaps(c.namespace).Get(name, metav1.GetOptions{})
if err != nil {
logrus.Errorf("get maven setting config failure %s", err.Error())
return nil, &util.APIHandleError{Code: 404, Err: fmt.Errorf("setting not found")}
}
return &MavenSetting{
Name: sm.Name,
CreateTime: sm.CreationTimestamp.Format(time.RFC3339),
UpdateTime: sm.Annotations["updateTime"],
Content: sm.Data["mavensetting"],
}, nil
}

View File

@ -68,7 +68,7 @@ func InitHandle(conf option.Config,
batchOperationHandler = CreateBatchOperationHandler(mqClient, operationHandler)
defaultAppRestoreHandler = NewAppRestoreHandler()
defPodHandler = NewPodHandler(statusCli)
defClusterHandler = NewClusterHandler(kubeClient)
defClusterHandler = NewClusterHandler(kubeClient, conf.RbdNamespace)
defaultVolumeTypeHandler = CreateVolumeTypeManger(statusCli)
defaultEtcdHandler = NewEtcdHandler(etcdcli)

View File

@ -137,7 +137,9 @@ func (t *TenantAction) DeleteTenant(tenantID string) error {
return err
}
if len(services) > 0 {
return ErrTenantStillHasServices
for _, service := range services {
GetServiceManager().TransServieToDelete(tenantID, service.ServiceID)
}
}
// check if there are still plugins
@ -146,7 +148,9 @@ func (t *TenantAction) DeleteTenant(tenantID string) error {
return err
}
if len(plugins) > 0 {
return ErrTenantStillHasPlugins
for _, plugin := range plugins {
GetPluginManager().DeletePluginAct(plugin.PluginID, tenantID)
}
}
tenant, err := db.GetManager().TenantDao().GetTenantByUUID(tenantID)
@ -408,6 +412,11 @@ func (t *TenantAction) initClusterResource() error {
return err
}
for _, node := range nodes.Items {
// check if node contains taints
if containsTaints(&node) {
logrus.Debugf("[GetClusterInfo] node(%s) contains NoSchedule taints", node.GetName())
continue
}
if node.Spec.Unschedulable {
continue
}
@ -417,7 +426,7 @@ func (t *TenantAction) initClusterResource() error {
}
}
crs.AllMemory += node.Status.Allocatable.Memory().Value() / (1024 * 1024)
crs.AllCPU += node.Status.Allocatable.Cpu().Value()
crs.AllCPU += node.Status.Allocatable.Cpu().MilliValue()
}
t.cacheClusterResourceStats = &crs
t.cacheTime = time.Now()

View File

@ -95,15 +95,21 @@ func (list TenantList) Less(i, j int) bool {
if list[i].MemoryRequest > list[j].MemoryRequest {
return true
}
if list[i].CPURequest > list[j].CPURequest {
return true
}
if list[i].RunningAppNum > list[j].RunningAppNum {
return true
}
// Minimum priority
if list[i].Tenants.LimitMemory > list[j].Tenants.LimitMemory {
return true
if list[i].MemoryRequest == list[j].MemoryRequest {
if list[i].CPURequest > list[j].CPURequest {
return true
}
if list[i].CPURequest == list[j].CPURequest {
if list[i].RunningAppNum > list[j].RunningAppNum {
return true
}
if list[i].RunningAppNum == list[j].RunningAppNum {
// Minimum priority
if list[i].Tenants.LimitMemory > list[j].Tenants.LimitMemory {
return true
}
}
}
}
return false
}

View File

@ -38,12 +38,23 @@ func TestTenantList(t *testing.T) {
tenants.Add(t2)
t3 := &TenantAndResource{
MemoryRequest: 80,
MemoryRequest: 0,
}
t3.LimitMemory = 60
t4 := &TenantAndResource{
MemoryRequest: 0,
}
t4.LimitMemory = 70
t5 := &TenantAndResource{
RunningAppNum: 10,
}
t5.LimitMemory = 0
tenants.Add(t3)
sort.Sort(sort.Reverse(tenants))
tenants.Add(t4)
tenants.Add(t5)
sort.Sort(tenants)
for _, ten := range tenants {
t.Logf("%+v", ten)
}

View File

@ -33,11 +33,11 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/eapache/channels"
"github.com/fsnotify/fsnotify"
"github.com/goodrain/rainbond/builder"
jobc "github.com/goodrain/rainbond/builder/job"
"github.com/goodrain/rainbond/builder/parser/code"
"github.com/goodrain/rainbond/builder/sources"
"github.com/goodrain/rainbond/event"
"github.com/goodrain/rainbond/util"
@ -232,10 +232,10 @@ func (s *slugBuild) getSourceCodeTarFile(re *Request) (string, error) {
var cmd []string
sourceTarFile := fmt.Sprintf("%s/%s-%s.tar", util.GetParentDirectory(re.SourceDir), re.ServiceID, re.DeployVersion)
if re.ServerType == "svn" {
cmd = append(cmd, "tar", "-cf", sourceTarFile, "--exclude=.svn", "./")
cmd = append(cmd, "tar", "-cf", sourceTarFile, "./")
}
if re.ServerType == "git" {
cmd = append(cmd, "tar", "-cf", sourceTarFile, "--exclude=.git", "./")
cmd = append(cmd, "tar", "-cf", sourceTarFile, "./")
}
source := exec.Command(cmd[0], cmd[1:]...)
source.Dir = re.SourceDir
@ -277,23 +277,6 @@ func (s *slugBuild) runBuildJob(re *Request) error {
}()
name := fmt.Sprintf("%s-%s", re.ServiceID, re.DeployVersion)
namespace := re.RbdNamespace
envs := []corev1.EnvVar{
{Name: "SLUG_VERSION", Value: re.DeployVersion},
{Name: "SERVICE_ID", Value: re.ServiceID},
{Name: "TENANT_ID", Value: re.TenantID},
{Name: "LANGUAGE", Value: re.Lang.String()},
}
for k, v := range re.BuildEnvs {
envs = append(envs, corev1.EnvVar{Name: k, Value: v})
if k == "PROC_ENV" {
var mapdata = make(map[string]interface{})
if err := json.Unmarshal([]byte(v), &mapdata); err == nil {
if runtime, ok := mapdata["runtimes"]; ok {
envs = append(envs, corev1.EnvVar{Name: "RUNTIME", Value: runtime.(string)})
}
}
}
}
job := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: name,
@ -304,7 +287,35 @@ func (s *slugBuild) runBuildJob(re *Request) error {
},
},
}
envs := []corev1.EnvVar{
{Name: "SLUG_VERSION", Value: re.DeployVersion},
{Name: "SERVICE_ID", Value: re.ServiceID},
{Name: "TENANT_ID", Value: re.TenantID},
{Name: "LANGUAGE", Value: re.Lang.String()},
}
var mavenSettingName string
for k, v := range re.BuildEnvs {
if k == "MAVEN_SETTING_NAME" {
mavenSettingName = v
continue
}
if k == "PROCFILE" {
if !strings.HasPrefix(v, "web:") {
v = "web: " + v
} else if v[4] != ' ' {
v = "web: " + v[4:]
}
}
envs = append(envs, corev1.EnvVar{Name: k, Value: v})
if k == "PROC_ENV" {
var mapdata = make(map[string]interface{})
if err := json.Unmarshal([]byte(v), &mapdata); err == nil {
if runtime, ok := mapdata["runtimes"]; ok {
envs = append(envs, corev1.EnvVar{Name: "RUNTIME", Value: runtime.(string)})
}
}
}
}
podSpec := corev1.PodSpec{RestartPolicy: corev1.RestartPolicyOnFailure} // only support never and onfailure
// schedule builder
if re.CacheMode == "hostpath" {
@ -337,10 +348,14 @@ func (s *slugBuild) runBuildJob(re *Request) error {
VolumeSource: re.CacheVolumeSource(),
},
}
container := corev1.Container{Name: name, Image: builder.BUILDERIMAGENAME, Stdin: true, StdinOnce: true}
container.Env = envs
container.Args = []string{"local"}
container := corev1.Container{
Name: name,
Image: builder.BUILDERIMAGENAME,
Stdin: true,
StdinOnce: true,
Env: envs,
Args: []string{"local"},
}
slugSubPath := strings.TrimPrefix(re.TGZDir, "/grdata/")
logrus.Debugf("sourceTarFileName is: %s", sourceTarFileName)
sourceTarPath := strings.TrimPrefix(sourceTarFileName, "/cache/")
@ -362,6 +377,44 @@ func (s *slugBuild) runBuildJob(re *Request) error {
SubPath: sourceTarPath,
},
}
//set maven setting
var mavenSettingConfigName string
if mavenSettingName != "" && re.Lang.String() == code.JavaMaven.String() {
if setting := jobc.GetJobController().GetLanguageBuildSetting(code.JavaMaven, mavenSettingName); setting != "" {
mavenSettingConfigName = setting
} else {
logrus.Warnf("maven setting config %s not found", mavenSettingName)
}
} else if settingName := jobc.GetJobController().GetDefaultLanguageBuildSetting(code.JavaMaven); settingName != "" {
mavenSettingConfigName = settingName
}
if mavenSettingConfigName != "" {
podSpec.Volumes = append(podSpec.Volumes, corev1.Volume{
Name: "mavensetting",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: mavenSettingConfigName,
},
},
},
})
mountPath := "/etc/maven/setting.xml"
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
MountPath: mountPath,
SubPath: "mavensetting",
Name: "mavensetting",
})
container.Env = append(container.Env, corev1.EnvVar{
Name: "MAVEN_SETTINGS_PATH",
Value: mountPath,
})
container.Env = append(container.Env, corev1.EnvVar{
Name: "MAVEN_MIRROR_DISABLE",
Value: "true",
})
logrus.Infof("set maven setting config %s success", mavenSettingName)
}
podSpec.Containers = append(podSpec.Containers, container)
for _, ha := range re.HostAlias {
podSpec.HostAliases = append(podSpec.HostAliases, corev1.HostAlias{IP: ha.IP, Hostnames: ha.Hostnames})
@ -425,116 +478,6 @@ func (s *slugBuild) waitingComplete(re *Request, reChan *channels.RingChannel) (
}
}
//runBuildContainer The deprecated
func (s *slugBuild) runBuildContainer(re *Request) error {
envs := []*sources.KeyValue{
&sources.KeyValue{Key: "SLUG_VERSION", Value: re.DeployVersion},
&sources.KeyValue{Key: "SERVICE_ID", Value: re.ServiceID},
&sources.KeyValue{Key: "TENANT_ID", Value: re.TenantID},
&sources.KeyValue{Key: "LANGUAGE", Value: re.Lang.String()},
}
for k, v := range re.BuildEnvs {
envs = append(envs, &sources.KeyValue{Key: k, Value: v})
if k == "PROC_ENV" {
var mapdata = make(map[string]interface{})
if err := json.Unmarshal([]byte(v), &mapdata); err == nil {
if runtime, ok := mapdata["runtimes"]; ok {
envs = append(envs, &sources.KeyValue{Key: "RUNTIME", Value: runtime.(string)})
}
}
}
}
containerConfig := &sources.ContainerConfig{
Metadata: &sources.ContainerMetadata{
Name: re.ServiceID[:8] + "_" + re.DeployVersion,
},
Image: &sources.ImageSpec{
Image: builder.BUILDERIMAGENAME,
},
Mounts: []*sources.Mount{
&sources.Mount{
ContainerPath: "/tmp/cache",
HostPath: re.CacheDir,
Readonly: false,
},
&sources.Mount{
ContainerPath: "/tmp/slug",
HostPath: s.tgzDir,
Readonly: false,
},
},
Envs: envs,
Stdin: true,
StdinOnce: true,
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
NetworkConfig: &sources.NetworkConfig{
NetworkMode: "host",
},
Args: []string{"local"},
ExtraHosts: re.ExtraHosts,
}
sourceTarFileName, err := s.getSourceCodeTarFile(re)
if err != nil {
return fmt.Errorf("create source code tar file error:%s", err.Error())
}
reader, err := os.OpenFile(sourceTarFileName, os.O_RDONLY, 0755)
if err != nil {
return fmt.Errorf("open source code tar file error:%s", err.Error())
}
defer func() {
reader.Close()
os.Remove(reader.Name())
}()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
containerService := sources.CreateDockerService(ctx, re.DockerClient)
containerID, err := containerService.CreateContainer(containerConfig)
if err != nil {
if client.IsErrNotFound(err) {
// we don't want to write to stdout anything apart from container.ID
if _, err = sources.ImagePull(re.DockerClient, containerConfig.Image.Image, builder.REGISTRYUSER, builder.REGISTRYPASS, re.Logger, 20); err != nil {
return fmt.Errorf("pull builder container image error:%s", err.Error())
}
// Retry
containerID, err = containerService.CreateContainer(containerConfig)
}
//The container already exists.
if err != nil && strings.Contains(err.Error(), "is already in use by container") {
//remove exist container
containerService.RemoveContainer(containerID)
// Retry
containerID, err = containerService.CreateContainer(containerConfig)
}
if err != nil {
return fmt.Errorf("create builder container failure %s", err.Error())
}
}
errchan := make(chan error, 1)
writer := re.Logger.GetWriter("builder", "info")
close, err := containerService.AttachContainer(containerID, true, true, true, reader, writer, writer, &errchan)
if err != nil {
containerService.RemoveContainer(containerID)
return fmt.Errorf("attach builder container error:%s", err.Error())
}
defer close()
statuschan := containerService.WaitExitOrRemoved(containerID, true)
//start the container
if err := containerService.StartContainer(containerID); err != nil {
containerService.RemoveContainer(containerID)
return fmt.Errorf("start builder container error:%s", err.Error())
}
if err := <-errchan; err != nil {
logrus.Debugf("Error hijack: %s", err)
}
status := <-statuschan
if status != 0 {
return &ErrorBuild{Code: status}
}
return nil
}
func (s *slugBuild) setImagePullSecretsForPod(pod *corev1.Pod) {
imagePullSecretName := os.Getenv("IMAGE_PULL_SECRET")
if imagePullSecretName == "" {

View File

@ -167,9 +167,10 @@ func (i *ImportApp) importApp() error {
//new image will create by new app store hub config
oldname, _ := app.Get("share_image").String()
image := parser.ParseImageName(oldname)
newImage := fmt.Sprintf("%s/%s/%s:%s", i.ServiceImage.HubUrl, i.ServiceImage.NameSpace, image.GetSimpleName(), image.GetTag())
imageRepo := builder.GetImageRepo(i.ServiceImage.HubUrl)
newImage := fmt.Sprintf("%s/%s/%s:%s", imageRepo, i.ServiceImage.NameSpace, image.GetSimpleName(), image.GetTag())
if i.ServiceImage.NameSpace == "" {
newImage = fmt.Sprintf("%s/%s:%s", i.ServiceImage.HubUrl, image.GetSimpleName(), image.GetTag())
newImage = fmt.Sprintf("%s/%s:%s", imageRepo, image.GetSimpleName(), image.GetTag())
}
return newImage
}
@ -354,7 +355,8 @@ func (i *ImportApp) importPlugins() error {
return fmt.Errorf("change plugin image tag(%s => %s) error %s", saveImageName, newImageName, err.Error())
}
}
if err := sources.ImagePush(i.DockerClient, newImageName, i.ServiceImage.HubUser, i.ServiceImage.HubPassword, i.Logger, 30); err != nil {
user, pass := builder.GetImageUserInfo(i.ServiceImage.HubUser, i.ServiceImage.HubPassword)
if err := sources.ImagePush(i.DockerClient, newImageName, user, pass, i.Logger, 30); err != nil {
return fmt.Errorf("push plugin image %s error %s", image, err.Error())
}
logrus.Debug("Successful load and push the plugin image ", image)
@ -403,7 +405,8 @@ func (i *ImportApp) loadApps() error {
return fmt.Errorf("change image tag(%s => %s) error %s", saveImageName, image, err.Error())
}
}
if err := sources.ImagePush(i.DockerClient, image, i.ServiceImage.HubUser, i.ServiceImage.HubPassword, i.Logger, 30); err != nil {
user, pass := builder.GetImageUserInfo(i.ServiceImage.HubUser, i.ServiceImage.HubPassword)
if err := sources.ImagePush(i.DockerClient, image, user, pass, i.Logger, 30); err != nil {
return fmt.Errorf("push image %s error %s", image, err.Error())
}
logrus.Debugf("Successful load and push the image %s", image)

View File

@ -27,6 +27,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/eapache/channels"
"github.com/goodrain/rainbond/builder/parser/code"
corev1 "k8s.io/api/core/v1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -43,6 +44,8 @@ type Controller interface {
GetJob(string) (*corev1.Pod, error)
GetServiceJobs(serviceID string) ([]*corev1.Pod, error)
DeleteJob(job string)
GetLanguageBuildSetting(lang code.Lang, name string) string
GetDefaultLanguageBuildSetting(lang code.Lang) string
}
type controller struct {
KubeClient kubernetes.Interface
@ -228,3 +231,29 @@ func (c *controller) DeleteJob(job string) {
c.jobContainerStatus.Delete(job)
logrus.Infof("delete job %s finish", job)
}
func (c *controller) GetLanguageBuildSetting(lang code.Lang, name string) string {
config, err := c.KubeClient.CoreV1().ConfigMaps(c.namespace).Get(name, metav1.GetOptions{})
if err != nil {
logrus.Errorf("get configmap %s failure %s", name, err.Error())
}
if config != nil {
return name
}
return ""
}
func (c *controller) GetDefaultLanguageBuildSetting(lang code.Lang) string {
config, err := c.KubeClient.CoreV1().ConfigMaps(c.namespace).List(metav1.ListOptions{
LabelSelector: "default=true",
})
if err != nil {
logrus.Errorf("get default maven setting configmap failure %s", err.Error())
}
if config != nil {
for _, c := range config.Items {
return c.Name
}
}
return ""
}

View File

@ -75,7 +75,7 @@ func (d *DockerRunOrImageParse) Parse() ParseErrorList {
}
//docker run
if strings.HasPrefix(d.source, "docker") {
d.ParseDockerun(strings.Split(d.source, " "))
d.ParseDockerun(d.source)
if d.image.String() == "" || d.image.String() == ":" {
d.errappend(ErrorAndSolve(FatalError, fmt.Sprintf("镜像名称识别失败"), SolveAdvice("modify_image", "请确认输入DockerRun命令是否正确")))
return d.errors
@ -139,13 +139,20 @@ func (d *DockerRunOrImageParse) Parse() ParseErrorList {
}
//ParseDockerun parse docker run command
func (d *DockerRunOrImageParse) ParseDockerun(source []string) {
func (d *DockerRunOrImageParse) ParseDockerun(cmd string) {
var name string
source = util.RemoveSpaces(source)
cmd = strings.TrimLeft(cmd, " ")
cmd = strings.Replace(cmd, "\n", "", -1)
cmd = strings.Replace(cmd, "\r", "", -1)
cmd = strings.Replace(cmd, "\t", "", -1)
cmd = strings.Replace(cmd, "\\", "", -1)
cmd = strings.Replace(cmd, " ", " ", -1)
source := util.RemoveSpaces(strings.Split(cmd, " "))
for i, s := range source {
if s == "docker" || s == "run" {
continue
}
fmt.Println(name)
if strings.HasPrefix(s, "-") {
name = strings.TrimLeft(s, "-")
index := strings.Index(name, "=")
@ -179,12 +186,12 @@ func (d *DockerRunOrImageParse) ParseDockerun(source []string) {
} else {
switch name {
case "e", "env":
info := strings.Split(s, "=")
info := strings.Split(removeQuotes(s), "=")
if len(info) == 2 {
d.envs[info[0]] = &types.Env{Name: info[0], Value: info[1]}
}
case "p", "public":
info := strings.Split(s, ":")
info := strings.Split(removeQuotes(s), ":")
if len(info) == 2 {
port, _ := strconv.Atoi(info[1])
if port != 0 {
@ -192,13 +199,13 @@ func (d *DockerRunOrImageParse) ParseDockerun(source []string) {
}
}
case "v", "volume":
info := strings.Split(s, ":")
info := strings.Split(removeQuotes(s), ":")
if len(info) >= 2 {
d.volumes[info[1]] = &types.Volume{VolumePath: info[1], VolumeType: model.ShareFileVolumeType.String()}
}
case "memory", "m":
d.memory = readmemory(s)
case "", "d", "i", "t", "it", "P":
case "", "d", "i", "t", "it", "P", "rm", "init", "interactive", "no-healthcheck", "oom-kill-disable", "privileged", "read-only", "tty", "sig-proxy":
d.image = ParseImageName(s)
if len(source) > i+1 {
d.args = source[i+1:]

View File

@ -20,6 +20,8 @@ package parser
import (
"testing"
"github.com/goodrain/rainbond/builder/parser/types"
)
func TestParseImageName(t *testing.T) {
@ -85,3 +87,24 @@ func TestReadmemory(t *testing.T) {
}
}
}
func TestParseDockerRun(t *testing.T) {
var dr = &DockerRunOrImageParse{
ports: make(map[int]*types.Port),
volumes: make(map[string]*types.Volume),
envs: make(map[string]*types.Env),
}
drs := `
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \
-e "MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
minio/minio server /data`
dr.ParseDockerun(drs)
t.Log(dr.GetEnvs())
t.Log(dr.GetPorts())
t.Log(dr.GetVolumes())
t.Log(dr.GetArgs())
t.Log(dr.GetImage())
}

View File

@ -513,6 +513,16 @@ func (d *SourceCodeParse) GetServiceInfo() []ServiceInfo {
return res
}
func removeQuotes(value string) string {
if len(value) > 0 && (value[0] == '"' || value[0] == '\'') {
value = value[1:]
}
if len(value) > 0 && (value[len(value)-1] == '"' || value[0] == '\'') {
value = value[:len(value)-1]
}
return value
}
func (d *SourceCodeParse) parseDockerfileInfo(dockerfile string) bool {
commands, err := sources.ParseFile(dockerfile)
if err != nil {
@ -527,14 +537,14 @@ func (d *SourceCodeParse) parseDockerfileInfo(dockerfile string) bool {
for i := 0; i < length; i++ {
if kv := strings.Split(cm.Value[i], "="); len(kv) > 1 {
key := "BUILD_ARG_" + kv[0]
d.envs[key] = &types.Env{Name: key, Value: kv[1]}
d.envs[key] = &types.Env{Name: key, Value: removeQuotes(kv[1])}
} else {
if i+1 >= length {
logrus.Error("Parse ARG format error at ", cm.Value[i])
continue
}
key := "BUILD_ARG_" + cm.Value[i]
d.envs[key] = &types.Env{Name: key, Value: cm.Value[i+1]}
d.envs[key] = &types.Env{Name: key, Value: removeQuotes(cm.Value[i+1])}
i++
}
}

View File

@ -68,6 +68,13 @@ func GetImageUserInfoV2(domain, user, pass string) (string, string) {
return "", ""
}
func GetImageRepo(imageRepo string) string {
if imageRepo == "" {
return REGISTRYDOMAIN
}
return imageRepo
}
//REGISTRYDOMAIN REGISTRY_DOMAIN
var REGISTRYDOMAIN = constants.DefImageRepository

View File

@ -253,7 +253,6 @@ func ImagePush(dockerCli *client.Client, image, user, pass string, logger event.
}
return err
}
logger.Info(fmt.Sprintf("success push image%s", image), map[string]string{"step": "pushimage"})
if readcloser != nil {
defer readcloser.Close()
dec := json.NewDecoder(readcloser)
@ -275,8 +274,8 @@ func ImagePush(dockerCli *client.Client, image, user, pass string, logger event.
}
logger.Debug(jm.JSONString(), map[string]string{"step": "progress"})
}
}
logger.Info(fmt.Sprintf("success push image%s", image), map[string]string{"step": "pushimage"})
return nil
}

View File

@ -59,6 +59,7 @@ type Config struct {
LogPath string
KuberentesDashboardAPI string
KubeConfigPath string
RbdNamespace string
}
//APIServer apiserver server
@ -109,6 +110,7 @@ func (a *APIServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&a.LogPath, "log-path", "/grdata/logs", "Where Docker log files and event log files are stored.")
fs.StringVar(&a.KubeConfigPath, "kube-config", "", "kube config file path, No setup is required to run in a cluster.")
fs.StringVar(&a.KuberentesDashboardAPI, "k8s-dashboard-api", "kubernetes-dashboard.rbd-system:443", "The service DNS name of Kubernetes dashboard. Default to kubernetes-dashboard.kubernetes-dashboard")
fs.StringVar(&a.RbdNamespace, "rbd-namespace", "rbd-system", "rbd component namespace")
}
//SetLog 设置log

View File

@ -230,9 +230,11 @@ func (c *Config) CompleteConfig() {
if c.Web.EnableLifecycle {
defaultOptions += " --web.enable-lifecycle"
}
if c.Web.ExternalURL != "" {
defaultOptions += fmt.Sprintf(" --web.external-url=%s", c.Web.ExternalURL)
}
args := strings.Split(defaultOptions, " ")
c.StartArgs = append(c.StartArgs, os.Args[0])
c.StartArgs = append(c.StartArgs, args...)
level, err := logrus.ParseLevel(c.LogLevel)

View File

@ -33,7 +33,14 @@ type Server struct {
Locations []*Location
OptionValue map[string]string
UpstreamName string //used for tcp and udp server
ProxyStreamTimeout string
// Sets the number of datagrams expected from the proxied server in response
// to the client request if the UDP protocol is used.
// http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses
// Default: 1
ProxyStreamResponses int
ProxyStreamTimeout string
//proxy protocol for tcp real ip
ProxyProtocol ProxyProtocol
}

View File

@ -243,7 +243,8 @@ func (o *OrService) getNgxServer(conf *v1.Config) (l7srv []*model.Server, l4srv
"tenant_id": vs.Namespace,
"service_id": vs.ServiceID,
},
UpstreamName: vs.PoolName,
UpstreamName: vs.PoolName,
ProxyStreamResponses: 1,
}
server.Listen = strings.Join(vs.Listening, " ")
l4srv = append(l4srv, server)

View File

@ -21,18 +21,24 @@ package cmd
import (
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/apcera/termtables"
"github.com/docker/docker/client"
"github.com/goodrain/rainbond/builder"
"github.com/goodrain/rainbond/builder/parser/code"
"github.com/goodrain/rainbond/builder/sources"
"github.com/goodrain/rainbond/grctl/clients"
"github.com/goodrain/rainbond/util"
"github.com/urfave/cli"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
//NewSourceBuildCmd cmd for source build test
@ -106,6 +112,194 @@ func NewSourceBuildCmd() cli.Command {
cmd.Run()
},
},
cli.Command{
Name: "maven-setting",
Usage: "maven setting config file manage",
Subcommands: []cli.Command{
cli.Command{
Name: "list",
Flags: []cli.Flag{
cli.StringFlag{
Name: "namespace,ns",
Usage: "rainbond default namespace",
Value: "rbd-system",
},
},
Usage: "list maven setting config file manage",
Action: func(ctx *cli.Context) {
Common(ctx)
namespace := ctx.String("namespace")
cms, err := clients.K8SClient.CoreV1().ConfigMaps(namespace).List(metav1.ListOptions{
LabelSelector: "configtype=mavensetting",
})
if err != nil {
showError(err.Error())
}
runtable := termtables.CreateTable()
runtable.AddHeaders("Name", "CreateTime", "UpdateTime", "Default")
for _, cm := range cms.Items {
var updateTime = "-"
if cm.Annotations != nil {
updateTime = cm.Annotations["updateTime"]
}
var def bool
if cm.Labels["default"] == "true" {
def = true
}
runtable.AddRow(cm.Name, cm.CreationTimestamp.Format(time.RFC3339), updateTime, def)
}
fmt.Println(runtable.Render())
},
},
cli.Command{
Name: "get",
Flags: []cli.Flag{
cli.StringFlag{
Name: "namespace,ns",
Usage: "rainbond default namespace",
Value: "rbd-system",
},
},
Usage: "get maven setting config file manage",
Action: func(ctx *cli.Context) {
Common(ctx)
name := ctx.Args().First()
if name == "" {
showError("Please specify the task pod name")
}
namespace := ctx.String("namespace")
cm, err := clients.K8SClient.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{})
if err != nil {
showError(err.Error())
}
fmt.Println(cm.Data["mavensetting"])
},
},
cli.Command{
Name: "update",
Usage: "update maven setting config file manage",
Flags: []cli.Flag{
cli.StringFlag{
Name: "file,f",
Usage: "define maven setting file",
Value: "./setting.xml",
},
cli.StringFlag{
Name: "namespace,ns",
Usage: "rainbond default namespace",
Value: "rbd-system",
},
},
Action: func(ctx *cli.Context) {
Common(ctx)
name := ctx.Args().First()
if name == "" {
showError("Please specify the task pod name")
}
namespace := ctx.String("namespace")
cm, err := clients.K8SClient.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{})
if err != nil {
showError(err.Error())
}
body, err := ioutil.ReadFile(ctx.String("f"))
if err != nil {
showError(err.Error())
}
if cm.Data == nil {
cm.Data = make(map[string]string)
}
if cm.Annotations == nil {
cm.Annotations = make(map[string]string)
}
cm.Data["mavensetting"] = string(body)
cm.Annotations["updateTime"] = time.Now().Format(time.RFC3339)
_, err = clients.K8SClient.CoreV1().ConfigMaps(namespace).Update(cm)
if err != nil {
showError(err.Error())
}
fmt.Println("Update Success")
},
},
cli.Command{
Name: "add",
Usage: "add maven setting config file manage",
Flags: []cli.Flag{
cli.StringFlag{
Name: "file,f",
Usage: "define maven setting file",
Value: "./setting.xml",
},
cli.BoolFlag{
Name: "default,d",
Usage: "default maven setting file",
},
cli.StringFlag{
Name: "namespace,ns",
Usage: "rainbond default namespace",
Value: "rbd-system",
},
},
Action: func(ctx *cli.Context) {
Common(ctx)
name := ctx.Args().First()
if name == "" {
showError("Please specify the task pod name")
}
namespace := ctx.String("namespace")
body, err := ioutil.ReadFile(ctx.String("f"))
if err != nil {
showError(err.Error())
}
config := &corev1.ConfigMap{}
config.Name = name
config.Namespace = namespace
config.Labels = map[string]string{
"creator": "Rainbond",
"configtype": "mavensetting",
"laguage": code.JavaMaven.String(),
}
if ctx.Bool("default") {
config.Labels["default"] = "true"
}
config.Annotations = map[string]string{
"updateTime": time.Now().Format(time.RFC3339),
}
config.Data = map[string]string{
"mavensetting": string(body),
}
_, err = clients.K8SClient.CoreV1().ConfigMaps(namespace).Create(config)
if err != nil {
showError(err.Error())
}
fmt.Println("Add Success")
},
},
cli.Command{
Name: "delete",
Usage: "delete maven setting config file manage",
Flags: []cli.Flag{
cli.StringFlag{
Name: "namespace,ns",
Usage: "rainbond default namespace",
Value: "rbd-system",
},
},
Action: func(ctx *cli.Context) {
Common(ctx)
name := ctx.Args().First()
if name == "" {
showError("Please specify the task pod name")
}
namespace := ctx.String("namespace")
err := clients.K8SClient.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{})
if err != nil {
showError(err.Error())
}
fmt.Println("Delete Success")
},
},
},
},
},
Name: "build",
Usage: "Commands related to building source code",

View File

@ -256,7 +256,7 @@ local _M = {
<div></div>
</div>
</div>
<p class="text2">Power By <a href="https://www.rainbond.com" target="_blank" rel="noopener noreferrer">Rainbond</a></p>
POWER
</div>
</body>
@ -266,7 +266,14 @@ local _M = {
function _M.call()
ngx.header["Content-type"] = "text/html"
ngx.print(_M.defaultHTML)
local html = ""
if (os.getenv("DISABLE_POWER") == "true")
then
html = string.gsub(_M.defaultHTML, "POWER", "", 1)
else
html = string.gsub(_M.defaultHTML, "POWER", [[<p class="text2" id="power">Power By <a href="https://www.rainbond.com" target="_blank" rel="noopener noreferrer">Rainbond</a></p>]],1)
end
ngx.print(html)
ngx.status = ngx.HTTP_OK
end

View File

@ -10,6 +10,9 @@ events {
worker_connections {{.Events.WorkerConnections}};
}
# env for lua
env DISABLE_POWER;
{{ $h := .HTTP }}
http {
lua_package_cpath "/run/nginx/lua/vendor/so/?.so;/usr/local/openresty/luajit/lib/?.so;;";

View File

@ -23,7 +23,7 @@ function localbuild() {
for item in "${build_items[@]}"
do
echo "build local ${item}"
go build -ldflags "-w -s -X github.com/goodrain/rainbond/cmd.version=${release_desc}" -o _output/${GOOS}/${VERSION}/rainbond-$item ./cmd/$item
go build -ldflags "-X github.com/goodrain/rainbond/cmd.version=${release_desc}" -o _output/${GOOS}/${VERSION}/rainbond-$item ./cmd/$item
done
else
echo "build local $1 ${VERSION}"
@ -32,11 +32,11 @@ function localbuild() {
if [ "$GOOS" = "windows" ];then
outputname="_output/${GOOS}/${VERSION}/rainbond-$1.exe"
fi
ldflags="-w -s -X github.com/goodrain/rainbond/cmd.version=${release_desc}"
ldflags="-X github.com/goodrain/rainbond/cmd.version=${release_desc}"
if [ "$STATIC" = "true" ];then
ldflags="${ldflags} -extldflags '-static'"
fi
CGO_ENABLED=1 go build -v -ldflags "${ldflags}" -o ${outputname} ./cmd/$1
go build -v -ldflags "${ldflags}" -o ${outputname} ./cmd/$1
fi
}

View File

@ -333,7 +333,7 @@ func NewRulesManager(config *option.Config) *AlertingRulesManager {
},
&RulesConfig{
Alert: "InsufficientClusteMemoryResources",
Expr: "sum(rbd_api_exporter_cluster_memory_total) - sum(namespace_resource_memory_request) < 2048",
Expr: "max(rbd_api_exporter_cluster_memory_total) - max(sum(namespace_resource_memory_request) by (instance)) < 2048",
For: "2m",
Labels: commonLables,
Annotations: map[string]string{
@ -343,7 +343,7 @@ func NewRulesManager(config *option.Config) *AlertingRulesManager {
},
&RulesConfig{
Alert: "InsufficientClusteCPUResources",
Expr: "sum(rbd_api_exporter_cluster_cpu_total*1000) - sum(namespace_resource_cpu_request) < 500",
Expr: "max(rbd_api_exporter_cluster_cpu_total) - max(sum(namespace_resource_cpu_request) by (instance)) < 500",
For: "2m",
Labels: commonLables,
Annotations: map[string]string{

View File

@ -445,8 +445,9 @@ func listDirNonSymlink(dir string) []os.FileInfo {
//RemoveSpaces 去除空格项
func RemoveSpaces(sources []string) (re []string) {
for _, s := range sources {
if s != " " && s != "" {
if s != " " && s != "" && s != "\t" && s != "\n" && s != "\r" {
re = append(re, s)
fmt.Println(re)
}
}
return

View File

@ -35,7 +35,8 @@ var ErrNoUpdateForLongTime = fmt.Errorf("not updated for a long time")
func WaitPrefixEvents(c *clientv3.Client, prefix string, rev int64, evs []mvccpb.Event_EventType) (*clientv3.Event, error) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
wc := c.Watch(ctx, prefix, clientv3.WithPrefix(), clientv3.WithRev(rev))
logrus.Debug("start watch message from etcd queue")
wc := clientv3.NewWatcher(c).Watch(ctx, prefix, clientv3.WithPrefix(), clientv3.WithRev(rev))
if wc == nil {
return nil, ErrNoWatcher
}
@ -55,6 +56,13 @@ func waitEvents(wc clientv3.WatchChan, evs []mvccpb.Event_EventType) *clientv3.E
for {
select {
case wresp := <-wc:
if wresp.Err() != nil {
logrus.Errorf("watch event failure %s", wresp.Err().Error())
return nil
}
if len(wresp.Events) == 0 {
return nil
}
for _, ev := range wresp.Events {
if ev.Type == evs[i] {
i++

View File

@ -173,30 +173,40 @@ func (wc *watchChan) startWatching(watchClosedCh chan struct{}) {
ctx, cancel := context.WithCancel(wc.ctx)
defer cancel()
wch := wc.watcher.client.Watch(ctx, wc.key, opts...)
timer := time.NewTimer(time.Second * 20)
defer timer.Stop()
lool:
for {
select {
case wres := <-wch:
if wres.Err() != nil {
err := wres.Err()
// If there is an error on server (e.g. compaction), the channel will return it before closed.
logrus.Errorf("watch chan error: %v", err)
wc.sendError(err)
return
err := func() error {
timer := time.NewTimer(time.Second * 20)
defer timer.Stop()
for {
select {
case wres := <-wch:
if err := wres.Err(); err != nil {
// If there is an error on server (e.g. compaction), the channel will return it before closed.
logrus.Errorf("watch chan error: %v", err)
wc.sendError(err)
close(watchClosedCh)
return err
}
logrus.Debugf("watch event %+v", wres)
// If you return a structure with no events
// It is considered that this watch is no longer effective
// Return nil redo watch
if len(wres.Events) == 0 {
return nil
}
for _, e := range wres.Events {
wc.sendEvent(parseEvent(e))
}
timer.Reset(time.Second * 20)
case <-timer.C:
return nil
}
for _, e := range wres.Events {
wc.sendEvent(parseEvent(e))
}
timer.Reset(time.Second * 20)
case <-timer.C:
break lool
}
}()
if err == nil {
wc.initialRev = 0
logrus.Debugf("watcher sync, because of not updated for a long time")
go wc.startWatching(watchClosedCh)
}
wc.initialRev = 0
logrus.Debugf("watcher sync, because of not updated for a long time")
go wc.startWatching(watchClosedCh)
}
// processEvent processes events from etcd watcher and sends results to resultChan.

View File

@ -468,6 +468,8 @@ func (a *AppServiceBuild) createInnerService(port *model.TenantServicesPort) *co
} else {
servicePort.Protocol = "TCP"
}
servicePort.Name = fmt.Sprintf("%s-%d",
strings.ToLower(string(servicePort.Protocol)), port.ContainerPort)
servicePort.TargetPort = intstr.FromInt(port.ContainerPort)
servicePort.Port = int32(port.MappingPort)
if servicePort.Port == 0 {
@ -503,6 +505,8 @@ func (a *AppServiceBuild) createOuterService(port *model.TenantServicesPort) *co
var servicePort corev1.ServicePort
servicePort.Protocol = conversionPortProtocol(port.Protocol)
servicePort.TargetPort = intstr.FromInt(port.ContainerPort)
servicePort.Name = fmt.Sprintf("%s-%d",
strings.ToLower(string(servicePort.Protocol)), port.ContainerPort)
servicePort.Port = int32(port.ContainerPort)
var portType corev1.ServiceType
if os.Getenv("CUR_NET") == "midonet" {
@ -538,7 +542,8 @@ func (a *AppServiceBuild) createStatefulService(ports []*model.TenantServicesPor
servicePort.Protocol = "TCP"
servicePort.TargetPort = intstr.FromInt(p.ContainerPort)
servicePort.Port = int32(p.MappingPort)
servicePort.Name = fmt.Sprintf("%d-port", p.ID)
servicePort.Name = fmt.Sprintf("%s-%d",
strings.ToLower(string(servicePort.Protocol)), p.ContainerPort)
if servicePort.Port == 0 {
servicePort.Port = int32(p.ContainerPort)
}

View File

@ -78,7 +78,8 @@ func conversionServicePlugin(as *typesv1.AppService, dbmanager db.Manager) ([]v1
}
versionInfo, err := dbmanager.TenantPluginBuildVersionDao().GetLastBuildVersionByVersionID(pluginR.PluginID, pluginR.VersionID)
if err != nil {
return nil, nil, nil, fmt.Errorf("do not found available plugin versions")
logrus.Errorf("do not found available plugin versions %s", pluginR.PluginID)
continue
}
podTmpl := as.GetPodTemplate()
if podTmpl == nil {