package pods import ( "fmt" "log" "github.com/containers/podman/v4/pkg/bindings/containers" "github.com/containers/podman/v4/pkg/bindings/images" "github.com/containers/podman/v4/pkg/specgen" "github.com/google/uuid" "git.jmbit.de/filegate/filegate/db" "git.jmbit.de/filegate/filegate/utils" ) // CreateDownloadContainer() creates Download Container and returns path UUID func CreateDownloadContainer() (string, error) { image := "docker.io/linuxserver/firefox:version-116.0-r0" user := "abc" folder := uuid.NewString() passwd, err := utils.RandomString(32) if err != nil { log.Printf("Error creating Download Container PW: %v", err) passwd = "" } container, err := initializeDownloadContainer(user, passwd, folder, image) if err != nil { return container.ProxyFolder, err } container, err = startDownloadContainer(container) if err != nil { return container.ProxyFolder, err } err = registerDownloadContainer(container) return container.ProxyFolder, err } // DestroyDownloadContainer resolves the Container ID from its folder UUID and destroys it func DestroyDownloadContainer(folder string) error { container, err := db.ContainerByFolder(folder) if err != nil { log.Printf("Could not find Container for Path ID %s: %v", folder, err) return err } err = removeDownloadContainer(container) if err != nil { log.Printf("Could not find Container for Path ID %s: %v", folder, err) return err } return nil } // initializeDownloadContainer() creates the Container Struct func initializeDownloadContainer( user string, passwd string, folder string, image string, ) (*db.Container, error) { container := &db.Container{ User: user, Password: passwd, ProxyFolder: folder, Image: image, } container, err := container.New() if err != nil { log.Printf("Error initializing Download Container Object: %v", err) } return container, err } // startDownloadContainer() takes a Container struct and creates the DownloadContainer for it func startDownloadContainer(container *db.Container) (*db.Container, error) { image := "docker.io/linuxserver/firefox:latest" conn := Socket _, err := images.Pull(conn, image, nil) if err != nil { log.Println(err) } s := specgen.NewSpecGenerator(image, false) s.Env["CUSTOM_USER"] = container.User s.Env["PASSWORD"] = container.Password s.Env["START_DOCKER"] = "False" s.Env["TITLE"] = "Filegate Download Browser" s.Env["PUID"] = "1000" s.Env["GUID"] = "1000" // Use the Containers ID as port offset // TODO: Use better networking to access Download Container s.Env["CUSTOM_PORT"] = fmt.Sprintf("%d", 3000+container.ID) s.Env["SUBFOLDER"] = fmt.Sprintf("/browser/%s/", container.ProxyFolder) createResponse, err := containers.CreateWithSpec(conn, s, nil) if err != nil { log.Println(err) return container, err } if err := containers.Start(conn, createResponse.ID, nil); err != nil { log.Println(err) return container, err } container.ContainerID = createResponse.ID return container, nil } // registerDownloadContainer() saves the Container to the Database func registerDownloadContainer(container *db.Container) error { err := container.Save() return err } // removeDownloadContainer() removes the Container from Podman and the Database func removeDownloadContainer(container *db.Container) error { conn := Socket if err := containers.Kill(conn, container.ContainerID, nil); err != nil { log.Println(err) return err } if _, err := containers.Remove(conn, container.ContainerID, nil); err != nil { log.Println(err) return err } container.Delete() return nil }