Skip to content

Commit

Permalink
feat: Add https tar.gz remote source for context
Browse files Browse the repository at this point in the history
  • Loading branch information
jfrabaute committed Dec 10, 2020
1 parent c2a919a commit 156fb27
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/buildcontext/buildcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func GetBuildContext(srcContext string, opts BuildOptions) (BuildContext, error)
if util.ValidAzureBlobStorageHost(srcContext) {
return &AzureBlob{context: srcContext}, nil
}
return nil, errors.New("url provided for https context is not in a supported format, please use the https url for Azure Blob Storage")
return &HTTPSTar{context: srcContext}, nil
case TarBuildContextPrefix:
return &Tar{context: context}, nil
}
Expand Down
63 changes: 63 additions & 0 deletions pkg/buildcontext/https.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package buildcontext

import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"

"github.com/GoogleContainerTools/kaniko/pkg/constants"
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/sirupsen/logrus"
)

// HTTPSTar struct for https tar.gz files processing
type HTTPSTar struct {
context string
}

// UnpackTarFromBuildContext downloads context file from https server
func (h *HTTPSTar) UnpackTarFromBuildContext() (directory string, err error) {

logrus.Info("Retrieving https tar file")

// Create directory and target file for downloading the context file
directory = constants.BuildContextDir
tarPath := filepath.Join(directory, constants.ContextTar)
file, err := util.CreateTargetTarfile(tarPath)
if err != nil {
return
}

// Download tar file from remote https server
// and save it into the target tar file
resp, err := http.Get(h.context)
if err != nil {
return
}
defer func() {
if closeErr := resp.Body.Close(); err == nil && closeErr != nil {
err = closeErr
}
}()

if resp.StatusCode != http.StatusOK {
return directory, fmt.Errorf("HTTPSTar bad status from server: %s", resp.Status)
}

if _, err = io.Copy(file, resp.Body); err != nil {
return tarPath, err
}

logrus.Info("Retrieved https tar file")

if err = util.UnpackCompressedTar(tarPath, directory); err != nil {
return
}

logrus.Info("Extracted https tar file")

// Remove the tar so it doesn't interfere with subsequent commands
return directory, os.Remove(tarPath)
}
104 changes: 104 additions & 0 deletions pkg/buildcontext/https_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package buildcontext

import (
"archive/tar"
"bytes"
"compress/gzip"
"net/http"
"net/http/httptest"
"testing"
)

func TestBuildWithHttpsTar(t *testing.T) {

tests := []struct {
name string
serverHandler http.HandlerFunc
shoudErr bool
}{
{
name: "test http bad status",
serverHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
_, err := w.Write([]byte("corrupted message"))
if err != nil {
t.Fatalf("Error sending response: %v", err)
}
}),
shoudErr: true,
},
{
name: "test http bad data",
serverHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte("corrupted message"))
if err != nil {
t.Fatalf("Error sending response: %v", err)
}
}),
shoudErr: true,
},
{
name: "test http tar file",
serverHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write(getTargzFile(t))
if err != nil {
t.Fatalf("Error sending response: %v", err)
}
}),
},
}

for _, tcase := range tests {
t.Run(tcase.name, func(t *testing.T) {
server := httptest.NewServer(tcase.serverHandler)
defer server.Close()

context := &HTTPSTar{
context: server.URL + "/data.tar.gz",
}

_, err := context.UnpackTarFromBuildContext()
if err == nil && tcase.shoudErr || err != nil && !tcase.shoudErr {
t.Fatalf("Error not expected but returned: %s", err)
}
})
}
}

func getTargzFile(t *testing.T) []byte {
// Create and add some files to the archive.
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
tw := tar.NewWriter(gz)
var files = []struct {
Name, Body string
}{
{"readme.txt", "This archive contains some text files."},
{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
{"todo.txt", "Get animal handling license."},
}
for _, file := range files {
hdr := &tar.Header{
Name: file.Name,
Mode: 0600,
Size: int64(len(file.Body)),
}
if err := tw.WriteHeader(hdr); err != nil {
t.Fatal(err)
}
if _, err := tw.Write([]byte(file.Body)); err != nil {
t.Fatal(err)
}
}
if err := tw.Close(); err != nil {
t.Fatal(err)
}

if err := gz.Close(); err != nil {
t.Fatal(err)
}

return buf.Bytes()
}

0 comments on commit 156fb27

Please sign in to comment.