From a3a3fc0681b2fe16de883148afb6460597ff5ce1 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Fri, 20 Apr 2018 15:37:05 -0700 Subject: [PATCH 1/7] Added CustomShell config --- build/builder.go | 2 +- configuration/config.go | 1 + main.go | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build/builder.go b/build/builder.go index f358bd2..2907480 100644 --- a/build/builder.go +++ b/build/builder.go @@ -701,7 +701,7 @@ func (b *Builder) createContainer(step *Step) (*docker.Container, error) { AttachStdin: false, AttachStderr: true, Image: b.uniqueStepName(step), - Cmd: []string{"/bin/bash"}, + Cmd: []string{b.Conf.CustomShell}, Tty: true, } diff --git a/configuration/config.go b/configuration/config.go index ecb0823..566807d 100644 --- a/configuration/config.go +++ b/configuration/config.go @@ -36,6 +36,7 @@ type Config struct { UseTLS bool UseStatForPermissions bool FroceRmImages bool + CustomShell string ApiPort int ApiBinding string SecretService bool diff --git a/main.go b/main.go index a0d8f6a..e3199b0 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,7 @@ func main() { flag.BoolVar(&config.NoSquash, "no-cleanup", false, "Skip cleanup commands for this run. Used for debugging") flag.BoolVar(&config.FroceRmImages, "force-rmi", false, "Force remove of unwanted images") flag.BoolVar(&config.NoPruneRmImages, "noprune-rmi", false, "No pruning of unwanted images") + flag.StringVar(&config.CustomShell, "shell", "/bin/bash", "Use custom shell binary to execute commands inside containers") flag.BoolVar(&flagShowHelp, "help", false, "Display the help") flag.BoolVar(&flagShowVersion, "version", false, "Display version information") flag.IntVar(&config.ApiPort, "port", 8080, "Port to server the API") From 316be17fa905040f78db02bbcedfe8c8e620a5c5 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Fri, 20 Apr 2018 18:27:54 -0700 Subject: [PATCH 2/7] Added -busybox switch to handle busybox/alpine containers --- build/builder.go | 17 +++++++++++++++-- configuration/config.go | 2 +- main.go | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/build/builder.go b/build/builder.go index 2907480..ddd13e6 100644 --- a/build/builder.go +++ b/build/builder.go @@ -430,14 +430,21 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { permMap := make(map[string]int) if b.Conf.UseStatForPermissions { for _, art := range step.Artifacts { + // Check for Busybox and modify the stat command + stat_cmd := []string{"stat", "--format='%a'", art.Source} + if b.Conf.UseBusybox { + stat_cmd = []string{"stat", "-c", "'%a'", art.Source} + } + execOpts := docker.CreateExecOptions{ Container: container.ID, AttachStdin: false, AttachStdout: true, AttachStderr: true, Tty: false, - Cmd: []string{"stat", "--format='%a'", art.Source}, + Cmd: stat_cmd, } + b.Conf.Logger.Debugf("Executing inside %s: %s", container.ID, execOpts.Cmd) execObj, err := b.docker.CreateExec(execOpts) if err != nil { return err @@ -503,6 +510,7 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { Tty: true, Cmd: strings.Split(step.Command, " "), } + b.Conf.Logger.Debugf("Executing inside %s: %s", container.ID, execOpts.Cmd) execObj, err := b.docker.CreateExec(execOpts) if err != nil { return err @@ -696,12 +704,17 @@ func (b *Builder) copyToHost(a *Artifact, container string, perms map[string]int } func (b *Builder) createContainer(step *Step) (*docker.Container, error) { + // check to see if we should run under a Busybox environment + shell := []string{"/bin/bash"} + if b.Conf.UseBusybox { + shell = []string{"/bin/sh"} + } config := docker.Config{ AttachStdout: true, AttachStdin: false, AttachStderr: true, Image: b.uniqueStepName(step), - Cmd: []string{b.Conf.CustomShell}, + Cmd: shell, Tty: true, } diff --git a/configuration/config.go b/configuration/config.go index 566807d..c67c3e3 100644 --- a/configuration/config.go +++ b/configuration/config.go @@ -36,7 +36,7 @@ type Config struct { UseTLS bool UseStatForPermissions bool FroceRmImages bool - CustomShell string + UseBusybox bool ApiPort int ApiBinding string SecretService bool diff --git a/main.go b/main.go index e3199b0..3150d7e 100644 --- a/main.go +++ b/main.go @@ -74,7 +74,7 @@ func main() { flag.BoolVar(&config.NoSquash, "no-cleanup", false, "Skip cleanup commands for this run. Used for debugging") flag.BoolVar(&config.FroceRmImages, "force-rmi", false, "Force remove of unwanted images") flag.BoolVar(&config.NoPruneRmImages, "noprune-rmi", false, "No pruning of unwanted images") - flag.StringVar(&config.CustomShell, "shell", "/bin/bash", "Use custom shell binary to execute commands inside containers") + flag.BoolVar(&config.UseBusybox, "busybox", false, "Make Habitat run compatible with busybox/Alpine") flag.BoolVar(&flagShowHelp, "help", false, "Display the help") flag.BoolVar(&flagShowVersion, "version", false, "Display version information") flag.IntVar(&config.ApiPort, "port", 8080, "Port to server the API") From 2fc910a3bb771b4d7a36842d48d218fc01602fc9 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Fri, 20 Apr 2018 18:35:45 -0700 Subject: [PATCH 3/7] Added -busybox switch to handle busybox/alpine containers --- build/builder.go | 17 +++++++++++++++-- configuration/config.go | 1 + main.go | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/build/builder.go b/build/builder.go index f358bd2..ddd13e6 100644 --- a/build/builder.go +++ b/build/builder.go @@ -430,14 +430,21 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { permMap := make(map[string]int) if b.Conf.UseStatForPermissions { for _, art := range step.Artifacts { + // Check for Busybox and modify the stat command + stat_cmd := []string{"stat", "--format='%a'", art.Source} + if b.Conf.UseBusybox { + stat_cmd = []string{"stat", "-c", "'%a'", art.Source} + } + execOpts := docker.CreateExecOptions{ Container: container.ID, AttachStdin: false, AttachStdout: true, AttachStderr: true, Tty: false, - Cmd: []string{"stat", "--format='%a'", art.Source}, + Cmd: stat_cmd, } + b.Conf.Logger.Debugf("Executing inside %s: %s", container.ID, execOpts.Cmd) execObj, err := b.docker.CreateExec(execOpts) if err != nil { return err @@ -503,6 +510,7 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { Tty: true, Cmd: strings.Split(step.Command, " "), } + b.Conf.Logger.Debugf("Executing inside %s: %s", container.ID, execOpts.Cmd) execObj, err := b.docker.CreateExec(execOpts) if err != nil { return err @@ -696,12 +704,17 @@ func (b *Builder) copyToHost(a *Artifact, container string, perms map[string]int } func (b *Builder) createContainer(step *Step) (*docker.Container, error) { + // check to see if we should run under a Busybox environment + shell := []string{"/bin/bash"} + if b.Conf.UseBusybox { + shell = []string{"/bin/sh"} + } config := docker.Config{ AttachStdout: true, AttachStdin: false, AttachStderr: true, Image: b.uniqueStepName(step), - Cmd: []string{"/bin/bash"}, + Cmd: shell, Tty: true, } diff --git a/configuration/config.go b/configuration/config.go index ecb0823..c67c3e3 100644 --- a/configuration/config.go +++ b/configuration/config.go @@ -36,6 +36,7 @@ type Config struct { UseTLS bool UseStatForPermissions bool FroceRmImages bool + UseBusybox bool ApiPort int ApiBinding string SecretService bool diff --git a/main.go b/main.go index a0d8f6a..3150d7e 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,7 @@ func main() { flag.BoolVar(&config.NoSquash, "no-cleanup", false, "Skip cleanup commands for this run. Used for debugging") flag.BoolVar(&config.FroceRmImages, "force-rmi", false, "Force remove of unwanted images") flag.BoolVar(&config.NoPruneRmImages, "noprune-rmi", false, "No pruning of unwanted images") + flag.BoolVar(&config.UseBusybox, "busybox", false, "Make Habitat run compatible with busybox/Alpine") flag.BoolVar(&flagShowHelp, "help", false, "Display the help") flag.BoolVar(&flagShowVersion, "version", false, "Display version information") flag.IntVar(&config.ApiPort, "port", 8080, "Port to server the API") From f71b014735d7dddd1bce178fe96fd05866785268 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Mon, 7 May 2018 12:22:27 -0700 Subject: [PATCH 4/7] Changed to use --os switch for OS selection --- build/builder.go | 25 ++++++++++++++++++------- configuration/config.go | 21 ++++++++++++++++++++- main.go | 8 +++++++- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/build/builder.go b/build/builder.go index ddd13e6..e7209ae 100644 --- a/build/builder.go +++ b/build/builder.go @@ -430,10 +430,15 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { permMap := make(map[string]int) if b.Conf.UseStatForPermissions { for _, art := range step.Artifacts { - // Check for Busybox and modify the stat command - stat_cmd := []string{"stat", "--format='%a'", art.Source} - if b.Conf.UseBusybox { - stat_cmd = []string{"stat", "-c", "'%a'", art.Source} + // Define stat command for debian and override if told to use another OS + statCmd := []string{"stat", "--format='%a'", art.Source} + switch b.Conf.OsType { + case "redhat": + statCmd = []string{"stat", "--format='%a'", art.Source} + case "busybox": + statCmd = []string{"stat", "-c", "'%a'", art.Source} + case "alpine": + statCmd = []string{"stat", "-c", "'%a'", art.Source} } execOpts := docker.CreateExecOptions{ @@ -442,7 +447,7 @@ func (b *Builder) BuildStep(step *Step, step_number int) error { AttachStdout: true, AttachStderr: true, Tty: false, - Cmd: stat_cmd, + Cmd: statCmd, } b.Conf.Logger.Debugf("Executing inside %s: %s", container.ID, execOpts.Cmd) execObj, err := b.docker.CreateExec(execOpts) @@ -704,11 +709,17 @@ func (b *Builder) copyToHost(a *Artifact, container string, perms map[string]int } func (b *Builder) createContainer(step *Step) (*docker.Container, error) { - // check to see if we should run under a Busybox environment + // Define shell for debian and override if another OS is specified shell := []string{"/bin/bash"} - if b.Conf.UseBusybox { + switch b.Conf.OsType { + case "redhat": + shell = []string{"/bin/bash"} + case "busybox": + shell = []string{"/bin/sh"} + case "alpine": shell = []string{"/bin/sh"} } + config := docker.Config{ AttachStdout: true, AttachStdin: false, diff --git a/configuration/config.go b/configuration/config.go index c67c3e3..05f282c 100644 --- a/configuration/config.go +++ b/configuration/config.go @@ -14,6 +14,14 @@ type TupleItem struct { type TupleArray []TupleItem +type OsIdentifier int +const ( + debian OsIdentifier = iota + 1 + redhat + busybox + alpine +) + // Config stores application configurations type Config struct { Buildfile string @@ -36,7 +44,7 @@ type Config struct { UseTLS bool UseStatForPermissions bool FroceRmImages bool - UseBusybox bool + OsType string ApiPort int ApiBinding string SecretService bool @@ -80,3 +88,14 @@ func (i *TupleArray) Find(key string) string { func CreateConfig() Config { return Config{} } + +func ValidateOsType(text string) bool { + osTypes := []string{"debian", "redhat", "busybox", "alpine"} + + for _, os := range(osTypes) { + if text == os { + return true + } + } + return false +} \ No newline at end of file diff --git a/main.go b/main.go index 3150d7e..8c1aaab 100644 --- a/main.go +++ b/main.go @@ -74,7 +74,7 @@ func main() { flag.BoolVar(&config.NoSquash, "no-cleanup", false, "Skip cleanup commands for this run. Used for debugging") flag.BoolVar(&config.FroceRmImages, "force-rmi", false, "Force remove of unwanted images") flag.BoolVar(&config.NoPruneRmImages, "noprune-rmi", false, "No pruning of unwanted images") - flag.BoolVar(&config.UseBusybox, "busybox", false, "Make Habitat run compatible with busybox/Alpine") + flag.StringVar(&config.OsType, "os", "debian", "Specify the OS that the build occurs in") flag.BoolVar(&flagShowHelp, "help", false, "Display the help") flag.BoolVar(&flagShowVersion, "version", false, "Display version information") flag.IntVar(&config.ApiPort, "port", 8080, "Port to server the API") @@ -112,6 +112,12 @@ func main() { return } + // The -os flag allows free form text. Validate what was specified + if !config.ValidateOsType(config.OsType) { + fmt.Println("Invalid OS name") + return + } + level, err := logging.LogLevel(flagLevel) if err != nil { fmt.Println("Invalid log level value. Falling back to debug") From a8b141f1f58d72eb7ef22c0a9b804deea63f33ce Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Sun, 5 Aug 2018 18:55:49 -0700 Subject: [PATCH 5/7] Added test code for configuration code changes --- build.yml | 2 +- configuration/config_test.go | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 configuration/config_test.go diff --git a/build.yml b/build.yml index 043d8b8..67b485b 100644 --- a/build.yml +++ b/build.yml @@ -5,7 +5,7 @@ build: tester: name: tester dockerfile: Dockerfile.tester - command: go test + command: go test . ./configuration crosscompile: name: crosscompile depends_on: diff --git a/configuration/config_test.go b/configuration/config_test.go new file mode 100644 index 0000000..9dcf008 --- /dev/null +++ b/configuration/config_test.go @@ -0,0 +1,50 @@ +package configuration_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "testing" + "github.com/cloud66/habitus/configuration" +) + +var _ = Describe("Config", func() { + var c configuration.Config + + BeforeEach(func() { + c = configuration.CreateConfig() + }) + + Describe("--os allowed values", func() { + It("should accept debian", func() { + c.OsType = "debian" + Expect(c.ValidateOsType()).To(Equal(true)) + }) + + It("should accept redhat", func() { + c.OsType = "redhat" + Expect(c.ValidateOsType()).To(Equal(true)) + }) + + It("should accept alpine", func() { + c.OsType = "alpine" + Expect(c.ValidateOsType()).To(Equal(true)) + }) + + It("should accept busybox", func() { + c.OsType = "busybox" + Expect(c.ValidateOsType()).To(Equal(true)) + }) + + It("should not accept msdos", func() { + c.OsType = "msdos" + Expect(c.ValidateOsType()).To(Equal(false)) + }) + }) + +}) + + +func ConfigTest(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Habitus Config Suite") +} From 3be3698af56fd271276275690e1488f2d54c89f0 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Sun, 5 Aug 2018 20:43:20 -0700 Subject: [PATCH 6/7] Checking for valid options for --os --- configuration/config.go | 25 ++++++++++++------------- main.go | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/configuration/config.go b/configuration/config.go index 05f282c..4c42e2a 100644 --- a/configuration/config.go +++ b/configuration/config.go @@ -14,13 +14,14 @@ type TupleItem struct { type TupleArray []TupleItem -type OsIdentifier int -const ( - debian OsIdentifier = iota + 1 - redhat - busybox - alpine -) +// Recognized OS type for --os switch. +// Needs to agree with builder.go +var OsTypes = []string{ + "debian", + "redhat", + "busybox", + "alpine", +} // Config stores application configurations type Config struct { @@ -89,13 +90,11 @@ func CreateConfig() Config { return Config{} } -func ValidateOsType(text string) bool { - osTypes := []string{"debian", "redhat", "busybox", "alpine"} - - for _, os := range(osTypes) { - if text == os { +func (c *Config) ValidateOsType() bool { + for _, os := range OsTypes { + if c.OsType == os { return true } } return false -} \ No newline at end of file +} diff --git a/main.go b/main.go index 8c1aaab..09552fb 100644 --- a/main.go +++ b/main.go @@ -113,7 +113,7 @@ func main() { } // The -os flag allows free form text. Validate what was specified - if !config.ValidateOsType(config.OsType) { + if !config.ValidateOsType() { fmt.Println("Invalid OS name") return } From d5169793b22105319539f839883aee2fd5ab8563 Mon Sep 17 00:00:00 2001 From: Gerard Hickey Date: Sun, 5 Aug 2018 21:07:06 -0700 Subject: [PATCH 7/7] Added list of supported OSes when invalid one is given --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 09552fb..47981c9 100644 --- a/main.go +++ b/main.go @@ -115,6 +115,7 @@ func main() { // The -os flag allows free form text. Validate what was specified if !config.ValidateOsType() { fmt.Println("Invalid OS name") + fmt.Println("Please choose from ", configuration.OsTypes) return }