func (i *integrationTest) exerciseInjectionBuild(tag, imageName string, injections []string) { t := i.t err := os.Mkdir("/tmp/s2i-test-dir", 0777) if err != nil { t.Errorf("Unable to create temporary directory: %v", err) } defer os.RemoveAll("/tmp/s2i-test-dir") err = ioutil.WriteFile(filepath.Join("/tmp/s2i-test-dir/secret"), []byte("secret"), 0666) if err != nil { t.Errorf("Unable to write content to temporary injection file: %v", err) } injectionList := api.VolumeList{} for _, i := range injections { injectionList.Set(i) } config := &api.Config{ DockerConfig: docker.GetDefaultDockerConfig(), BuilderImage: imageName, BuilderPullPolicy: api.DefaultBuilderPullPolicy, Source: TestSource, Tag: tag, Injections: injectionList, } builder, _, err := strategies.GetStrategy(config) if err != nil { t.Fatalf("Unable to create builder: %v", err) } resp, err := builder.Build(config) if err != nil { t.Fatalf("Unexpected error occurred during build: %v", err) } if !resp.Success { t.Fatalf("S2I build failed.") } i.checkForImage(tag) containerID := i.createContainer(tag) defer i.removeContainer(containerID) // Check that the injected file is delivered to assemble script i.fileExists(containerID, "/sti-fake/secret-delivered") i.fileExists(containerID, "/sti-fake/relative-secret-delivered") // Make sure the injected file does not exists in resulting image files, err := util.ExpandInjectedFiles(injectionList) if err != nil { t.Errorf("Unexpected error: %v", err) } for _, f := range files { if exitCode := i.runInImage(tag, "test -s "+f); exitCode == 0 { t.Errorf("The file must be empty: %q, we got %q", f, err) } } }
func main() { rand.Seed(time.Now().UnixNano()) // Applying partial glog flag initialization workaround from: https://github.com/kubernetes/kubernetes/issues/17162 // Without this fake command line parse, glog will compain its flags have not been interpreted flag.CommandLine.Parse([]string{}) cfg := &api.Config{} s2iCmd := &cobra.Command{ Use: "s2i", Long: "Source-to-image (S2I) is a tool for building repeatable docker images.\n\n" + "A command line interface that injects and assembles source code into a docker image.\n" + "Complete documentation is available at http://github.com/openshift/source-to-image", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } cfg.DockerConfig = docker.GetDefaultDockerConfig() s2iCmd.PersistentFlags().StringVarP(&(cfg.DockerConfig.Endpoint), "url", "U", cfg.DockerConfig.Endpoint, "Set the url of the docker socket to use") s2iCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.CertFile), "cert", cfg.DockerConfig.CertFile, "Set the path of the docker TLS certificate file") s2iCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.KeyFile), "key", cfg.DockerConfig.KeyFile, "Set the path of the docker TLS key file") s2iCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.CAFile), "ca", cfg.DockerConfig.CAFile, "Set the path of the docker TLS ca file") s2iCmd.PersistentFlags().BoolVar(&(cfg.DockerConfig.UseTLS), "tls", cfg.DockerConfig.UseTLS, "Use TLS to connect to docker; implied by --tlsverify") s2iCmd.PersistentFlags().BoolVar(&(cfg.DockerConfig.TLSVerify), "tlsverify", cfg.DockerConfig.TLSVerify, "Use TLS to connect to docker and verify the remote") s2iCmd.AddCommand(newCmdVersion()) s2iCmd.AddCommand(newCmdBuild(cfg)) s2iCmd.AddCommand(newCmdRebuild(cfg)) s2iCmd.AddCommand(newCmdUsage(cfg)) s2iCmd.AddCommand(newCmdCreate()) setupGlog(s2iCmd.PersistentFlags()) basename := filepath.Base(os.Args[0]) // Make case-insensitive and strip executable suffix if present if runtime.GOOS == "windows" { basename = strings.ToLower(basename) basename = strings.TrimSuffix(basename, ".exe") } if basename == "sti" { glog.Warning("sti binary is deprecated, use s2i instead") } s2iCmd.AddCommand(newCmdGenBashCompletion(s2iCmd)) err := s2iCmd.Execute() if err != nil { os.Exit(1) } }
// setup sets up integration tests func (i *integrationTest) setup() { var err error i.engineClient, err = docker.NewEngineAPIClient(docker.GetDefaultDockerConfig()) if err != nil { i.t.Errorf("%+v", err) return } if !i.setupComplete { // get the full path to this .go file so we can construct the file url // using this file's dirname _, filename, _, _ := runtime.Caller(0) testImagesDir := filepath.Join(filepath.Dir(filename), "scripts") FakeScriptsFileURL = "file://" + filepath.Join(testImagesDir, ".s2i", "bin") for _, image := range []string{TagCleanBuild, TagCleanBuildUser, TagIncrementalBuild, TagIncrementalBuildUser} { ctx, cancel := getDefaultContext() i.engineClient.ImageRemove(ctx, image, dockertypes.ImageRemoveOptions{}) cancel() } go http.ListenAndServe(":23456", http.FileServer(http.Dir(testImagesDir))) if err := waitForHTTPReady(); err != nil { i.t.Fatalf("Unexpected error: %v", err) } i.setupComplete = true } from := flag.CommandLine if vflag := from.Lookup("v"); vflag != nil { // the thing here is that we are looking for the bash -v passed into test-integration.sh (with no value), // but for glog (https://github.com/golang/glog/blob/master/glog.go), one specifies // the logging level with -v=# (i.e. -v=0 or -v=3 or -v=5). // so, for the changes stemming from issue 133, we 'reuse' the bash -v, and set the highest glog level. // (if you look at STI's main.go, and setupGlog, it essentially maps glog's -v to --loglevel for use by the sti command) //NOTE - passing --loglevel or -v=5 into test-integration.sh does not work if getLogLevel() != 5 { vflag.Value.Set("5") // FIXME currently glog has only option to redirect output to stderr // the preferred for STI would be to redirect to stdout flag.CommandLine.Set("logtostderr", "true") } } }
func (i *integrationTest) exerciseCleanAllowedUIDsBuild(tag, imageName string, expectError bool) { t := i.t config := &api.Config{ DockerConfig: docker.GetDefaultDockerConfig(), BuilderImage: imageName, BuilderPullPolicy: api.DefaultBuilderPullPolicy, Source: TestSource, Tag: tag, Incremental: false, ScriptsURL: "", } config.AllowedUIDs.Set("1-") _, _, err := strategies.GetStrategy(config) if err != nil && !expectError { t.Fatalf("Cannot create a new builder: %v", err) } if err == nil && expectError { t.Fatalf("Did not get an error and was expecting one.") } }
func main() { cfg := &api.Config{} stiCmd := &cobra.Command{ Use: "s2i", Long: "Source-to-image (S2I) is a tool for building repeatable docker images.\n\n" + "A command line interface that injects and assembles source code into a docker image.\n" + "Complete documentation is available at http://github.com/openshift/source-to-image", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } cfg.DockerConfig = docker.GetDefaultDockerConfig() stiCmd.PersistentFlags().StringVarP(&(cfg.DockerConfig.Endpoint), "url", "U", cfg.DockerConfig.Endpoint, "Set the url of the docker socket to use") stiCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.CertFile), "cert", cfg.DockerConfig.CertFile, "Set the path of the docker TLS certificate file") stiCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.KeyFile), "key", cfg.DockerConfig.KeyFile, "Set the path of the docker TLS key file") stiCmd.PersistentFlags().StringVar(&(cfg.DockerConfig.CAFile), "ca", cfg.DockerConfig.CAFile, "Set the path of the docker TLS ca file") stiCmd.AddCommand(newCmdVersion()) stiCmd.AddCommand(newCmdBuild(cfg)) stiCmd.AddCommand(newCmdRebuild(cfg)) stiCmd.AddCommand(newCmdUsage(cfg)) stiCmd.AddCommand(newCmdCreate()) setupGlog(stiCmd.PersistentFlags()) basename := filepath.Base(os.Args[0]) // Make case-insensitive and strip executable suffix if present if runtime.GOOS == "windows" { basename = strings.ToLower(basename) basename = strings.TrimSuffix(basename, ".exe") } if basename == "sti" { glog.Warning("sti binary is deprecated, use s2i instead") } stiCmd.AddCommand(newCmdGenBashCompletion(stiCmd)) err := stiCmd.Execute() if err != nil { os.Exit(1) } }
func (i *integrationTest) exerciseIncrementalBuild(tag, imageName string, removePreviousImage bool, expectClean bool, checkOnBuild bool) { t := i.t config := &api.Config{ DockerConfig: docker.GetDefaultDockerConfig(), BuilderImage: imageName, BuilderPullPolicy: api.DefaultBuilderPullPolicy, Source: TestSource, Tag: tag, Incremental: false, RemovePreviousImage: removePreviousImage, } builder, _, err := strategies.GetStrategy(config) if err != nil { t.Fatalf("Unable to create builder: %v", err) } resp, err := builder.Build(config) if err != nil { t.Fatalf("Unexpected error occurred during build: %v", err) } if !resp.Success { t.Fatalf("S2I build failed.") } previousImageID := resp.ImageID config = &api.Config{ DockerConfig: docker.GetDefaultDockerConfig(), BuilderImage: imageName, BuilderPullPolicy: api.DefaultBuilderPullPolicy, Source: TestSource, Tag: tag, Incremental: true, RemovePreviousImage: removePreviousImage, PreviousImagePullPolicy: api.PullIfNotPresent, } builder, _, err = strategies.GetStrategy(config) if err != nil { t.Fatalf("Unable to create incremental builder: %v", err) } resp, err = builder.Build(config) if err != nil { t.Fatalf("Unexpected error occurred during incremental build: %v", err) } if !resp.Success { t.Fatalf("S2I incremental build failed.") } i.checkForImage(tag) containerID := i.createContainer(tag) defer i.removeContainer(containerID) i.checkIncrementalBuildState(containerID, resp.WorkingDir, expectClean) _, err = i.InspectImage(previousImageID) if removePreviousImage { if err == nil { t.Errorf("Previous image %s not deleted", previousImageID) } } else { if err != nil { t.Errorf("Couldn't find previous image %s", previousImageID) } } if checkOnBuild { i.fileExists(containerID, "/sti-fake/src/onbuild") } }
func (i *integrationTest) exerciseCleanBuild(tag string, verifyCallback bool, imageName string, scriptsURL string, expectImageName bool, setTag bool) { t := i.t callbackURL := "" callbackInvoked := false callbackHasValidJSON := false if verifyCallback { handler := func(w http.ResponseWriter, r *http.Request) { // we got called callbackInvoked = true // the header is as expected contentType := r.Header["Content-Type"][0] callbackHasValidJSON = contentType == "application/json" // the request body is as expected if callbackHasValidJSON { defer r.Body.Close() body, _ := ioutil.ReadAll(r.Body) type CallbackMessage struct { Payload string Success bool } var callbackMessage CallbackMessage err := json.Unmarshal(body, &callbackMessage) callbackHasValidJSON = (err == nil) && (callbackMessage.Success) } } ts := httptest.NewServer(http.HandlerFunc(handler)) defer ts.Close() callbackURL = ts.URL } var buildTag string if setTag { buildTag = tag } else { buildTag = "" } config := &api.Config{ DockerConfig: docker.GetDefaultDockerConfig(), BuilderImage: imageName, BuilderPullPolicy: api.DefaultBuilderPullPolicy, Source: TestSource, Tag: buildTag, Incremental: false, CallbackURL: callbackURL, ScriptsURL: scriptsURL} b, _, err := strategies.GetStrategy(config) if err != nil { t.Fatalf("Cannot create a new builder.") } resp, err := b.Build(config) if err != nil { t.Fatalf("An error occurred during the build: %v", err) } else if !resp.Success { t.Fatalf("The build failed.") } if callbackInvoked != verifyCallback { t.Fatalf("S2I build did not invoke callback") } if callbackHasValidJSON != verifyCallback { t.Fatalf("S2I build did not invoke callback with valid json message") } // We restrict this check to only when we are passing tag through the build config // since we will not end up with an available tag by that name from build if setTag { i.checkForImage(tag) containerID := i.createContainer(tag) defer i.removeContainer(containerID) i.checkBasicBuildState(containerID, resp.WorkingDir) } // Check if we receive back an ImageID when we are expecting to if expectImageName && len(resp.ImageID) == 0 { t.Fatalf("S2I build did not receive an ImageID in response") } if !expectImageName && len(resp.ImageID) > 0 { t.Fatalf("S2I build received an ImageID in response") } }