diff --git a/Vagrantfile b/Vagrantfile index 1ad37ad..fb65d43 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -93,10 +93,11 @@ Vagrant.configure("2") do |config| # OS apt-get update apt-get upgrade -y - apt-get install -y vim curl git wget qemu-guest-agent + apt-get install -y vim curl git wget qemu-guest-agent make-ssl-cert apt-get install -y nfs-common podman pwgen open-vm-tools make gcc libgpgme-dev apt-get install -y build-essential pkgconf pkgconf-bin libdevmapper-dev libbtrfs-dev echo "export EDITOR=vim" >> /etc/profile + make-ssl-cert generate-default-snakeoil useradd -r -s /bin/false podterminal ## NEOVIM diff --git a/exampleconfig.yaml b/exampleconfig.yaml index 8656480..16dbe3c 100644 --- a/exampleconfig.yaml +++ b/exampleconfig.yaml @@ -14,3 +14,8 @@ image: lscr.io/linuxserver/webtop maxage: 10800 # Port Podterminal should listen to port: 80 +# Files that will be copied into container on startup +skel: /etc/podterminal/skel/ +ssl: false +ssl_cert: /etc/ssl/certs/ssl-cert-snakeoil.pem +ssl_cert_key: /etc/ssl/private/ssl-cert-snakeoil.key diff --git a/main.go b/main.go index 835ef5e..ea35afa 100644 --- a/main.go +++ b/main.go @@ -2,45 +2,48 @@ package main import ( "log" - "net" "os" "github.com/spf13/viper" + "golang.org/x/sync/errgroup" "git.jmbit.de/jmb/podterminal/pods" "git.jmbit.de/jmb/podterminal/utils" "git.jmbit.de/jmb/podterminal/web" ) +var ( + g errgroup.Group +) + func main() { readConfigFile() - laddr := &net.TCPAddr{ - IP: net.IPv4zero, - Port: viper.GetInt("port"), - } - log.Println("Binding Port ", viper.GetInt("port")) - listener, err := net.ListenTCP("tcp", laddr) - if err != nil { - log.Fatalln("could not bind to port ", viper.GetInt("port"), ": ", err) - } pods.ConnectSocket() - // Dumm, ich weiß + + // Start Webserver + g.Go(web.Run) + utils.DropPrivileges("podterminal") log.Println("Dropped Privileges") - pods.PullImage() - // Jank - go pods.GarbageCollector() - web.Run(listener) + g.Go(pods.GarbageCollector) + g.Go(pods.PullImage) + + // prevent main thread from dying + if err := g.Wait(); err != nil { + log.Fatal(err) + } } func readConfigFile() { log.Println("Reading Config") viper.SetConfigFile("/etc/podterminal/config.yaml") viper.SetDefault("port", 80) + viper.SetDefault("ip_addr", "0.0.0.0") viper.SetDefault("image", "lscr.io/linuxserver/webtop") viper.SetDefault("maxAge", 10800) viper.SetDefault("dri", false) viper.SetDefault("dir_node", "/dev/dri/renderD128") + viper.SetDefault("skel", "/etc/podterminal/skel") viper.SetDefault("envvars", map[string]string{ "CUSTOM_USER": "user", diff --git a/pods/garbageCollector.go b/pods/garbageCollector.go index 854565d..d3d67c3 100644 --- a/pods/garbageCollector.go +++ b/pods/garbageCollector.go @@ -4,9 +4,12 @@ import ( "time" ) -func GarbageCollector() { +func GarbageCollector() error { for { - Cleanup() + err := Cleanup() + if err != nil { + return err + } time.Sleep(time.Minute * 10) } } diff --git a/pods/manager.go b/pods/manager.go index 2ab1a9b..e21f3d4 100644 --- a/pods/manager.go +++ b/pods/manager.go @@ -31,18 +31,20 @@ func ConnectSocket() { Socket = socketConnection() } -func PullImage() { +func PullImage() error { log.Println("Downloading Container image ", viper.GetString("image")) image := viper.GetString("image") conn := Socket _, err := images.Pull(conn, image, nil) if err != nil { log.Println(err) + return err } + return nil } // Cleanup deletes Containers older than the specified maximum Age (Equal to session cookie maximum age) -func Cleanup() { +func Cleanup() error { log.Println("Starting cleanup function") containerList := containerList() @@ -55,13 +57,16 @@ func Cleanup() { err := containers.Kill(Socket, container.ID, nil) if err != nil { log.Println(err) + return err } _, err = containers.Remove(Socket, container.ID, nil) if err != nil { log.Println(err) + return err } } } + return nil } func containerList() []entities.ListContainer { diff --git a/podterminal.service b/podterminal.service index b49e170..aa042d5 100644 --- a/podterminal.service +++ b/podterminal.service @@ -4,7 +4,7 @@ After=podman.service [Service] ExecStart=/usr/local/bin/podterminal -Type=Simple +Type=simple Restart=on-failure DeviceAllow=/dev/dri/renderD128 ProtectKernelModules=true diff --git a/web/router.go b/web/router.go index 31ee5c0..83e1b02 100644 --- a/web/router.go +++ b/web/router.go @@ -3,7 +3,6 @@ package web import ( "fmt" "log" - "net" "net/http/httputil" "net/url" "time" @@ -19,9 +18,22 @@ import ( var proxies = make(map[string]*httputil.ReverseProxy) -func Run(listener net.Listener) error { +func Run() error { router := setupRouter() - err := router.RunListener(listener) + address := fmt.Sprintf("%s:%d", viper.GetString("ip_addr"), viper.GetInt("port")) + log.Println("Listening on address", address) + var err error + if viper.GetBool("ssl") == true { + err = router.RunTLS( + address, + viper.GetString("ssl_cert"), + viper.GetString("ssl_cert_key"), + ) + log.Println("Using SSL") + } else { + err = router.Run(address) + } + log.Println("Router is ready") if err != nil { return err } @@ -42,7 +54,6 @@ func setupRouter() *gin.Engine { //router.Use(urlLog()) router.Use(containerProxy) // router.Any("/", containerProxy) - log.Println("Router is ready") return router } @@ -79,6 +90,7 @@ func createReverseProxy(backendService string) (*httputil.ReverseProxy, error) { func containerProxy(c *gin.Context) { session := sessions.Default(c) + session.Save() sessionID := session.ID() if session.Get("ct") == nil { log.Println("Creating Container for Session ", sessionID)