mirror of
https://github.com/mudler/luet.git
synced 2025-09-05 01:00:44 +00:00
Switch to go mod
This commit is contained in:
157
vendor/github.com/mudler/docker-companion/api/unpack.go
generated
vendored
Normal file
157
vendor/github.com/mudler/docker-companion/api/unpack.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
docker "github.com/fsouza/go-dockerclient"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
// SEPARATOR contains system-specific separator
|
||||
const SEPARATOR = string(filepath.Separator)
|
||||
|
||||
// ROOTFS is our temporary rootfs path
|
||||
const ROOTFS = "." + SEPARATOR + "rootfs_overlay"
|
||||
|
||||
// Unpack unpacks a docker image into a path
|
||||
func Unpack(client *docker.Client, image string, dirname string, fatal bool) error {
|
||||
var err error
|
||||
r, w := io.Pipe()
|
||||
|
||||
if dirname == "" {
|
||||
dirname = ROOTFS
|
||||
}
|
||||
|
||||
os.MkdirAll(dirname, 0777)
|
||||
|
||||
filename, err := ioutil.TempFile(os.TempDir(), "artemide")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't create the temporary file")
|
||||
}
|
||||
os.Remove(filename.Name())
|
||||
|
||||
jww.INFO.Println("Creating container")
|
||||
|
||||
container, err := client.CreateContainer(docker.CreateContainerOptions{
|
||||
Config: &docker.Config{
|
||||
Image: image,
|
||||
Cmd: []string{"true"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln("Couldn't export container, sorry", err)
|
||||
}
|
||||
defer func(*docker.Container) {
|
||||
client.RemoveContainer(docker.RemoveContainerOptions{
|
||||
ID: container.ID,
|
||||
Force: true,
|
||||
})
|
||||
}(container)
|
||||
|
||||
signalchan := make(chan os.Signal, 1)
|
||||
signal.Notify(signalchan,
|
||||
syscall.SIGINT,
|
||||
syscall.SIGTERM,
|
||||
syscall.SIGQUIT)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
s := <-signalchan
|
||||
switch s {
|
||||
|
||||
case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
|
||||
jww.WARN.Println("SIGTERM/SIGINT/SIGQUIT detected, removing pending containers")
|
||||
client.RemoveContainer(docker.RemoveContainerOptions{
|
||||
ID: container.ID,
|
||||
Force: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// writing without a reader will deadlock so write in a goroutine
|
||||
go func() {
|
||||
// it is important to close the writer or reading from the other end of the
|
||||
// pipe will never finish
|
||||
defer w.Close()
|
||||
err := client.ExportContainer(docker.ExportContainerOptions{ID: container.ID, OutputStream: w})
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln("Couldn't export container, sorry", err)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
jww.INFO.Println("Extracting to", dirname)
|
||||
|
||||
err = Untar(r, dirname, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not unpack to " + dirname)
|
||||
}
|
||||
err = prepareRootfs(dirname, fatal)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func prepareRootfs(dirname string, fatal bool) error {
|
||||
|
||||
_, err := os.Stat(dirname + SEPARATOR + ".dockerenv")
|
||||
if err == nil {
|
||||
err = os.Remove(dirname + SEPARATOR + ".dockerenv")
|
||||
if err != nil {
|
||||
if fatal == true {
|
||||
return fmt.Errorf("could not remove docker env file")
|
||||
} else {
|
||||
jww.WARN.Println("error on remove .dockerenv, extracting anyway")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = os.Stat(dirname + SEPARATOR + ".dockerinit")
|
||||
if err == nil {
|
||||
err = os.Remove(dirname + SEPARATOR + ".dockerinit")
|
||||
if err != nil {
|
||||
if fatal == true {
|
||||
return fmt.Errorf("could not remove docker init file")
|
||||
} else {
|
||||
jww.WARN.Println("error on remove .dockerinit, extracting anyway")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = os.MkdirAll(dirname+SEPARATOR+"dev", 0751)
|
||||
if err != nil {
|
||||
if fatal == true {
|
||||
return fmt.Errorf("could not create dev folder")
|
||||
} else {
|
||||
jww.WARN.Println("could not create dev folder")
|
||||
}
|
||||
}
|
||||
|
||||
// Google DNS as default
|
||||
d1 := []byte("nameserver 8.8.8.8\nnameserver 8.8.4.4\n")
|
||||
err = ioutil.WriteFile(dirname+SEPARATOR+"etc"+SEPARATOR+"resolv.conf", d1, 0644)
|
||||
if err != nil {
|
||||
if fatal == true {
|
||||
return fmt.Errorf("could not write resolv.conf file")
|
||||
} else {
|
||||
jww.WARN.Println("could not create resolv.conf file")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Untar just a wrapper around the docker functions
|
||||
func Untar(in io.Reader, dest string, sameOwner bool) error {
|
||||
return archive.Untar(in, dest, &archive.TarOptions{
|
||||
NoLchown: !sameOwner,
|
||||
ExcludePatterns: []string{"dev/"}, // prevent 'operation not permitted'
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user