Add possibility to prepare /srv from an archive
This commit is contained in:
parent
0ad979b240
commit
9564118f40
3 changed files with 78 additions and 4 deletions
|
@ -111,6 +111,7 @@ type App struct {
|
|||
Tech string `json:"tech"`
|
||||
TechVersion string `json:"tech_version"`
|
||||
Password string `json:"password"`
|
||||
ArchiveURL string `json:"archive_url"` // Archive with content of /srv
|
||||
} `json:"setup,omitempty" gorm:"-"`
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ func (c *Container) getDriver() *Driver {
|
|||
}
|
||||
|
||||
// volumeHostPath each container has one volume mounted into it,
|
||||
func (c *Container) volumeHostPath() string {
|
||||
func (c *Container) VolumeHostPath() string {
|
||||
return path.Join(c.AppsPath, c.App.Name)
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ func (c *Container) Status() (ContainerStatus, error) {
|
|||
|
||||
// DiskUsage returns number of bytes and inodes used by the container in it's mounted volume
|
||||
func (c *Container) DiskUsage() (int, int, error) {
|
||||
return du(c.volumeHostPath())
|
||||
return du(c.VolumeHostPath())
|
||||
}
|
||||
|
||||
// ResourceUsage returns amount of memory in B and CPU in % that the app occupies
|
||||
|
@ -153,7 +153,7 @@ func (c *Container) Create() error {
|
|||
_, err := driver.Create(
|
||||
c.App.Name,
|
||||
c.App.Image,
|
||||
c.volumeHostPath(),
|
||||
c.VolumeHostPath(),
|
||||
c.App.HTTPPort,
|
||||
c.App.SSHPort,
|
||||
c.App.CPU,
|
||||
|
@ -586,7 +586,7 @@ func (c *Container) GetTechs() (apps.AppTechs, error) {
|
|||
|
||||
// Returns info about active technology
|
||||
func (c *Container) GetActiveTech() (*TechInfo, error) {
|
||||
info, err := getTechAndVersion(path.Join(c.volumeHostPath(), "bin", "primary_tech"))
|
||||
info, err := getTechAndVersion(path.Join(c.VolumeHostPath(), "bin", "primary_tech"))
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
|
|
73
glue/main.go
73
glue/main.go
|
@ -3,7 +3,11 @@ package glue
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -200,6 +204,64 @@ func (p *Processor) Get(noUpdate bool) (apps.App, error) {
|
|||
return app, nil
|
||||
}
|
||||
|
||||
// Takes URL with an tar archive and prepares container's volume from it.
|
||||
func (p *Processor) volumeFromURL(url string, container *docker.Container) error {
|
||||
// Validation, check if url ends with tar.zstd
|
||||
if !strings.HasSuffix(url, ".tar.zstd") {
|
||||
return fmt.Errorf("archive has to end with .tar.zstd")
|
||||
}
|
||||
|
||||
volumePath := container.VolumeHostPath()
|
||||
|
||||
// Prepare volume path
|
||||
err := os.MkdirAll(volumePath, 0755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create volume path: %v", err)
|
||||
}
|
||||
|
||||
// Download the archive
|
||||
log.Printf("%s: downloading archive from %s\n", container.App.Name, url)
|
||||
f, err := os.Create(volumePath + "/archive.tar.zstd")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create archive file: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download archive: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
n, err := io.Copy(f, resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download archive: %v", err)
|
||||
}
|
||||
log.Printf("downloaded %d bytes\n", n)
|
||||
|
||||
// Extract the archive
|
||||
log.Printf("%s: extracting archive\n", container.App.Name)
|
||||
|
||||
// Call tar xf archive.tar.zstd -C /volume
|
||||
cmd := exec.Command("tar", "-I", "zstd", "-xf", "archive.tar.zstd", "-C", volumePath)
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Printf("%s: failed to extract archive: %v", container.App.Name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove archive
|
||||
log.Printf("%s: removing archive\n", container.App.Name)
|
||||
err = os.Remove(volumePath + "/archive.tar.zstd")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove archive: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("%s: volume preparing done\n", container.App.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create creates a single app in the system
|
||||
func (p *Processor) Create(appTemplate apps.App) error {
|
||||
if appTemplate.EnvRaw == nil {
|
||||
|
@ -219,6 +281,17 @@ func (p *Processor) Create(appTemplate apps.App) error {
|
|||
AppsPath: p.AppsPath,
|
||||
}
|
||||
|
||||
if len(appTemplate.Snapshot) > 0 && len(appTemplate.Setup.ArchiveURL) > 0 {
|
||||
return fmt.Errorf("snapshot and archive_url cannot be used together")
|
||||
}
|
||||
|
||||
if len(appTemplate.Setup.ArchiveURL) > 0 {
|
||||
err = p.volumeFromURL(appTemplate.Setup.ArchiveURL, &container)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare volume: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = container.Create()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue