feat: support https URLs for digest-file (#2811)
This feature allows one to specify an https URL for any of the digest-file options, resulting in an HTTP PUT to the provided URL. This could for example be a (pre-signed) URL to S3 or GCS. Currently the final digest is only written to the local filesystem, which disappears and is not accessible when Kaniko is run in a managed container service like AWS ECS. By supporting https a single implementation supports all storage services, without the need for special code for S3, GCS, etc..
This commit is contained in:
parent
5133ad83b1
commit
e5395c7a21
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
package executor
|
package executor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
@ -136,6 +137,17 @@ func getDigest(image v1.Image) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDigestFile(path string, digestByteArray []byte) error {
|
func writeDigestFile(path string, digestByteArray []byte) error {
|
||||||
|
if strings.HasPrefix(path, "https://") {
|
||||||
|
// Do a HTTP PUT to the URL; this could be a pre-signed URL to S3 or GCS or Azure
|
||||||
|
req, err := http.NewRequest("PUT", path, bytes.NewReader(digestByteArray)) //nolint:noctx
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "text/plain")
|
||||||
|
_, err = http.DefaultClient.Do(req)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
parentDir := filepath.Dir(path)
|
parentDir := filepath.Dir(path)
|
||||||
if _, err := os.Stat(parentDir); os.IsNotExist(err) {
|
if _, err := os.Stat(parentDir); os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(parentDir, 0700); err != nil {
|
if err := os.MkdirAll(parentDir, 0700); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,10 @@ package executor
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -475,4 +477,32 @@ func TestWriteDigestFile(t *testing.T) {
|
||||||
t.Errorf("expected file to be written successfully, but got error: %v", err)
|
t.Errorf("expected file to be written successfully, but got error: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("https PUT OK", func(t *testing.T) {
|
||||||
|
var uploadedContent []byte
|
||||||
|
|
||||||
|
// Start a test server that checks the PUT request.
|
||||||
|
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPut {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uploadedContent, _ = io.ReadAll(r.Body)
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
// Temporarily replace the default client with the test server client to avoid TLS verification errors.
|
||||||
|
oldClient := http.DefaultClient
|
||||||
|
defer func() { http.DefaultClient = oldClient }()
|
||||||
|
http.DefaultClient = server.Client()
|
||||||
|
|
||||||
|
err := writeDigestFile(server.URL+"/df?sig=1234", []byte("test"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected file to be written successfully, but got error: %v", err)
|
||||||
|
}
|
||||||
|
if string(uploadedContent) != "test" {
|
||||||
|
t.Errorf("expected uploaded content to be 'test', but got '%s'", uploadedContent)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue