Skip to content

Commit

Permalink
Fix incorrect timestamp when helm package
Browse files Browse the repository at this point in the history
The files contained in the `tar` file from `helm package` did not have
the correct timestamp. This lack of timestamp occurred because we were
not writing any time to the tar header file.
  • Loading branch information
mattjmcnaughton committed Jun 2, 2018
1 parent 7571691 commit 96a85a0
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 3 deletions.
8 changes: 5 additions & 3 deletions pkg/chartutil/save.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"time"

"github.com/ghodss/yaml"

Expand Down Expand Up @@ -205,9 +206,10 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
func writeToTar(out *tar.Writer, name string, body []byte) error {
// TODO: Do we need to create dummy parent directory names if none exist?
h := &tar.Header{
Name: filepath.ToSlash(name),
Mode: 0755,
Size: int64(len(body)),
Name: filepath.ToSlash(name),
Mode: 0755,
Size: int64(len(body)),
ModTime: time.Now(),
}
if err := out.WriteHeader(h); err != nil {
return err
Expand Down
80 changes: 80 additions & 0 deletions pkg/chartutil/save_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ limitations under the License.
package chartutil

import (
"archive/tar"
"compress/gzip"
"io"
"io/ioutil"
"os"
"strings"
"testing"
"time"

"github.com/golang/protobuf/ptypes/any"
"k8s.io/helm/pkg/proto/hapi/chart"
Expand Down Expand Up @@ -73,6 +77,82 @@ func TestSave(t *testing.T) {
}
}

func TestSavePreservesTimestamps(t *testing.T) {
// Test executes so quickly that if we don't subtract a second, the
// check will fail because `initialCreateTime` will be identical to the
// written timestamp for the files.
initialCreateTime := time.Now().Add(-1 * time.Second)

tmp, err := ioutil.TempDir("", "helm-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)

c := &chart.Chart{
Metadata: &chart.Metadata{
Name: "ahab",
Version: "1.2.3.4",
},
Values: &chart.Config{
Raw: "ship: Pequod",
},
Files: []*any.Any{
{TypeUrl: "scheherazade/shahryar.txt", Value: []byte("1,001 Nights")},
},
}

where, err := Save(c, tmp)
if err != nil {
t.Fatalf("Failed to save: %s", err)
}

allHeaders, err := retrieveAllHeadersFromTar(where)
if err != nil {
t.Fatalf("Failed to parse tar: %v", err)
}

for _, header := range allHeaders {
if header.ModTime.Before(initialCreateTime) {
t.Fatalf("File timestamp not preserved: %v", header.ModTime)
}
}
}

// We could refactor `load.go` to use this `retrieveAllHeadersFromTar` function
// as well, so we are not duplicating components of the code which iterate
// through the tar.
func retrieveAllHeadersFromTar(path string) ([]*tar.Header, error) {
raw, err := os.Open(path)
if err != nil {
return nil, err
}
defer raw.Close()

unzipped, err := gzip.NewReader(raw)
if err != nil {
return nil, err
}
defer unzipped.Close()

tr := tar.NewReader(unzipped)
headers := []*tar.Header{}
for {
hd, err := tr.Next()
if err == io.EOF {
break
}

if err != nil {
return nil, err
}

headers = append(headers, hd)
}

return headers, nil
}

func TestSaveDir(t *testing.T) {
tmp, err := ioutil.TempDir("", "helm-")
if err != nil {
Expand Down

0 comments on commit 96a85a0

Please sign in to comment.