@ -31,6 +31,22 @@ import (
"helm.sh/helm/v3/pkg/chart"
)
type (
saveConfig struct {
noTimestamp bool
}
// SaveOpt is an option for modifying the behavior of Save
SaveOpt func ( * saveConfig )
)
// WithoutTimestamp provides the ability to save tar archives without a timestamp
func WithoutTimestamp ( ) SaveOpt {
return func ( cfg * saveConfig ) {
cfg . noTimestamp = true
}
}
var headerBytes = [ ] byte ( "+aHR0cHM6Ly95b3V0dS5iZS96OVV6MWljandyTQo=" )
// SaveDir saves a chart as files in a directory.
@ -99,7 +115,12 @@ func SaveDir(c *chart.Chart, dest string) error {
// will generate /foo/bar-1.0.0.tgz.
//
// This returns the absolute path to the chart archive file.
func Save ( c * chart . Chart , outDir string ) ( string , error ) {
func Save ( c * chart . Chart , outDir string , saveOpts ... SaveOpt ) ( string , error ) {
config := new ( saveConfig )
for _ , fn := range saveOpts {
fn ( config )
}
if err := c . Validate ( ) ; err != nil {
return "" , errors . Wrap ( err , "chart validation" )
}
@ -141,14 +162,19 @@ func Save(c *chart.Chart, outDir string) (string, error) {
}
} ( )
if err := writeTarContents ( twriter , c , "" ) ; err != nil {
var timestamp time . Time
if ! config . noTimestamp {
timestamp = time . Now ( )
}
if err := writeTarContents ( twriter , c , "" , timestamp ) ; err != nil {
rollback = true
return filename , err
}
return filename , nil
}
func writeTarContents ( out * tar . Writer , c * chart . Chart , prefix string ) error {
func writeTarContents ( out * tar . Writer , c * chart . Chart , prefix string , timestamp time . Time ) error {
base := filepath . Join ( prefix , c . Name ( ) )
// Pull out the dependencies of a v1 Chart, since there's no way
@ -165,7 +191,7 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
if err != nil {
return err
}
if err := writeToTar ( out , filepath . Join ( base , ChartfileName ) , cdata ); err != nil {
if err := writeToTar ( out , filepath . Join ( base , ChartfileName ) , cdata , timestamp ); err != nil {
return err
}
@ -177,7 +203,7 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
if err != nil {
return err
}
if err := writeToTar ( out , filepath . Join ( base , "Chart.lock" ) , ldata ); err != nil {
if err := writeToTar ( out , filepath . Join ( base , "Chart.lock" ) , ldata , timestamp ); err != nil {
return err
}
}
@ -186,7 +212,7 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
// Save values.yaml
for _ , f := range c . Raw {
if f . Name == ValuesfileName {
if err := writeToTar ( out , filepath . Join ( base , ValuesfileName ) , f . Data ); err != nil {
if err := writeToTar ( out , filepath . Join ( base , ValuesfileName ) , f . Data , timestamp ); err != nil {
return err
}
}
@ -197,7 +223,7 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
if ! json . Valid ( c . Schema ) {
return errors . New ( "Invalid JSON in " + SchemafileName )
}
if err := writeToTar ( out , filepath . Join ( base , SchemafileName ) , c . Schema ); err != nil {
if err := writeToTar ( out , filepath . Join ( base , SchemafileName ) , c . Schema , timestamp ); err != nil {
return err
}
}
@ -205,7 +231,7 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
// Save templates
for _ , f := range c . Templates {
n := filepath . Join ( base , f . Name )
if err := writeToTar ( out , n , f . Data ); err != nil {
if err := writeToTar ( out , n , f . Data , timestamp ); err != nil {
return err
}
}
@ -213,14 +239,14 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
// Save files
for _ , f := range c . Files {
n := filepath . Join ( base , f . Name )
if err := writeToTar ( out , n , f . Data ); err != nil {
if err := writeToTar ( out , n , f . Data , timestamp ); err != nil {
return err
}
}
// Save dependencies
for _ , dep := range c . Dependencies ( ) {
if err := writeTarContents ( out , dep , filepath . Join ( base , ChartsDir ) ); err != nil {
if err := writeTarContents ( out , dep , filepath . Join ( base , ChartsDir ) , timestamp ); err != nil {
return err
}
}
@ -228,13 +254,13 @@ func writeTarContents(out *tar.Writer, c *chart.Chart, prefix string) error {
}
// writeToTar writes a single file to a tar archive.
func writeToTar ( out * tar . Writer , name string , body [ ] byte ) error {
func writeToTar ( out * tar . Writer , name string , body [ ] byte , timestamp time . Time ) error {
// TODO: Do we need to create dummy parent directory names if none exist?
h := & tar . Header {
Name : filepath . ToSlash ( name ) ,
Mode : 0644 ,
Size : int64 ( len ( body ) ) ,
ModTime : time . Now ( ) ,
ModTime : time stamp ,
}
if err := out . WriteHeader ( h ) ; err != nil {
return err