代码拉取完成,页面将自动刷新
package route
import (
"context"
"fmt"
"html/template"
"net"
"net/http"
pprof "net/http/pprof"
"os"
"regexp"
"sync"
noesctmpl "text/template"
"time"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
log "github.com/sirupsen/logrus"
"github.com/yudai/gotty/webtty"
"gitee.com/infrastlabs/fk-container-web-tty/config"
"gitee.com/infrastlabs/fk-container-web-tty/container"
"gitee.com/infrastlabs/fk-container-web-tty/route/asset"
"gitee.com/infrastlabs/fk-container-web-tty/types"
"gitee.com/infrastlabs/fk-container-web-tty/container/grpc"
"github.com/elazarl/go-bindata-assetfs"
)
// Server provides a webtty HTTP endpoint.
type Server struct {
options config.ServerConfig
containerCli container.Cli
upgrader *websocket.Upgrader
srv *http.Server
hostname string
// execID -> containerID
execs map[string]string
// execID -> process
masters map[string]*types.MasterTTY
m sync.RWMutex
}
var (
indexTemplate *template.Template
listTemplate *template.Template
titleTemplate *noesctmpl.Template
)
func mod(i, j int) int {
return i % j
}
func init() {
/* indexData, err := asset.Find("/index.html")
if err != nil {
log.Fatal(err)
}
indexTemplate = indexData.Template()
listIndexData, err := asset.Find("/list.html")
if err != nil {
log.Fatal(err)
}
listTemplate, err = template.New(listIndexData.Name()).
Funcs(template.FuncMap{
"mod": mod,
}).Parse(string(listIndexData.Bytes()))
if err != nil {
panic(err)
} */
var err error
indexData, _ := asset.Asset("index.html")
indexTemplate, err = template.New("index").
Parse(string(indexData))
if err != nil {
panic(err)
}
// fmt.Println("====indexData", string(indexData))
listIndexData, _ := asset.Asset("list.html")
listTemplate, err = template.New("list").
Funcs(template.FuncMap{
"mod": mod,
}).Parse(string(listIndexData))
if err != nil {
panic(err)
}
// fmt.Println("====listIndexData", string(listIndexData))
titleFormat := "{{ .containerName }}@{{ .containerLoc }}"
titleTemplate, err = noesctmpl.New("title").Parse(titleFormat)
if err != nil {
log.Fatal(err)
}
}
// New creates a new instance of Server.
// Server will use the New() of the factory provided to handle each request.
func New(containerCli container.Cli, options config.ServerConfig) (*Server, error) {
var originChekcer func(r *http.Request) bool
if options.WSOrigin != "" {
matcher, err := regexp.Compile(options.WSOrigin)
if err != nil {
return nil, fmt.Errorf("failed to compile regular expression of Websocket Origin: %s", options.WSOrigin)
}
originChekcer = func(r *http.Request) bool {
return matcher.MatchString(r.Header.Get("Origin"))
}
}
h, _ := os.Hostname()
return &Server{
options: options,
containerCli: containerCli,
execs: make(map[string]string, 500),
masters: make(map[string]*types.MasterTTY, 50),
hostname: h,
upgrader: &websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
Subprotocols: webtty.Protocols,
CheckOrigin: originChekcer,
},
}, nil
}
// gin
func (server *Server) addClient(c *gin.Context) {
addr:= c.Param("addr")
server.ClientAdd(addr)
}
func (server *Server) ClientAdd(addr string) {
log.Info("add grpc agent: ", addr)
server.containerCli.(*grpc.GrpcCli).ClientAdd(context.TODO(), addr)
}
func (server *Server) ClientSync(addrs []string) {
log.Info("sync grpc agents: ", addrs)
server.containerCli.(*grpc.GrpcCli).ClientSync(context.TODO(), addrs)
}
// Run starts the main process of the Server.
// The cancelation of ctx will shutdown the server immediately with aborting
// existing connections. Use WithGracefulContext() to support graceful shutdown.
func (server *Server) Run00(ctx context.Context, options ...RunOption) error {
cctx, cancel := context.WithCancel(ctx)
defer cancel()
opts := &RunOptions{gracefulCtx: context.Background()}
for _, opt := range options {
opt(opts)
}
router := gin.New()
router.Use(gin.Recovery())
if gin.Mode() == gin.DebugMode {
router.Use(gin.Logger())
}
// Routes
router.GET("/", server.handleListContainers)
router.GET("/auth_token.js", server.handleAuthToken)
router.GET("/config.js", server.handleConfig)
/* h := gin.WrapF(asset.Handler)
for _, f := range asset.List() {
if f.Name() != "/" {
router.GET(f.Name(), h)
}
} */
// exec
counter := newCounter(server.options.IdleTime)
router.GET("/e/:cid/", server.handleExecRedirect) // containerID
router.GET("/exec/:eid/", server.handleWSIndex) // execID
router.GET("/exec/:eid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
router.GET("/exec2/:cid/", server.handleWSIndex) // execID
router.GET("/exec2/:cid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
// logs
router.GET("/logs/:cid/", server.handleWSIndex)
router.GET("/logs/:cid/"+"ws", func(c *gin.Context) { server.handleLogs(c) })
router.GET("/conf/:addr/", server.addClient)
ctl := server.options.Control
if ctl.Enable {
// container actions: start|stop|restart
containerG := router.Group("/container")
if ctl.Start || ctl.All {
containerG.POST("/start/:id", server.handleStartContainer)
}
if ctl.Stop || ctl.All {
containerG.POST("/stop/:id", server.handleStopContainer)
}
if ctl.Restart || ctl.All {
containerG.POST("/restart/:id", server.handleRestartContainer)
}
}
// pprof
rootMux := http.NewServeMux()
if log.GetLevel() == log.DebugLevel {
rootMux.HandleFunc("/debug/pprof/", pprof.Index)
rootMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
rootMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
rootMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
rootMux.HandleFunc("/debug/pprof/trace", pprof.Trace)
}
rootMux.Handle("/", router)
hostPort := net.JoinHostPort(server.options.Address,
fmt.Sprint(server.options.Port))
srv := &http.Server{
Addr: hostPort,
Handler: rootMux,
}
srvErr := make(chan error, 1)
go func() {
srvErr <- srv.ListenAndServe()
}()
go func() {
select {
case <-opts.gracefulCtx.Done():
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
case <-cctx.Done():
}
}()
log.Infof("Server running at http://%s", hostPort)
var err error
select {
case err = <-srvErr:
if err == http.ErrServerClosed { // by graceful ctx
err = nil
} else {
cancel()
}
case <-cctx.Done():
srv.Close()
err = cctx.Err()
}
conn := counter.count()
if conn > 0 {
log.Printf("Waiting for %d connections to be closed", conn)
fmt.Println("Ctl-C to force close")
}
counter.wait()
return err
}
var WebCtx=""
func (server *Server) Run01(ctx context.Context, options ...RunOption) error {
cctx, cancel := context.WithCancel(ctx)
defer cancel()
opts := &RunOptions{gracefulCtx: context.Background()}
for _, opt := range options {
opt(opts)
}
router := gin.New()
router.Use(gin.Recovery())
if gin.Mode() == gin.DebugMode {
router.Use(gin.Logger())
}
// Routes
WebCtx= "/webssh"
rG := router.Group(WebCtx)
rG.GET("/", server.handleListContainers)
rG.GET("/auth_token.js", server.handleAuthToken)
rG.GET("/config.js", server.handleConfig)
//asset.Handler: generateReplace, ServerHTTP
//d.files["/"+cut]
/* path:= r.RequestURI
cut:= strings.Trim(path, "/webssh")
fmt.Println("path:", path)
fmt.Println("cut:", cut) */
/* h := gin.WrapF(asset.Handler)
for _, f := range asset.List() {
if f.Name() != "/" {
// router.GET("/webssh/"+f.Name(), h)
rG.GET(f.Name(), h)
}
} */
fs := assetfs.AssetFS{
Asset: asset.Asset,
AssetDir: asset.AssetDir,
AssetInfo: asset.AssetInfo,
}
rG.StaticFS("/static", &fs)
// router.StaticFS("/aa2", &fs)
// exec
counter := newCounter(server.options.IdleTime)
rG.GET("/e/:cid/", server.handleExecRedirect) // containerID
rG.GET("/exec/:eid/", server.handleWSIndex) // execID
rG.GET("/exec/:eid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
rG.GET("/exec2/:cid/", server.handleWSIndex) // execID
rG.GET("/exec2/:cid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
// logs
rG.GET("/logs/:cid/", server.handleWSIndex)
rG.GET("/logs/:cid/"+"ws", func(c *gin.Context) { server.handleLogs(c) })
rG.GET("/conf/:addr/", server.addClient)
// rG.StaticFS() //
ctl := server.options.Control
if ctl.Enable {
// container actions: start|stop|restart
containerG := rG.Group("/container")
if ctl.Start || ctl.All {
containerG.POST("/start/:id", server.handleStartContainer)
}
if ctl.Stop || ctl.All {
containerG.POST("/stop/:id", server.handleStopContainer)
}
if ctl.Restart || ctl.All {
containerG.POST("/restart/:id", server.handleRestartContainer)
}
}
// pprof
rootMux := http.NewServeMux()
if log.GetLevel() == log.DebugLevel {
rootMux.HandleFunc("/debug/pprof/", pprof.Index)
rootMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
rootMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
rootMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
rootMux.HandleFunc("/debug/pprof/trace", pprof.Trace)
}
rootMux.Handle("/", router)
hostPort := net.JoinHostPort(server.options.Address,
fmt.Sprint(server.options.Port))
srv := &http.Server{
Addr: hostPort,
Handler: rootMux,
}
srvErr := make(chan error, 1)
go func() {
srvErr <- srv.ListenAndServe()
}()
go func() {
select {
case <-opts.gracefulCtx.Done():
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
case <-cctx.Done():
}
}()
log.Infof("Server running at http://%s", hostPort)
var err error
select {
case err = <-srvErr:
if err == http.ErrServerClosed { // by graceful ctx
err = nil
} else {
cancel()
}
case <-cctx.Done():
srv.Close()
err = cctx.Err()
}
conn := counter.count()
if conn > 0 {
log.Printf("Waiting for %d connections to be closed", conn)
fmt.Println("Ctl-C to force close")
}
counter.wait()
return err
}
func (server *Server) RunGinRoute(ctx context.Context, r *gin.Engine, prefix string, options ...RunOption) error {
/* cctx, cancel := context.WithCancel(ctx)
defer cancel() */
/* opts := &RunOptions{gracefulCtx: context.Background()}
for _, opt := range options {
opt(opts)
} */
/* router := gin.New()
router.Use(gin.Recovery())
if gin.Mode() == gin.DebugMode {
router.Use(gin.Logger())
} */
// Routes
WebCtx= prefix //"/webssh"
rG := r.Group(WebCtx) //router
rG.GET("/", server.handleListContainers)
rG.GET("/auth_token.js", server.handleAuthToken)
rG.GET("/config.js", server.handleConfig)
fs := assetfs.AssetFS{
Asset: asset.Asset,
AssetDir: asset.AssetDir,
AssetInfo: asset.AssetInfo,
}
rG.StaticFS("/static", &fs)
// exec
counter := newCounter(server.options.IdleTime)
rG.GET("/e/:cid/", server.handleExecRedirect) // containerID
rG.GET("/exec/:eid/", server.handleWSIndex) // execID
rG.GET("/exec/:eid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
rG.GET("/exec2/:cid/", server.handleWSIndex) // execID
rG.GET("/exec2/:cid/"+"ws", func(c *gin.Context) { server.handleExec(c, counter) })
// logs
rG.GET("/logs/:cid/", server.handleWSIndex)
rG.GET("/logs/:cid/"+"ws", func(c *gin.Context) { server.handleLogs(c) })
rG.GET("/conf/:addr/", server.addClient)
// rG.StaticFS() //
ctl := server.options.Control
if ctl.Enable {
// container actions: start|stop|restart
containerG := rG.Group("/container")
if ctl.Start || ctl.All {
containerG.POST("/start/:id", server.handleStartContainer)
}
if ctl.Stop || ctl.All {
containerG.POST("/stop/:id", server.handleStopContainer)
}
if ctl.Restart || ctl.All {
containerG.POST("/restart/:id", server.handleRestartContainer)
}
}
// pprof
/* rootMux := http.NewServeMux()
if log.GetLevel() == log.DebugLevel {
rootMux.HandleFunc("/debug/pprof/", pprof.Index)
rootMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
rootMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
rootMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
rootMux.HandleFunc("/debug/pprof/trace", pprof.Trace)
}
rootMux.Handle("/", router) */
/* hostPort := net.JoinHostPort(server.options.Address,
fmt.Sprint(server.options.Port))
srv := &http.Server{
Addr: hostPort,
Handler: rootMux,
}
srvErr := make(chan error, 1)
go func() {
srvErr <- srv.ListenAndServe()
}()
go func() {
select {
case <-opts.gracefulCtx.Done():
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
case <-cctx.Done():
}
}() */
// log.Infof("Server running at http://%s", hostPort)
var err error
/* select {
case err = <-srvErr:
if err == http.ErrServerClosed { // by graceful ctx
err = nil
} else {
cancel()
}
case <-cctx.Done():
srv.Close()
err = cctx.Err()
} */
conn := counter.count()
if conn > 0 {
log.Printf("Waiting for %d connections to be closed", conn)
fmt.Println("Ctl-C to force close")
}
counter.wait()
return err
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。