Browse Source

Merge pull request #288 from dtm-labs/alpha

dashboard rename to admin
topic
yedf2 4 years ago
committed by GitHub
parent
commit
230de1254e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      .github/workflows/release.yml
  2. 2
      .gitignore
  3. 1
      admin/.env
  4. 0
      admin/.eslintrc.js
  5. 0
      admin/.gitignore
  6. 0
      admin/README.md
  7. 1
      admin/dist/placeholder
  8. 0
      admin/index.html
  9. 0
      admin/package.json
  10. 0
      admin/postcss.config.js
  11. 0
      admin/public/favicon.ico
  12. 0
      admin/src/App.vue
  13. 22
      admin/src/api/api_dtm.ts
  14. 0
      admin/src/assets/css/index.css
  15. 0
      admin/src/components.d.ts
  16. 0
      admin/src/components/SvgIcon/index.vue
  17. 0
      admin/src/icons/readme.md
  18. 0
      admin/src/icons/svg/logo.svg
  19. 19
      admin/src/layout/aside.vue
  20. 0
      admin/src/layout/components/content.vue
  21. 6
      admin/src/layout/components/header.vue
  22. 0
      admin/src/layout/components/sidebar.vue
  23. 0
      admin/src/layout/index.vue
  24. 0
      admin/src/main.ts
  25. 0
      admin/src/permission.ts
  26. 0
      admin/src/router/asyncRouter.ts
  27. 46
      admin/src/router/index.ts
  28. 0
      admin/src/store/index.ts
  29. 9
      admin/src/store/modules/layout.ts
  30. 10
      admin/src/type/index.d.ts
  31. 0
      admin/src/type/shim.vue.d.ts
  32. 11
      admin/src/type/store/layout.ts
  33. 1
      admin/src/utils/request.ts
  34. 0
      admin/src/utils/util.ts
  35. 0
      admin/src/views/Dashboard/GlobalTransactions/AllTransactions.vue
  36. 0
      admin/src/views/Dashboard/GlobalTransactions/UnfinishedTransactions.vue
  37. 0
      admin/src/views/Dashboard/Nodes/LivingNodes.vue
  38. 0
      admin/tailwind.config.js
  39. 0
      admin/tsconfig.json
  40. 2
      admin/vite.config.ts
  41. 0
      admin/yarn.lock
  42. 3
      dashboard/.env.development
  43. 15
      dashboard/src/api/api_dtm.ts
  44. 3
      dtmsvr/api.go
  45. 3
      dtmsvr/api_http.go
  46. 5
      dtmsvr/config/config.go
  47. 2
      dtmsvr/config/config_utils.go
  48. 21
      dtmsvr/entry/main.go
  49. 8
      helper/Dockerfile-release
  50. 54
      main.go
  51. 6
      test/api_test.go

19
.github/workflows/release.yml

