2021-02-12 11:20:11 +00:00
package main
import (
"flag"
"fmt"
"io"
"log"
"os"
"github.com/pkg/errors"
"github.com/tinkerbell/sandbox/cmd/bump-version/envfile"
"github.com/tinkerbell/sandbox/cmd/bump-version/git"
"github.com/tinkerbell/sandbox/cmd/bump-version/image"
)
// Config represents the flags that you can configure
// when running bump-version
type Config struct {
// CurrentVersionFile is the path of the envfile that
// contains the current version of Tinkerbell stack.
// In sandbod it is called current_versions.sh
CurrentVersionFile string
// Overwrite switched the output of this program from
// standard output to the current_versions.sh file.
Overwrite bool
// Help prints the help command and exists
Help bool
}
const help = `
bump - version is an utility that reads and update the current_version . sh file .
It is designed to be used in CI / CD but it works locally as well .
Note :
* Osie is currently not supported
Examples :
Prints this - help
$ bump - version - help
This is how you will normally run this command .
bump - version will read the specified current - version - file
( . / current_version . sh ) , it will clone the various components in memory
checking the latest commit available in the default branch .
The command will get and validate that a docker image is available for each
component and it will print the updated current_version . sh to stdout .
$ bump - version - current - version - file . / current_versions . sh
This command does the same as the previous one but it overwrite the content
of the original current_version file
$ bump - version - overwrite
`
const headerFile = ` # ! / bin / bash
# This file is generated by an utility called bump - version in
# tinkerbell / sandbox .
2021-04-16 16:51:10 +00:00
# This file gets used from generate - env . sh but it is also used standalone by
2021-02-12 11:20:11 +00:00
# automation that wants to get the version of the programs currently supported
# in sandbox
`
func main ( ) {
config := Config { }
fs := flag . NewFlagSet ( "bump-version" , flag . ContinueOnError )
fs . BoolVar ( & config . Help , "help" , false , "Display help command and exit" )
fs . BoolVar ( & config . Overwrite , "overwrite" , false , "This commands overwrite the current_versions file instead of printing to stdout" )
fs . StringVar ( & config . CurrentVersionFile , "current-version-file" , "./current_versions.sh" , "Load the current_version.sh file where the current Tinkerbell component versions are specified." )
err := fs . Parse ( os . Args [ 1 : ] )
if err != nil {
fmt . Fprint ( os . Stderr , help )
log . Fatalf ( "Err: %s\n\r" , err . Error ( ) )
}
if config . Help {
fmt . Fprint ( os . Stderr , help )
os . Exit ( 0 )
}
// Read the current_versions envfile
myEnv , err := envfile . ReadEnvFile ( config . CurrentVersionFile )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Impossible to read current_file.sh" ) )
}
tag , err := getImageTagFromRepo ( "https://github.com/tinkerbell/tink" )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Impossible to get image tag from tinkerbell/tink repo" ) )
}
// Set the new versions to the current_versions.sh
myEnv [ "TINKERBELL_TINK_SERVER_IMAGE" ] = "quay.io/tinkerbell/tink:" + tag
myEnv [ "TINKERBELL_TINK_WORKER_IMAGE" ] = "quay.io/tinkerbell/tink-worker:" + tag
myEnv [ "TINKERBELL_TINK_CLI_IMAGE" ] = "quay.io/tinkerbell/tink-cli:" + tag
tag , err = getImageTagFromRepo ( "https://github.com/tinkerbell/hegel" )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Impossible to get image tag from tinkerbell/hegel repo" ) )
}
myEnv [ "TINKERBELL_TINK_HEGEL_IMAGE" ] = "quay.io/tinkerbell/hegel:" + tag
tag , err = getImageTagFromRepo ( "https://github.com/tinkerbell/boots" )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Impossible to get image tag from tinkerbell/hegel repo" ) )
}
myEnv [ "TINKERBELL_TINK_BOOTS_IMAGE" ] = "quay.io/tinkerbell/boots:" + tag
out , err := envfile . Marshal ( myEnv )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Impossible to render new current_version envfile" ) )
}
destination := os . Stdout
// if the overwrite flag is set to true change the output of the command
// from stdout to the original file
if config . Overwrite {
f , err := os . OpenFile ( config . CurrentVersionFile , os . O_WRONLY | os . O_TRUNC , 0 )
if err != nil {
log . Fatal ( errors . Wrap ( err , "Error overwriting current versions envfile" ) )
}
destination = f
}
io . WriteString ( destination , headerFile + out + "\n" )
}
// getImageTagFromRepo is an utility function that wraps a couple of things
// together that technically we need to repeat for each repo.
func getImageTagFromRepo ( repoName string ) ( string , error ) {
// Clone the specified repository in memory
repo , err := git . Clone ( repoName )
if err != nil {
return "" , errors . Wrap ( err , "Impossible to clone the repository" )
}
// Get the latest commit from the defautl branch
latestCommit , err := repo . GetHeadHash ( )
if err != nil {
return "" , errors . Wrap ( err , "Impossible to get commit from HEAD" )
}
// Calculate the image tag from a commit sha
tag , err := image . TagFromSha ( latestCommit )
if err != nil {
return "" , errors . Wrap ( err , "Impossible to get image tag from commit" )
}
return tag , nil
}