dendrite/cmd/dendrite-upgrade-tests/main.go

101 lines
2.7 KiB
Go

package main
import (
"bytes"
"context"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"time"
"github.com/codeclysm/extract"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
var (
flagTempDir = flag.String("tmp", "tmp", "Path to temporary directory to dump tarballs to")
)
func ptr(in string) *string {
return &in
}
// downloadArchive downloads an arbitrary github archive of the form:
// https://github.com/matrix-org/dendrite/archive/v0.3.11.tar.gz
// and re-tarballs it without the top-level directory which contains branch information. It inserts
// the contents of `dockerfile` as a root file `Dockerfile` in the re-tarballed directory such that
// you can directly feed the retarballed archive to `ImageBuild` to have it run said dockerfile.
// Returns the tarball buffer on success.
func downloadArchive(cli *http.Client, archiveURL string, dockerfile []byte) (*bytes.Buffer, error) {
tmpDir := *flagTempDir
resp, err := cli.Get(archiveURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("got HTTP %d", resp.StatusCode)
}
os.Mkdir(tmpDir, os.ModePerm)
defer os.RemoveAll(tmpDir)
// dump the tarball temporarily, stripping the top-level directory
err = extract.Archive(context.Background(), resp.Body, tmpDir, func(inPath string) string {
// remove top level
segments := strings.Split(inPath, "/")
return strings.Join(segments[1:], "/")
})
if err != nil {
return nil, err
}
// add top level Dockerfile
err = ioutil.WriteFile(path.Join(tmpDir, "Dockerfile"), dockerfile, os.ModePerm)
if err != nil {
return nil, fmt.Errorf("failed to inject /Dockerfile: %w", err)
}
// now re-tarball it :/
var tarball bytes.Buffer
err = compress(*flagTempDir, &tarball)
if err != nil {
return nil, err
}
return &tarball, nil
}
func main() {
flag.Parse()
httpClient := &http.Client{
Timeout: 60 * time.Second,
}
// pull an archive, this contains a top-level directory which screws with the build context
// which we need to fix up post download
u := "https://github.com/matrix-org/dendrite/archive/v0.3.11.tar.gz"
tarball, err := downloadArchive(httpClient, u, []byte("FROM golang:1.15\nRUN echo 'hello world'"))
if err != nil {
panic(err)
}
fmt.Printf("%s => %d bytes\n", u, tarball.Len())
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
fmt.Println("building...")
res, err := cli.ImageBuild(context.Background(), tarball, types.ImageBuildOptions{
Tags: []string{"dendrite-upgrade"},
})
if err != nil {
panic(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}