@@ -14,6 +14,7 @@ import (
1414 "os/exec"
1515 "path"
1616 "path/filepath"
17+ "slices"
1718 "strings"
1819 "time"
1920
@@ -43,24 +44,57 @@ func ParseCode(u string) (Code, bool) {
4344// Build builds the checktype defined in a directory. It builds the binary and
4445// the docker image of the checktype and returns the name of the docker image
4546// built.
46- func (c Code ) Build (logger log.Logger ) (string , error ) {
47- modified , err := c .isModified (logger )
47+ func (c Code ) Build (debug bool , logger log.Logger ) (string , error ) {
48+ modified , err := c .isModified (debug , logger )
4849 if err != nil {
4950 return "" , err
5051 }
5152 if ! modified {
52- logger .Infof ("No changes in checktype in dir %s, reusing image %s" , string (c ), c .imageName ())
53- return c .imageName (), nil
53+ logger .Infof ("No changes in checktype in dir %s, reusing image %s" , string (c ), c .imageName (debug ))
54+ return c .imageName (debug ), nil
5455 }
5556 logger .Infof ("Compiling checktype in dir %s" , c )
5657 dir := string (c )
5758 // Run go build in the checktype dir.
5859 if err := goBuildDir (dir ); err != nil {
5960 return "" , err
6061 }
62+ dockerfile := "Dockerfile"
63+
64+ // In case of debug, we need to add the delve debugger to the image.
65+ // We create a new Dockerfile with the necessary changes.
66+ // The original Dockerfile is kept in the dir but excluded from the Tar file.
67+ // The new Dockerfile is removed after the image is built.
68+ if debug {
69+ b , err := os .ReadFile (path .Join (dir , "Dockerfile" ))
70+ if err != nil {
71+ return "" , err
72+ }
73+ dockerfile = "Dockerfile.debug"
74+ add := fmt .Sprintf (`
75+ RUN apk add --no-cache go
76+ RUN go install github.com/go-delve/delve/cmd/dlv@latest
77+ EXPOSE 2345
78+ ENTRYPOINT /root/go/bin/dlv --listen=:2345 --headless=true --api-version=2 --log exec %s
79+ ` , filepath .Base (dir ))
80+
81+ b = append (b , []byte (add )... )
82+ if err := os .WriteFile (path .Join (dir , dockerfile ), b , 0644 ); err != nil {
83+ return "" , err
84+ }
85+ }
86+
87+ defer func () {
88+ if dockerfile != "Dockerfile" {
89+ if err := os .Remove (path .Join (dir , dockerfile )); err != nil {
90+ logger .Errorf ("error removing %s: %v" , dockerfile , err )
91+ }
92+ }
93+ }()
94+
6195 // Build a Tar file with the docker image contents.
6296 logger .Infof ("Building image for checktype in dir %s" , dir )
63- contents , err := buildTarFromDir (dir )
97+ contents , err := buildTarFromDir (dir , debug )
6498 if err != nil {
6599 return "" , err
66100 }
@@ -72,8 +106,8 @@ func (c Code) Build(logger log.Logger) (string, error) {
72106 t := modif .Format (time .RFC822 )
73107 logger .Debugf ("Last modified time for checktype in dir %s is %s" , dir , t )
74108 labels := map [string ]string {modifTimeLabel : t }
75- image := c .imageName ()
76- r , err := buildDockerdImage (contents , []string {image }, labels )
109+ image := c .imageName (debug )
110+ r , err := buildDockerdImage (contents , []string {image }, labels , dockerfile )
77111 if err != nil {
78112 return "" , err
79113 }
@@ -82,19 +116,19 @@ func (c Code) Build(logger log.Logger) (string, error) {
82116 return image , nil
83117}
84118
85- func (c Code ) isModified (logger log.Logger ) (bool , error ) {
86- labels , err := imageInfo (c .imageName ())
119+ func (c Code ) isModified (debug bool , logger log.Logger ) (bool , error ) {
120+ labels , err := imageInfo (c .imageName (debug ))
87121 if err != nil {
88122 return false , err
89123 }
90124 imageTimeS , ok := labels [modifTimeLabel ]
91125 if ! ok {
92- logger .Infof ("Image %s does not contain the label %s" , c .imageName (), modifTimeLabel )
126+ logger .Infof ("Image %s does not contain the label %s" , c .imageName (debug ), modifTimeLabel )
93127 return true , nil
94128 }
95129 _ , err = time .Parse (time .RFC822 , imageTimeS )
96130 if err != nil {
97- logger .Infof ("invalid time, %+w defined in the label %s of the image %s" , err , modifTimeLabel , c .imageName ())
131+ logger .Infof ("invalid time, %+w defined in the label %s of the image %s" , err , modifTimeLabel , c .imageName (debug ))
98132 return true , nil
99133 }
100134 dirTime , err := c .lastModified (logger )
@@ -142,14 +176,16 @@ func (c Code) lastModified(logger log.Logger) (time.Time, error) {
142176 return * latest , nil
143177}
144178
145- func (c Code ) imageName () string {
146- dir := string (c )
147- image := path .Base (dir )
148- return fmt .Sprintf ("%s-%s" , image , "local" )
179+ func (c Code ) imageName (debug bool ) string {
180+ base := path .Base (string (c ))
181+ if debug {
182+ return fmt .Sprintf ("%s-local-debug" , base )
183+ }
184+ return fmt .Sprintf ("%s-local" , base )
149185}
150186
151187func goBuildDir (dir string ) error {
152- args := []string {"build" , "-a " , "-ldflags" , "-extldflags -static " , "." }
188+ args := []string {"build" , "-gcflags " , "all=-N -l " , "." }
153189 cmd := exec .Command ("go" , args ... )
154190 cmd .Env = os .Environ ()
155191 cmd .Env = append (cmd .Env , "GOOS=linux" , "CGO_ENABLED=0" )
@@ -160,7 +196,7 @@ func goBuildDir(dir string) error {
160196 return cmd .Run ()
161197}
162198
163- func buildTarFromDir (dirPath string ) (* bytes.Buffer , error ) {
199+ func buildTarFromDir (dirPath string , excludeDockerfile bool ) (* bytes.Buffer , error ) {
164200 dir , err := os .Open (path .Clean (dirPath ))
165201 if err != nil {
166202 return nil , err
@@ -172,6 +208,9 @@ func buildTarFromDir(dirPath string) (*bytes.Buffer, error) {
172208 return nil , err
173209 }
174210
211+ if excludeDockerfile {
212+ files = slices .DeleteFunc (files , func (f fs.FileInfo ) bool { return f .Name () == "Dockerfile" })
213+ }
175214 var output bytes.Buffer
176215 tarfileWriter := tar .NewWriter (& output )
177216 defer tarfileWriter .Close () // nolint: errcheck
0 commit comments