@ -10,7 +10,24 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@v2 uses: actions/checkout@v3
uses: actions/setup-node@v3
with:
node-version: 14
env:
host: 'ubuntu@en.dtm.pub'
dest: '/data/dtm-admin/'
run: |
cd admin
npm install -g yarn
yarn
VITE_ADMIN_VERSION=${GITHUB_REF#refs/*/} yarn build
echo "${{secrets.DEPLOY_KEY}}" > deploy_key
chmod 600 ./deploy_key
tar -cvzf dist.tar.gz dist
scp -i ../../deploy_key -o StrictHostKeyChecking=no dist.tar.gz ${{env.host}}:${{env.dest}}
ssh -i ../../deploy_key -o StrictHostKeyChecking=no ${{env.host}} 'cd ${{env.dest}} && tar -zvxf dist.tar.gz'
cd ..
- name: Validates GO releaser config - name: Validates GO releaser config
uses: docker://goreleaser/goreleaser:v1.7.0 uses: docker://goreleaser/goreleaser:v1.7.0

2
.gitignore

@ -1,7 +1,7 @@
conf.yml conf.yml
*.out *.out
*.log *.log
dist # dist
.idea/** .idea/**
.vscode .vscode
default.etcd default.etcd

1
admin/.env

@ -0,0 +1 @@
VITE_ADMIN_VERSION="v0.0.0-dev"

0
dashboard/.eslintrc.js → admin/.eslintrc.js

0
dashboard/.gitignore → admin/.gitignore

0
dashboard/README.md → admin/README.md

1
admin/dist/placeholder

@ -0,0 +1 @@
placeholder

0
dashboard/index.html → admin/index.html

0
dashboard/package.json → admin/package.json

0
dashboard/postcss.config.js → admin/postcss.config.js

0
dashboard/public/favicon.ico → admin/public/favicon.ico

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

0
dashboard/src/App.vue → admin/src/App.vue

22
admin/src/api/api_dtm.ts

@ -0,0 +1,22 @@
import { AxiosResponse } from 'axios'
import request from '/@/utils/request'
export interface IListAllTransactionsReq {
limit: number
position?: number
}
export function listAllTransactions<T>(payload: IListAllTransactionsReq): Promise<AxiosResponse<T>> {
return request({
url: '/api/dtmsvr/all',
method: 'get',
params: payload
})
}
export function getDtmVersion(): Promise<AxiosResponse<any>> {
return request({
url: '/api/dtmsvr/version',
method: 'get',
})
}

0
dashboard/src/assets/css/index.css → admin/src/assets/css/index.css

0
dashboard/src/components.d.ts → admin/src/components.d.ts

0
dashboard/src/components/SvgIcon/index.vue → admin/src/components/SvgIcon/index.vue

0
dashboard/src/icons/readme.md → admin/src/icons/readme.md

0
dashboard/src/icons/svg/logo.svg → admin/src/icons/svg/logo.svg

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

19
dashboard/src/layout/aside.vue → admin/src/layout/aside.vue

@ -4,6 +4,7 @@
<Sidebar /> <Sidebar />
</a-layout-sider> </a-layout-sider>
<a-layout style="padding: 0 24px 24px"> <a-layout style="padding: 0 24px 24px">
<div v-if="layout.dtmVersion && layout.dtmVersion != dashVer" style="color:#f00"> !!! admin version: {{dashVer}} != dtm version: {{layout.dtmVersion}}. </div>
<a-breadcrumb style="margin: 16px 0"> <a-breadcrumb style="margin: 16px 0">
<a-breadcrumb-item>{{ mainNav }}</a-breadcrumb-item> <a-breadcrumb-item>{{ mainNav }}</a-breadcrumb-item>
<a-breadcrumb-item>{{ subNav }}</a-breadcrumb-item> <a-breadcrumb-item>{{ subNav }}</a-breadcrumb-item>
@ -26,18 +27,21 @@ import { useLayoutStore } from '../store/modules/layout'
import { IMenubarList } from '../type/store/layout' import { IMenubarList } from '../type/store/layout'
import { findCurrentMenubar } from '../utils/util' import { findCurrentMenubar } from '../utils/util'
import { computed, onMounted, ref } from 'vue' import { computed, onMounted, ref } from 'vue'
import { getDtmVersion } from '../api/api_dtm'
const dashVer = import.meta.env.VITE_ADMIN_VERSION
const route = useRoute() const route = useRoute()
const { getMenubar } = useLayoutStore() const layout = useLayoutStore()
const mainNav = computed(() => { const mainNav = computed(() => {
const currentMenubar = findCurrentMenubar(getMenubar.menuList, true) const currentMenubar = findCurrentMenubar(layout.getMenubar.menuList, true)
return currentMenubar?.meta.title return currentMenubar?.meta.title
}) })
const subNav = computed(() => { const subNav = computed(() => {
let subNav = '' let subNav = ''
const currentMenubar = findCurrentMenubar(getMenubar.menuList, true) const currentMenubar = findCurrentMenubar(layout.getMenubar.menuList, true)
currentMenubar.children?.forEach(v => { currentMenubar.children?.forEach(v => {
if (route.path.indexOf(v.path) !== -1) { if (route.path.indexOf(v.path) !== -1) {
subNav = v.meta.title subNav = v.meta.title
@ -49,17 +53,22 @@ const subNav = computed(() => {
const page = computed(() => { const page = computed(() => {
let page = '' let page = ''
const currentMenubar = findCurrentMenubar(getMenubar.menuList, true) const currentMenubar = findCurrentMenubar(layout.getMenubar.menuList, true)
currentMenubar.children?.forEach(v => { currentMenubar.children?.forEach(v => {
v.children?.forEach(vv => { v.children?.forEach(vv => {
if (route.path == vv.path) { if (route.path == vv.path) {
page = vv.meta.title page = vv.meta.title
} }
}) })
}) })
return page return page
}) })
onMounted(() => {
layout.loadDtmVersion()
})
</script> </script>
<style lang="postcss" scoped> <style lang="postcss" scoped>

0
dashboard/src/layout/components/content.vue → admin/src/layout/components/content.vue

6
dashboard/src/layout/components/header.vue → admin/src/layout/components/header.vue

@ -3,7 +3,7 @@
<a-layout-header class="header flex"> <a-layout-header class="header flex">
<div class="flex items-center logo h-16"> <div class="flex items-center logo h-16">
<svg-icon style="width: 36px; height: 36px; margin-right: 84px;" icon-class="svg-logo" /> <svg-icon style="width: 36px; height: 36px; margin-right: 84px;" icon-class="svg-logo" />
<span class="text-gray-400 text-lg">DTM dashbaord {{ version }}</span> <span class="text-gray-400 text-lg">DTM admin {{ version }}</span>
</div> </div>
<a-menu <a-menu
v-model:selectedKeys="activeMenu" v-model:selectedKeys="activeMenu"
@ -25,8 +25,8 @@ import { useLayoutStore } from '/@/store/modules/layout'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const { getMenubar, getCurrentVersion } = useLayoutStore() const { getMenubar, getCurrentVersion } = useLayoutStore()
const firstRedirectPath = '/dashboard' const firstRedirectPath = '/admin'
const version = import.meta.env.VITE_DASHBOARD_VERSION const version = import.meta.env.VITE_ADMIN_VERSION
const activeMenu = ref([route.meta.activeMenu !== firstRedirectPath ? route.meta.activeMenu : '/']) const activeMenu = ref([route.meta.activeMenu !== firstRedirectPath ? route.meta.activeMenu : '/'])

0
dashboard/src/layout/components/sidebar.vue → admin/src/layout/components/sidebar.vue

0
dashboard/src/layout/index.vue → admin/src/layout/index.vue

0
dashboard/src/main.ts → admin/src/main.ts

0
dashboard/src/permission.ts → admin/src/permission.ts

0
dashboard/src/router/asyncRouter.ts → admin/src/router/asyncRouter.ts

46
dashboard/src/router/index.ts → admin/src/router/index.ts

@ -8,43 +8,43 @@ const Components: IObject<() => Promise<typeof import('*.vue')>> = Object.assign
}) })
export const allowRouter: Array<IMenubarList> = [ export const allowRouter: Array<IMenubarList> = [
{ {
name: 'Dashboard', name: 'Admin',
path: '/', path: '/',
redirect: '/dashboard/nodes/living', redirect: '/admin/global-transactions/all',
component: Components['LayoutHeader'], component: Components['LayoutHeader'],
meta: { title: 'Dashboard', activeMenu: '/dashboard' }, meta: { title: 'Admin', activeMenu: '/admin' },
children: [ children: [
{ {
name: 'Nodes', name: 'Nodes',
path: '/dashboard/nodes', path: '/admin/nodes',
component: Components['LayoutMain'], component: Components['LayoutMain'],
meta: { title: 'Nodes' }, meta: { title: 'Nodes' },
children: [ children: [
{ {
name: 'LivingNodes', name: 'LivingNodes',
path: '/dashboard/nodes/living', path: '/admin/nodes/living',
component: Components['LivingNodes'], component: Components['LivingNodes'],
meta: { title: 'Living Nodes' }, meta: { title: 'Living Nodes' },
} }
] ]
}, { }, {
name: 'GlobalTransactions', name: 'GlobalTransactions',
path: '/dashboard/global-transactions', path: '/admin/global-transactions',
component: Components['LayoutMain'], component: Components['LayoutMain'],
meta: { title: 'Global Transactions' }, meta: { title: 'Global Transactions' },
children: [ children: [
{ {
name: 'AllTransactions', name: 'AllTransactions',
path: '/dashboard/global-transactions/all', path: '/admin/global-transactions/all',
component: Components['AllTransactions'], component: Components['AllTransactions'],
meta: { title: 'All Transactions' }, meta: { title: 'All Transactions' },
}, { }, {
name: 'UnfinishedTransactions', name: 'UnfinishedTransactions',
path: '/dashboard/global-transactions/unfinished', path: '/admin/global-transactions/unfinished',
component: Components['UnfinishedTransactions'], component: Components['UnfinishedTransactions'],
meta: { title: 'Unfinished Transactions' }, meta: { title: 'Unfinished Transactions' },
} }
] ]
} }
] ]

0
dashboard/src/store/index.ts → admin/src/store/index.ts

9
dashboard/src/store/modules/layout.ts → admin/src/store/modules/layout.ts

@ -1,16 +1,18 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { allowRouter } from '/@/router'; import { allowRouter } from '/@/router';
import { ILayout, IMenubar, IMenubarList, IStatus } from '/@/type/store/layout'; import { ILayout, IMenubar, IMenubarList, IStatus } from '/@/type/store/layout';
import { getDtmVersion } from '/@/api/api_dtm';
export const useLayoutStore = defineStore({ export const useLayoutStore = defineStore({
id: 'layout', id: 'layout',
state: ():ILayout => ({ state: (): ILayout => ({
menubar: { menubar: {
menuList: [] menuList: []
}, },
status: { status: {
isLoading: false isLoading: false
}, },
dtmVersion: "",
}), }),
getters: { getters: {
getMenubar(): IMenubar { getMenubar(): IMenubar {
@ -27,5 +29,10 @@ export const useLayoutStore = defineStore({
concatAllowRoutes(): void { concatAllowRoutes(): void {
allowRouter.reverse().forEach(v => this.menubar.menuList.unshift(v)) allowRouter.reverse().forEach(v => this.menubar.menuList.unshift(v))
}, },
async loadDtmVersion(): Promise<void> {
const { data: { version } } = await getDtmVersion()
this.dtmVersion = version
console.log("dtm version: ", this.dtmVersion)
}
} }
}) })

10
dashboard/src/type/index.d.ts → admin/src/type/index.d.ts

@ -1,4 +1,4 @@
export {} export { }
declare global { declare global {
interface IObject<T> { interface IObject<T> {
[index: string]: T [index: string]: T
@ -7,11 +7,11 @@ declare global {
VITE_APP_TITLE: string VITE_APP_TITLE: string
VITE_PORT: number VITE_PORT: number
VITE_PROXY: string VITE_PROXY: string
VITE_DASHBOARD_VERSION: string VITE_ADMIN_VERSION: string
} }
interface ITable<T = any> { interface ITable<T = any> {
data: Array<T> data: Array<T>
next_position: number, next_position: number,
size: number size: number
} }
} }

0
dashboard/src/type/shim.vue.d.ts → admin/src/type/shim.vue.d.ts

11
dashboard/src/type/store/layout.ts → admin/src/type/store/layout.ts

@ -1,14 +1,15 @@
export interface IMenubar { export interface IMenubar {
menuList: Array<IMenubarList> menuList: Array<IMenubarList>
} }
export interface ILayout { export interface ILayout {
menubar: IMenubar menubar: IMenubar
status: IStatus status: IStatus
dtmVersion: string
} }
export interface IStatus { export interface IStatus {
isLoading: boolean isLoading: boolean
} }
export interface IMenubarList { export interface IMenubarList {
@ -16,7 +17,7 @@ export interface IMenubarList {
id?: number | string id?: number | string
name: string name: string
path: string path: string
redirect?: string redirect?: string
meta: { meta: {
icon?: string icon?: string
title: string title: string

1
dashboard/src/utils/request.ts → admin/src/utils/request.ts

@ -1,7 +1,6 @@
import axios from 'axios' import axios from 'axios'
const request = axios.create({ const request = axios.create({
baseURL: import.meta.env.VITE_APP_API_BASE_URL as string | undefined,
timeout: 60000 timeout: 60000
}) })

0
dashboard/src/utils/util.ts → admin/src/utils/util.ts

0
dashboard/src/views/Dashboard/GlobalTransactions/AllTransactions.vue → admin/src/views/Dashboard/GlobalTransactions/AllTransactions.vue

0
dashboard/src/views/Dashboard/GlobalTransactions/UnfinishedTransactions.vue → admin/src/views/Dashboard/GlobalTransactions/UnfinishedTransactions.vue

0
dashboard/src/views/Dashboard/Nodes/LivingNodes.vue → admin/src/views/Dashboard/Nodes/LivingNodes.vue

0
dashboard/tailwind.config.js → admin/tailwind.config.js

0
dashboard/tsconfig.json → admin/tsconfig.json

2
dashboard/vite.config.ts → admin/vite.config.ts

@ -29,7 +29,7 @@ export default ({ }: ConfigEnv): UserConfigExport => {
], ],
server: { server: {
port: 5000, port: 5000,
base: 'dashboard', base: 'admin',
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:36789', target: 'http://localhost:36789',

0
dashboard/yarn.lock → admin/yarn.lock

3
dashboard/.env.development

@ -1,3 +0,0 @@
VITE_APP_API_BASE_URL="/api"
VITE_PROXY=[["/api", "http://localhost:36789"]]
VITE_DASHBOARD_VERSION="v0.0.0-dev"

15
dashboard/src/api/api_dtm.ts

@ -1,15 +0,0 @@
import { AxiosResponse } from 'axios'
import request from '/@/utils/request'
export interface IListAllTransactionsReq {
limit: number
position?: number
}
export function listAllTransactions<T>(payload:IListAllTransactionsReq):Promise<AxiosResponse<T>> {
return request({
url: '/dtmsvr/all',
method: 'get',
params: payload
})
}

3
dtmsvr/api.go

@ -15,6 +15,9 @@ import (
"github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/dtm-labs/dtm/dtmsvr/storage"
) )
// Version store the passin version for dtm server
var Version = ""
func svcSubmit(t *TransGlobal) interface{} { func svcSubmit(t *TransGlobal) interface{} {
t.Status = dtmcli.StatusSubmitted t.Status = dtmcli.StatusSubmitted
branches, err := t.saveNew() branches, err := t.saveNew()

3
dtmsvr/api_http.go

@ -19,6 +19,9 @@ import (
) )
func addRoute(engine *gin.Engine) { func addRoute(engine *gin.Engine) {
engine.GET("/api/dtmsvr/version", dtmutil.WrapHandler2(func(c *gin.Context) interface{} {
return gin.H{"version": Version}
}))
engine.GET("/api/dtmsvr/newGid", dtmutil.WrapHandler2(newGid)) engine.GET("/api/dtmsvr/newGid", dtmutil.WrapHandler2(newGid))
engine.POST("/api/dtmsvr/prepare", dtmutil.WrapHandler2(prepare)) engine.POST("/api/dtmsvr/prepare", dtmutil.WrapHandler2(prepare))
engine.POST("/api/dtmsvr/submit", dtmutil.WrapHandler2(submit)) engine.POST("/api/dtmsvr/submit", dtmutil.WrapHandler2(submit))

5
dtmsvr/config/config.go

@ -79,7 +79,8 @@ func (s *Store) GetDBConf() dtmcli.DBConf {
} }
} }
type configType struct { // Type is the type for the config of dtm server
type Type struct {
Store Store `yaml:"Store"` Store Store `yaml:"Store"`
TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` TransCronInterval int64 `yaml:"TransCronInterval" default:"3"`
TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"`
@ -97,7 +98,7 @@ type configType struct {
} }
// Config config // Config config
var Config = configType{} var Config = Type{}
// MustLoadConfig load config from env and file // MustLoadConfig load config from env and file
func MustLoadConfig(confFile string) { func MustLoadConfig(confFile string) {

2
dtmsvr/config/config_utils.go

@ -58,7 +58,7 @@ func toUnderscoreUpper(key string) string {
return strings.ToUpper(s2) return strings.ToUpper(s2)
} }
func checkConfig(conf *configType) error { func checkConfig(conf *Type) error {
if conf.RetryInterval < 10 { if conf.RetryInterval < 10 {
return errors.New("RetryInterval should not be less than 10") return errors.New("RetryInterval should not be less than 10")
} }

21
dtmsvr/entry/main.go

@ -14,13 +14,6 @@ import (
"go.uber.org/automaxprocs/maxprocs" "go.uber.org/automaxprocs/maxprocs"
) )
func ver(version *string) {
if *version == "" {
*version = "0.0.0-dev"
}
fmt.Printf("dtm version: %s\n", *version)
}
func usage() { func usage() {
cmd := filepath.Base(os.Args[0]) cmd := filepath.Base(os.Args[0])
s := "Usage: %s [options]\n\n" s := "Usage: %s [options]\n\n"
@ -35,14 +28,18 @@ var isReset = flag.Bool("r", false, "Reset dtm server data.")
var confFile = flag.String("c", "", "Path to the server configuration file.") var confFile = flag.String("c", "", "Path to the server configuration file.")
// Main is the entry point of dtm server. // Main is the entry point of dtm server.
func Main(version *string) *gin.Engine { func Main(version *string) (*gin.Engine, *config.Type) {
flag.Parse() flag.Parse()
if *version == "" {
*version = "v0.0.0-dev"
}
dtmsvr.Version = *version
if flag.NArg() > 0 || *isHelp { if flag.NArg() > 0 || *isHelp {
usage() usage()
return nil return nil, nil
} else if *isVersion { } else if *isVersion {
ver(version) fmt.Printf("dtm version: %s\n", *version)
return nil return nil, nil
} }
logger.Infof("dtm version is: %s", *version) logger.Infof("dtm version is: %s", *version)
config.MustLoadConfig(*confFile) config.MustLoadConfig(*confFile)
@ -58,5 +55,5 @@ func Main(version *string) *gin.Engine {
registry.WaitStoreUp() registry.WaitStoreUp()
app := dtmsvr.StartSvr() // start dtmsvr api app := dtmsvr.StartSvr() // start dtmsvr api
go dtmsvr.CronExpiredTrans(-1) // start dtmsvr cron job go dtmsvr.CronExpiredTrans(-1) // start dtmsvr cron job
return app return app, &config.Config
} }

8
helper/Dockerfile-release

@ -1,4 +1,11 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM node:14.5.0-alpine as bulder1
ARG RELEASE_VERSION
WORKDIR /app/dtm
COPY . .
RUN cd admin && yarn
RUN VITE_ADMIN_VERSION=$RELEASE_VERSION yarn build
FROM --platform=$TARGETPLATFORM golang:1.16-alpine as builder FROM --platform=$TARGETPLATFORM golang:1.16-alpine as builder
ARG TARGETARCH ARG TARGETARCH
ARG TARGETOS ARG TARGETOS
@ -7,6 +14,7 @@ WORKDIR /app/dtm
# RUN go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct # RUN go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
EXPOSE 8080 EXPOSE 8080
COPY . . COPY . .
COPY --from=bulder1 /app/dtm/admin/dist /app/dtm/admin
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags="-s -w -X main.Version=$RELEASE_VERSION" RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags="-s -w -X main.Version=$RELEASE_VERSION"
FROM --platform=$TARGETPLATFORM alpine FROM --platform=$TARGETPLATFORM alpine

54
main.go

@ -7,12 +7,16 @@
package main package main
import ( import (
"embed"
"fmt" "fmt"
"io/fs"
"io/ioutil"
"net/http" "net/http"
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmcli/logger"
"github.com/dtm-labs/dtm/dtmsvr/config"
"github.com/dtm-labs/dtm/dtmsvr/entry" "github.com/dtm-labs/dtm/dtmsvr/entry"
_ "github.com/dtm-labs/dtm/dtmsvr/microservices" _ "github.com/dtm-labs/dtm/dtmsvr/microservices"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -22,23 +26,51 @@ import (
var Version string var Version string
func main() { func main() {
app := entry.Main(&Version) app, conf := entry.Main(&Version)
if app != nil { if app != nil {
addDashboard(app) addAdmin(app, conf)
select {} select {}
} }
} }
func addDashboard(app *gin.Engine) {
app.GET("/dashboard/*name", proxyDashboard) //go:embed admin/dist
app.GET("/@vite/*name", proxyDashboard) var admin embed.FS
app.GET("/node_modules/*name", proxyDashboard)
app.GET("/src/*name", proxyDashboard) var target = "admin.dtm.pub"
app.GET("/@id/*name", proxyDashboard)
func getSub(f1 fs.FS, sub string) fs.FS {
f2, err := fs.Sub(f1, sub)
logger.FatalIfError(err)
return f2
}
func addAdmin(app *gin.Engine, conf *config.Type) {
// for released dtm, serve admin from local files because the build output has been embed
// for testing users, proxy admin to target because the build output has not been embed
dist := getSub(admin, "admin/dist")
index, err := dist.Open("index.html")
if err == nil {
cont, err := ioutil.ReadAll(index)
logger.FatalIfError(err)
_ = index.Close()
sfile := string(cont)
renderIndex := func(c *gin.Context) {
c.Header("content-type", "text/html;charset=utf-8")
c.String(200, sfile)
}
app.StaticFS("/assets", http.FS(getSub(dist, "assets")))
app.GET("/admin/*name", renderIndex)
app.GET("/", renderIndex)
logger.Infof("admin is served from dir 'admin/dist/'")
} else {
app.GET("/", proxyAdmin)
app.GET("/admin/*name", proxyAdmin)
logger.Infof("admin is proxied to %s", target)
}
logger.Infof("admin is running at: http://localhost:%d", conf.HTTPPort)
} }
func proxyDashboard(c *gin.Context) { func proxyAdmin(c *gin.Context) {
target := "127.0.0.1:5000"
u := &url.URL{} u := &url.URL{}
u.Scheme = "http" u.Scheme = "http"
u.Host = target u.Host = target
@ -49,7 +81,7 @@ func proxyDashboard(c *gin.Context) {
ret := fmt.Sprintf("http proxy error %v", err) ret := fmt.Sprintf("http proxy error %v", err)
_, _ = rw.Write([]byte(ret)) _, _ = rw.Write([]byte(ret))
} }
logger.Debugf("proxy dashboard to %s", target) logger.Debugf("proxy admin to %s", target)
proxy.ServeHTTP(c.Writer, c.Request) proxy.ServeHTTP(c.Writer, c.Request)
} }

6
test/api_test.go

@ -18,6 +18,12 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestAPIVersion(t *testing.T) {
resp, err := dtmimp.RestyClient.R().Get(dtmutil.DefaultHTTPServer + "/version")
assert.Nil(t, err)
assert.Equal(t, 200, resp.StatusCode())
}
func TestAPIQuery(t *testing.T) { func TestAPIQuery(t *testing.T) {
gid := dtmimp.GetFuncName() gid := dtmimp.GetFuncName()
err := genMsg(gid).Submit() err := genMsg(gid).Submit()

Loading…
Cancel
Save