github.com/openshift/source-to-image@v1.4.1-0.20240516041539-bf52fc02204e/pkg/api/describe/describer.go (about) 1 package describe 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os" 8 "runtime" 9 "strings" 10 "text/tabwriter" 11 12 "github.com/openshift/source-to-image/pkg/api" 13 "github.com/openshift/source-to-image/pkg/build" 14 "github.com/openshift/source-to-image/pkg/docker" 15 ) 16 17 // Config returns the Config object in nice readable, tabbed format. 18 func Config(client docker.Client, config *api.Config) string { 19 out, err := tabbedString(func(out io.Writer) error { 20 if len(config.DisplayName) > 0 { 21 fmt.Fprintf(out, "Application Name:\t%s\n", config.DisplayName) 22 } 23 if len(config.Description) > 0 { 24 fmt.Fprintf(out, "Description:\t%s\n", config.Description) 25 } 26 if len(config.AsDockerfile) == 0 { 27 describeBuilderImage(client, config, out) 28 describeRuntimeImage(config, out) 29 } 30 fmt.Fprintf(out, "Source:\t%s\n", config.Source) 31 if len(config.ContextDir) > 0 { 32 fmt.Fprintf(out, "Context Directory:\t%s\n", config.ContextDir) 33 } 34 fmt.Fprintf(out, "Output Image Tag:\t%s\n", config.Tag) 35 printEnv(out, config.Environment) 36 if len(config.EnvironmentFile) > 0 { 37 fmt.Fprintf(out, "Environment File:\t%s\n", config.EnvironmentFile) 38 } 39 printLabels(out, config.Labels) 40 fmt.Fprintf(out, "Incremental Build:\t%s\n", printBool(config.Incremental)) 41 if config.Incremental { 42 fmt.Fprintf(out, "Incremental Image Pull User:\t%s\n", config.IncrementalAuthentication.Username) 43 } 44 fmt.Fprintf(out, "Remove Old Build:\t%s\n", printBool(config.RemovePreviousImage)) 45 fmt.Fprintf(out, "Builder Pull Policy:\t%s\n", config.BuilderPullPolicy) 46 fmt.Fprintf(out, "Previous Image Pull Policy:\t%s\n", config.PreviousImagePullPolicy) 47 fmt.Fprintf(out, "Quiet:\t%s\n", printBool(config.Quiet)) 48 fmt.Fprintf(out, "Layered Build:\t%s\n", printBool(config.LayeredBuild)) 49 if len(config.Destination) > 0 { 50 fmt.Fprintf(out, "Artifacts Destination:\t%s\n", config.Destination) 51 } 52 if len(config.CallbackURL) > 0 { 53 fmt.Fprintf(out, "Callback URL:\t%s\n", config.CallbackURL) 54 } 55 if len(config.ScriptsURL) > 0 { 56 fmt.Fprintf(out, "S2I Scripts URL:\t%s\n", config.ScriptsURL) 57 } 58 if len(config.WorkingDir) > 0 { 59 fmt.Fprintf(out, "Workdir:\t%s\n", config.WorkingDir) 60 } 61 if config.DockerNetworkMode != "" { 62 fmt.Fprintf(out, "Docker NetworkMode:\t%s\n", config.DockerNetworkMode) 63 } 64 fmt.Fprintf(out, "Docker Endpoint:\t%s\n", config.DockerConfig.Endpoint) 65 66 if _, err := os.Open(config.DockerCfgPath); err == nil { 67 fmt.Fprintf(out, "Docker Pull Config:\t%s\n", config.DockerCfgPath) 68 fmt.Fprintf(out, "Docker Pull User:\t%s\n", config.PullAuthentication.Username) 69 } 70 71 if len(config.Injections) > 0 { 72 result := []string{} 73 for _, i := range config.Injections { 74 result = append(result, fmt.Sprintf("%s->%s", i.Source, i.Destination)) 75 } 76 fmt.Fprintf(out, "Injections:\t%s\n", strings.Join(result, ",")) 77 } 78 if len(config.BuildVolumes) > 0 { 79 result := []string{} 80 for _, i := range config.BuildVolumes { 81 if runtime.GOOS == "windows" { 82 // We need to avoid the colon in the Windows drive letter 83 result = append(result, i[0:2]+strings.Replace(i[3:], ":", "->", 1)) 84 } else { 85 result = append(result, strings.Replace(i, ":", "->", 1)) 86 } 87 } 88 fmt.Fprintf(out, "Bind mounts:\t%s\n", strings.Join(result, ",")) 89 } 90 return nil 91 }) 92 93 if err != nil { 94 fmt.Printf("error: %v", err) 95 } 96 return out 97 } 98 99 func describeBuilderImage(client docker.Client, config *api.Config, out io.Writer) { 100 c := &api.Config{ 101 DockerConfig: config.DockerConfig, 102 PullAuthentication: config.PullAuthentication, 103 BuilderImage: config.BuilderImage, 104 BuilderPullPolicy: config.BuilderPullPolicy, 105 Tag: config.Tag, 106 IncrementalAuthentication: config.IncrementalAuthentication, 107 } 108 dkr := docker.New(client, c.PullAuthentication) 109 builderImage, err := docker.GetBuilderImage(dkr, c) 110 if err == nil { 111 build.GenerateConfigFromLabels(c, builderImage) 112 if len(c.DisplayName) > 0 { 113 fmt.Fprintf(out, "Builder Name:\t%s\n", c.DisplayName) 114 } 115 fmt.Fprintf(out, "Builder Image:\t%s\n", c.BuilderImage) 116 if len(c.BuilderImageVersion) > 0 { 117 fmt.Fprintf(out, "Builder Image Version:\t%s\n", c.BuilderImageVersion) 118 } 119 if len(c.BuilderBaseImageVersion) > 0 { 120 fmt.Fprintf(out, "Builder Base Version:\t%s\n", c.BuilderBaseImageVersion) 121 } 122 } else { 123 fmt.Fprintf(out, "Error describing image:\t%s\n", err.Error()) 124 } 125 } 126 127 func describeRuntimeImage(config *api.Config, out io.Writer) { 128 if len(config.RuntimeImage) == 0 { 129 return 130 } 131 132 fmt.Fprintf(out, "Runtime Image:\t%s\n", config.RuntimeImage) 133 fmt.Fprintf(out, "Runtime Image Pull Policy:\t%s\n", config.RuntimeImagePullPolicy) 134 if len(config.RuntimeAuthentication.Username) > 0 { 135 fmt.Fprintf(out, "Runtime Image Pull User:\t%s\n", config.RuntimeAuthentication.Username) 136 } 137 } 138 139 func printEnv(out io.Writer, env api.EnvironmentList) { 140 result := []string{} 141 for _, e := range env { 142 result = append(result, strings.Join([]string{e.Name, e.Value}, "=")) 143 } 144 fmt.Fprintf(out, "Environment:\t%s\n", strings.Join(result, ",")) 145 } 146 147 func printLabels(out io.Writer, labels map[string]string) { 148 result := []string{} 149 for k, v := range labels { 150 result = append(result, fmt.Sprintf("%s=%q", k, v)) 151 } 152 fmt.Fprintf(out, "Labels:\t%s\n", strings.Join(result, ",")) 153 } 154 155 func printBool(b bool) string { 156 if b { 157 return "\033[1menabled\033[0m" 158 } 159 return "disabled" 160 } 161 162 func tabbedString(f func(io.Writer) error) (string, error) { 163 out := new(tabwriter.Writer) 164 buf := &bytes.Buffer{} 165 out.Init(buf, 0, 8, 1, '\t', 0) 166 167 err := f(out) 168 if err != nil { 169 return "", err 170 } 171 172 out.Flush() 173 str := string(buf.String()) 174 return str, nil 175 }