This is an automated email from the ASF dual-hosted git repository.

astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 34956df3c99cb0d86f11483dc881596940fb1178
Author: Antonin Stefanutti <[email protected]>
AuthorDate: Thu Jul 29 11:36:41 2021 +0200

    chore(s2i): Use tar.gz archive to preserve file permissions
---
 pkg/builder/s2i.go  | 72 +++++++++++++++++++++++++++++++++++++++++++++++++----
 pkg/util/zip/zip.go | 64 -----------------------------------------------
 2 files changed, 67 insertions(+), 69 deletions(-)

diff --git a/pkg/builder/s2i.go b/pkg/builder/s2i.go
index 428901a..6ce99b6 100644
--- a/pkg/builder/s2i.go
+++ b/pkg/builder/s2i.go
@@ -18,10 +18,16 @@ limitations under the License.
 package builder
 
 import (
+       "archive/tar"
+       "compress/gzip"
        "context"
+       "fmt"
+       "io"
        "io/ioutil"
        "os"
        "path"
+       "path/filepath"
+       "strings"
        "time"
 
        "github.com/pkg/errors"
@@ -42,7 +48,6 @@ import (
        "github.com/apache/camel-k/pkg/client"
        "github.com/apache/camel-k/pkg/util/kubernetes/customclient"
        "github.com/apache/camel-k/pkg/util/log"
-       "github.com/apache/camel-k/pkg/util/zip"
 )
 
 type s2iTask struct {
@@ -140,7 +145,7 @@ func (t *s2iTask) Do(ctx context.Context) v1.BuildStatus {
        if err != nil {
                return status.Failed(err)
        }
-       archive := path.Join(tmpDir, "archive.zip")
+       archive := path.Join(tmpDir, "archive.tar.gz")
        defer os.RemoveAll(tmpDir)
 
        contextDir := t.task.ContextDir
@@ -156,14 +161,19 @@ func (t *s2iTask) Do(ctx context.Context) v1.BuildStatus {
                contextDir = path.Join(pwd, ContextDir)
        }
 
-       err = zip.Directory(contextDir, archive)
+       archiveFile, err := os.Create(archive)
        if err != nil {
-               return status.Failed(errors.Wrap(err, "cannot zip context 
directory"))
+               return status.Failed(errors.Wrap(err, "cannot create tar 
archive"))
+       }
+
+       err = tarDir(contextDir, archiveFile)
+       if err != nil {
+               return status.Failed(errors.Wrap(err, "cannot tar context 
directory"))
        }
 
        resource, err := ioutil.ReadFile(archive)
        if err != nil {
-               return status.Failed(errors.Wrap(err, "cannot fully read zip 
file "+archive))
+               return status.Failed(errors.Wrap(err, "cannot read tar file 
"+archive))
        }
 
        restClient, err := customclient.GetClientFor(t.c, "build.openshift.io", 
"v1")
@@ -275,3 +285,55 @@ func (t *s2iTask) cancelBuild(ctx context.Context, build 
*buildv1.Build) error {
        *build = *target
        return nil
 }
+
+func tarDir(src string, writers ...io.Writer) error {
+       // ensure the src actually exists before trying to tar it
+       if _, err := os.Stat(src); err != nil {
+               return fmt.Errorf("unable to tar files - %v", err.Error())
+       }
+
+       mw := io.MultiWriter(writers...)
+
+       gzw := gzip.NewWriter(mw)
+       defer gzw.Close()
+
+       tw := tar.NewWriter(gzw)
+       defer tw.Close()
+
+       return filepath.Walk(src, func(file string, fi os.FileInfo, err error) 
error {
+               if err != nil {
+                       return err
+               }
+
+               if !fi.Mode().IsRegular() {
+                       return nil
+               }
+
+               header, err := tar.FileInfoHeader(fi, fi.Name())
+               if err != nil {
+                       return err
+               }
+
+               // update the name to correctly reflect the desired destination 
when un-taring
+               header.Name = strings.TrimPrefix(strings.Replace(file, src, "", 
-1), string(filepath.Separator))
+
+               if err := tw.WriteHeader(header); err != nil {
+                       return err
+               }
+
+               f, err := os.Open(file)
+               if err != nil {
+                       return err
+               }
+
+               if _, err := io.Copy(tw, f); err != nil {
+                       return err
+               }
+
+               // manually close here after each file operation; deferring 
would cause each file close
+               // to wait until all operations have completed.
+               f.Close()
+
+               return nil
+       })
+}
diff --git a/pkg/util/zip/zip.go b/pkg/util/zip/zip.go
deleted file mode 100644
index a5f59de..0000000
--- a/pkg/util/zip/zip.go
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package zip
-
-import (
-       "archive/zip"
-       "io"
-       "os"
-       "path/filepath"
-       "strings"
-)
-
-func Directory(pathToZip, destinationPath string) error {
-       destinationFile, err := os.Create(destinationPath)
-       if err != nil {
-               return err
-       }
-       myZip := zip.NewWriter(destinationFile)
-       err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, 
err error) error {
-               if info.IsDir() {
-                       return nil
-               }
-               if err != nil {
-                       return err
-               }
-               relPath := strings.TrimPrefix(filePath, pathToZip)
-               zipFile, err := myZip.Create(relPath)
-               if err != nil {
-                       return err
-               }
-               fsFile, err := os.Open(filePath)
-               if err != nil {
-                       return err
-               }
-               _, err = io.Copy(zipFile, fsFile)
-               if err != nil {
-                       return err
-               }
-               return nil
-       })
-       if err != nil {
-               return err
-       }
-       err = myZip.Close()
-       if err != nil {
-               return err
-       }
-       return nil
-}

Reply via email to