filegate/pods/downloadContainer.go

128 lines
3.5 KiB
Go

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
}