diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4136c0e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +# Build the manager binary +FROM golang:1.21 AS backend-builder +COPY backend/ /build/backend +COPY build.sh /build/ +WORKDIR /build +RUN sh -x ./build.sh --backend && ls /build/bin/ && sleep 10 + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +#FROM gcr.io/distroless/static:nonroot +FROM node:21 AS frontend-builder +COPY frontend/ /build/frontend +COPY build.sh /build/ +WORKDIR /build/frontend +RUN npm install +RUN npm run build + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +#FROM gcr.io/distroless/static:nonroot +FROM debian:latest +WORKDIR /src +COPY --from=backend-builder /build/bin/cfs-gui . +COPY --from=backend-builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=frontend-builder /build/frontend/dist ./dist/ +EXPOSE 6007 +ENTRYPOINT ["/src/cfs-gui","-c","/src/config/"] \ No newline at end of file diff --git a/Makefile b/Makefile index de4a102..4f6401b 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,24 @@ phony := build phony += clean +phony += backend +phony += frontend -build: build.sh - sh build.sh +DOCKER_IMAGE="cubefs-dashboard" +build: frontend backend + +docker-build: + docker build . -t "${DOCKER_IMAGE}" + +docker-push: + docker push "${DOCKER_IMAGE}" + +frontend: + sh build.sh --frontend + +backend: + sh build.sh --backend clean: bin rm -rf bin diff --git a/README.md b/README.md index 8da1811..9201e17 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,35 @@ total 26256 -rw-r--r-- 1 root root 1009 Jul 27 17:26 config.yml drwxr-xr-x 6 root root 4096 Jul 27 17:27 dist ``` + +# Configuration +## /src/config/config.yaml + +``` +server: + port: 6007 + mode: dev + static_resource: + enable: true + relative_path: /portal + root_path: ./dist +prefix: + api: /api/cubefs +``` +## /src/config/mysql.yaml +``` +mysql: + host: + port: + slaveHost: + slavePort: + database: + user: + password: + maxIdleConn: 20 + MaxOpenConn: 300 +``` + # Preview ## Cluster overview diff --git a/backend/conf/config.yml b/backend/conf/config.yml deleted file mode 100644 index c9d77f5..0000000 --- a/backend/conf/config.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2023 The CubeFS Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -server: - port: 6007 - mode: dev - static_resource: - enable: true - relative_path: /portal - root_path: ./dist -prefix: - api: /api/cubefs -mysql: - host: - port: - slaveHost: - slavePort: - user: - password: - database: - maxIdleConn: 20 - MaxOpenConn: 300 diff --git a/backend/config/config.go b/backend/config/config.go index 7f036ac..94357c8 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -16,25 +16,35 @@ package config import ( "github.com/spf13/viper" - - "github.com/cubefs/cubefs-dashboard/backend/helper/crypt" ) var Conf *Config func Init(configPath string) (err error) { - viper.SetConfigFile(configPath) + serverConfig := viper.New() + mysqlConfig := viper.New() + serverConfig.SetConfigFile(configPath + "config.yaml") + mysqlConfig.SetConfigFile(configPath + "mysql.yaml") + + err = serverConfig.ReadInConfig() + if err != nil { + return err + } + + err = mysqlConfig.ReadInConfig() + if err != nil { + return err + } - err = viper.ReadInConfig() + err = serverConfig.Unmarshal(&Conf) if err != nil { return err } - err = viper.Unmarshal(&Conf) + err = mysqlConfig.Unmarshal(&Conf) if err != nil { return err } - err = Conf.AesDecode() return } @@ -72,12 +82,3 @@ type MysqlConfig struct { MaxIdleConn int `mapstructure:"maxIdleConn"` MaxOpenConn int `mapstructure:"maxOpenConn"` } - -func (c *Config) AesDecode() error { - mysqlPass, err := crypt.Decrypt(c.Mysql.Password) - if err != nil { - return err - } - c.Mysql.Password = mysqlPass - return nil -} diff --git a/backend/main.go b/backend/main.go index f0a9fad..1f01f4f 100644 --- a/backend/main.go +++ b/backend/main.go @@ -16,32 +16,17 @@ package main import ( "flag" - "fmt" - "os" - "github.com/cubefs/cubefs-dashboard/backend/config" "github.com/cubefs/cubefs-dashboard/backend/helper" "github.com/cubefs/cubefs-dashboard/backend/model/migrate" "github.com/cubefs/cubefs-dashboard/backend/model/mysql" "github.com/cubefs/cubefs-dashboard/backend/router" - "github.com/cubefs/cubefs-dashboard/backend/helper/crypt" ) -var confPath = flag.String("c", "", "please input your conf file path") -var enc = flag.String("e", "", "please input your encrypted string") +var confPath = flag.String("c", "", "please input your configuration directory") func main() { flag.Parse() - if *enc != "" { - str, err := crypt.Encrypt([]byte(*enc)) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - fmt.Println(str) - os.Exit(0) - } - helper.Must(config.Init(*confPath)) helper.Must(mysql.Init()) helper.Must(migrate.Init()) diff --git a/backend/model/op_type.go b/backend/model/op_type.go index a8bcb2d..e649a19 100644 --- a/backend/model/op_type.go +++ b/backend/model/op_type.go @@ -79,7 +79,7 @@ func (o *OpType) Find(record *bool) ([]OpType, error) { return optypes, err } -func (o *OpType) FindByUniqKey(uri, method string) (*OpType, error) { +func (o *OpType) FindByUniqKey(uri, method string) (*OpType, error) { if uri == "" || method == "" { return nil, errors.New("uri and method are required") } diff --git a/build.sh b/build.sh index b166751..f191e8c 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh BIN_PATH=bin FRONT_PATH=frontend BACK_PATH=backend @@ -9,38 +9,43 @@ BranchName=`git rev-parse --abbrev-ref HEAD 2>/dev/null` CommitID=`git rev-parse HEAD 2>/dev/null` BuildTime=`date +%Y-%m-%d\ %H:%M` -#SrcPath=${RootPath}/console -TargetFile=${1:-$RootPath/bin/cfs-gui} -TargetDic=$(dirname $TargetFile) -mkdir -p $TargetDic +if [ "${1}" = "--backend" ]; +then + #SrcPath=${RootPath}/console + TargetFile=${2:-$RootPath/bin/cfs-gui} + TargetDic=$(dirname $TargetFile) + mkdir -p $TargetDic -LDFlags="-X github.com/cubefs/cubefs/proto.Version=${Version} \ - -X github.com/cubefs/cubefs/proto.CommitID=${CommitID} \ - -X github.com/cubefs/cubefs/proto.BranchName=${BranchName} \ - -X 'github.com/cubefs/cubefs/proto.BuildTime=${BuildTime}' " -cd $BACK_PATH -go build \ - -ldflags "${LDFlags}" \ - -o $TargetFile \ - *.go -if [[ $? -ne 0 ]];then - echo "go build error" - exit 13 + LDFlags="-X github.com/cubefs/cubefs/proto.Version=${Version} \ + -X github.com/cubefs/cubefs/proto.CommitID=${CommitID} \ + -X github.com/cubefs/cubefs/proto.BranchName=${BranchName} \ + -X 'github.com/cubefs/cubefs/proto.BuildTime=${BuildTime}' " + cd $BACK_PATH + go build \ + -ldflags "${LDFlags}" \ + -o $TargetFile \ + *.go + if [[ $? -ne 0 ]]; + then + echo "go build error" + exit 13 + fi fi -cd - -cp -rf ./$BACK_PATH/conf/config.yml $TargetDic/config.yml -#compile frontend -cd $FRONT_PATH -npm install -if [[ $? -ne 0 ]];then - echo "npm install error" - exit 11 -fi -npm run build -if [[ $? -ne 0 ]];then - echo "npm run build error" - exit 12 -fi -cd - -cp -rf ./$FRONT_PATH/dist $TargetDic/dist \ No newline at end of file +if [ "${1}" = "--frontend" ]; +then + #compile frontend + cd $FRONT_PATH + npm install + if [[ $? -ne 0 ]];then + echo "npm install error" + exit 11 + fi + npm run build + if [[ $? -ne 0 ]];then + echo "npm run build error" + exit 12 + fi + cd - + cp -rf ./$FRONT_PATH/dist $TargetDic/dist +fi \ No newline at end of file diff --git a/deploy/chart/Chart.yaml b/deploy/chart/Chart.yaml new file mode 100755 index 0000000..e6823e5 --- /dev/null +++ b/deploy/chart/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +name: cubefs-dashboard +description: CubeFS Dashboard Helm Chart +version: 0.0.1 \ No newline at end of file diff --git a/deploy/chart/templates/configmap.yaml b/deploy/chart/templates/configmap.yaml new file mode 100644 index 0000000..9b23884 --- /dev/null +++ b/deploy/chart/templates/configmap.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cubefs-dashboard-config +data: + config.yaml: | + server: + port: 6007 + mode: dev + static_resource: + enable: true + relative_path: /portal + root_path: ./dist + prefix: + api: /api/cubefs diff --git a/deploy/chart/templates/deployment.yaml b/deploy/chart/templates/deployment.yaml new file mode 100644 index 0000000..7008d7e --- /dev/null +++ b/deploy/chart/templates/deployment.yaml @@ -0,0 +1,58 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: cubefs-dashboard + name: cubefs-dashboard +spec: + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: cubefs-dashboard + template: + metadata: + labels: + app: cubefs-dashboard + spec: + imagePullSecrets: + - name: {{.Values.image.pullSecret}} + containers: + - image: "{{.Values.image.registry}}/{{.Values.image.repository}}:{{.Values.image.tag}}" + imagePullPolicy: Always + name: dashboard + resources: {{- toYaml .Values.resources | indent 10 }} + volumeMounts: + - mountPath: /src/config + name: dashboard-config + - env: + - name: MARIADB_PASSWORD + value: {{ .Values.mariadb.auth.password}} + - name: MARIADB_DATABASE + value: {{ .Values.mariadb.auth.database}} + - name: MARIADB_USER + value: {{ .Values.mariadb.auth.username}} + - name: MARIADB_RANDOM_ROOT_PASSWORD + value: "True" + image: {{.Values.mariadb.image}} + imagePullPolicy: IfNotPresent + name: mariadb + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /var/lib/mysql + name: db + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + volumes: + - name: db + persistentVolumeClaim: + claimName: cubefs-dashboard + - name: dashboard-config + projected: + sources: + - secret: + name: cubefs-dashboard-mysql + - configMap: + name: cubefs-dashboard-config \ No newline at end of file diff --git a/deploy/chart/templates/ingress.yaml b/deploy/chart/templates/ingress.yaml new file mode 100644 index 0000000..837d3bb --- /dev/null +++ b/deploy/chart/templates/ingress.yaml @@ -0,0 +1,25 @@ +{{if .Values.ingress.enable}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cubefs-dashboard +spec: + ingressClassName: {{.Values.ingress.ingressClassName}} + rules: + - host: {{.Values.ingress.hostname}} + http: + paths: + - backend: + service: + name: cubefs-dashboard + port: + number: {{.Values.service.port}} + path: / + pathType: Prefix + {{- if .Values.ingress.tls }} + tls: + - hosts: + - {{.Values.ingress.hostname}} + secretName: {{.Values.ingress.secretName}} + {{- end}} +{{end}} diff --git a/deploy/chart/templates/pvc.yaml b/deploy/chart/templates/pvc.yaml new file mode 100644 index 0000000..329f0f0 --- /dev/null +++ b/deploy/chart/templates/pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: cubefs-dashboard +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/deploy/chart/templates/secret.yaml b/deploy/chart/templates/secret.yaml new file mode 100644 index 0000000..847a6d6 --- /dev/null +++ b/deploy/chart/templates/secret.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cubefs-dashboard-mysql +type: Opaque +stringData: + mysql.yaml: | + mysql: + host: localhost + port: 3306 + database: {{.Values.mariadb.auth.database}} + user: {{.Values.mariadb.auth.username}} + password: {{.Values.mariadb.auth.password}} + maxIdleConn: 20 + MaxOpenConn: 300 diff --git a/deploy/chart/templates/service.yaml b/deploy/chart/templates/service.yaml new file mode 100644 index 0000000..cb45cfe --- /dev/null +++ b/deploy/chart/templates/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: cubefs-dashboard + name: cubefs-dashboard +spec: + ports: + - port: {{.Values.service.port}} + protocol: TCP + targetPort: {{.Values.service.port}} + selector: + app: cubefs-dashboard + type: ClusterIP \ No newline at end of file diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml new file mode 100644 index 0000000..c6bcb50 --- /dev/null +++ b/deploy/chart/values.yaml @@ -0,0 +1,27 @@ +image: + tag: latest + registry: docker.io + repository: cubefs/dashboard + pullSecret: +service: + port: 6007 +spec: + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 1 + memory: 2Gi +mariadb: + image: mariadb:11.3.2 + auth: + username: cfs + database: cfs + password: password +ingress: + enable: true + ingressClassName: haproxy + hostname: cubefs-dashboard.local + tls: false + secretName: wildcard-tls