Skip to content

Commit 60ca33c

Browse files
mojtaba-eskMSevey
andauthored
make k8s the default builder (#541)
* merge main into it * chore: refactored read file from image to use k8s instead of docker * chore: cleanup * filx: linter complain * Update pkg/container/docker.go Co-authored-by: Matthew Sevey <15232757+MSevey@users.noreply.github.com> * chore: merge fix conflicts * fix: remove duplicate test parallel * fix: set state after building image * fix: put the set git repo out of retry loop --------- Co-authored-by: Matthew Sevey <15232757+MSevey@users.noreply.github.com>
1 parent 224383d commit 60ca33c

6 files changed

Lines changed: 102 additions & 140 deletions

File tree

e2e/system/build_from_git_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,12 @@ func (s *Suite) TestBuildFromGitWithModifications() {
6565
s.Require().NoError(err)
6666

6767
s.T().Log("Setting git repo")
68-
err = s.RetryOperation(func() error {
69-
return target.Build().SetGitRepo(ctx, builder.GitContext{
70-
Repo: gitRepo,
71-
Branch: gitBranch,
72-
Username: "",
73-
Password: "",
74-
})
75-
}, maxRetries)
68+
err = target.Build().SetGitRepo(ctx, builder.GitContext{
69+
Repo: gitRepo,
70+
Branch: gitBranch,
71+
Username: "",
72+
Password: "",
73+
})
7674
s.Require().NoError(err)
7775

7876
s.Require().NoError(target.Build().SetStartCommand("sleep", "infinity"))

e2e/system/file_test.go

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,11 @@ func (s *Suite) TestDownloadFileFromRunningInstance() {
7474
namePrefix = "download-file-running"
7575
)
7676

77-
// Setup
78-
7977
target, err := s.Knuu.NewInstance(namePrefix + "-target")
8078
s.Require().NoError(err)
8179

8280
ctx := context.Background()
83-
s.Require().NoError(target.Build().SetImage(ctx, "alpine:latest"))
81+
s.Require().NoError(target.Build().SetImage(ctx, alpineImage))
8482
s.Require().NoError(target.Build().SetArgs("tail", "-f", "/dev/null")) // Keep the container running
8583
s.Require().NoError(target.Build().Commit(ctx))
8684
s.Require().NoError(target.Execution().Start(ctx))
@@ -100,6 +98,38 @@ func (s *Suite) TestDownloadFileFromRunningInstance() {
10098

10199
s.Assert().Equal(fileContent, string(gotContent))
102100
}
101+
func (s *Suite) TestDownloadFileFromBuilder() {
102+
const namePrefix = "download-file-builder"
103+
104+
target, err := s.Knuu.NewInstance(namePrefix + "-target")
105+
s.Require().NoError(err)
106+
107+
ctx := context.Background()
108+
s.Require().NoError(target.Build().SetImage(ctx, alpineImage))
109+
110+
s.T().Cleanup(func() {
111+
if err := target.Execution().Destroy(ctx); err != nil {
112+
s.T().Logf("error destroying instance: %v", err)
113+
}
114+
})
115+
116+
// Test logic
117+
const (
118+
fileContent = "Hello World!"
119+
filePath = "/hello.txt"
120+
)
121+
122+
s.Require().NoError(target.Storage().AddFileBytes([]byte(fileContent), filePath, "0:0"))
123+
124+
// The commit is required to make the changes persistent to the image
125+
s.Require().NoError(target.Build().Commit(ctx))
126+
127+
// Now test if the file can be downloaded correctly from the built image
128+
gotContent, err := target.Storage().GetFileBytes(ctx, filePath)
129+
s.Require().NoError(err, "Error getting file bytes")
130+
131+
s.Assert().Equal(fileContent, string(gotContent))
132+
}
103133

104134
func (s *Suite) TestMinio() {
105135
const (
@@ -112,7 +142,7 @@ func (s *Suite) TestMinio() {
112142
s.Require().NoError(err)
113143

114144
ctx := context.Background()
115-
s.Require().NoError(target.Build().SetImage(ctx, "alpine:latest"))
145+
s.Require().NoError(target.Build().SetImage(ctx, alpineImage))
116146
s.Require().NoError(target.Build().SetArgs("tail", "-f", "/dev/null")) // Keep the container running
117147
s.Require().NoError(target.Build().Commit(ctx))
118148
s.Require().NoError(target.Execution().Start(ctx))

e2e/system/suite_setup_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
const (
1818
testTimeout = time.Minute * 15 // the same time that is used in the ci/cd pipeline
1919

20+
alpineImage = "alpine:latest"
2021
resourcesHTML = "resources/html"
2122
resourcesFileCMToFolder = "resources/file_cm_to_folder"
2223
)

pkg/container/docker.go

Lines changed: 8 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,13 @@
22
package container
33

44
import (
5-
"archive/tar"
6-
"bytes"
75
"context"
86
"crypto/sha256"
97
"fmt"
10-
"io"
118
"os"
12-
"os/exec"
139
"path/filepath"
1410
"strings"
15-
"time"
1611

17-
"github.com/docker/docker/api/types/container"
18-
"github.com/docker/docker/client"
1912
"github.com/sirupsen/logrus"
2013

2114
"github.com/celestiaorg/knuu/pkg/builder"
@@ -26,24 +19,18 @@ type BuilderFactory struct {
2619
imageNameFrom string
2720
imageNameTo string
2821
imageBuilder builder.Builder
29-
cli *client.Client
3022
dockerFileInstructions []string
3123
buildContext string
3224
}
3325

3426
// NewBuilderFactory creates a new instance of BuilderFactory.
3527
func NewBuilderFactory(imageName, buildContext string, imageBuilder builder.Builder) (*BuilderFactory, error) {
36-
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
37-
if err != nil {
38-
return nil, ErrCreatingDockerClient.Wrap(err)
39-
}
40-
err = os.MkdirAll(buildContext, 0755)
41-
if err != nil {
28+
if err := os.MkdirAll(buildContext, 0755); err != nil {
4229
return nil, ErrFailedToCreateContextDir.Wrap(err)
4330
}
31+
4432
return &BuilderFactory{
4533
imageNameFrom: imageName,
46-
cli: cli,
4734
dockerFileInstructions: []string{"FROM " + imageName},
4835
buildContext: buildContext,
4936
imageBuilder: imageBuilder,
@@ -55,104 +42,24 @@ func (f *BuilderFactory) ImageNameFrom() string {
5542
return f.imageNameFrom
5643
}
5744

58-
// ExecuteCmdInBuilder runs the provided command in the context of the given builder.
59-
// It returns the command's output or any error encountered.
60-
func (f *BuilderFactory) ExecuteCmdInBuilder(command []string) (string, error) {
45+
// AddCmdToBuilder adds the provided command to be run in the context of the builder.
46+
func (f *BuilderFactory) AddCmdToBuilder(command []string) {
6147
f.dockerFileInstructions = append(f.dockerFileInstructions, "RUN "+strings.Join(command, " "))
62-
// FIXME: does not return expected output
63-
return "", nil
6448
}
6549

6650
// AddToBuilder adds a file from the source path to the destination path in the image, with the specified ownership.
67-
func (f *BuilderFactory) AddToBuilder(srcPath, destPath, chown string) error {
51+
func (f *BuilderFactory) AddToBuilder(srcPath, destPath, chown string) {
6852
f.dockerFileInstructions = append(f.dockerFileInstructions, "ADD --chown="+chown+" "+srcPath+" "+destPath)
69-
return nil
70-
}
71-
72-
// ReadFileFromBuilder reads a file from the given builder's mount point.
73-
// It returns the file's content or any error encountered.
74-
func (f *BuilderFactory) ReadFileFromBuilder(filePath string) ([]byte, error) {
75-
if f.imageNameTo == "" {
76-
return nil, ErrNoImageNameProvided
77-
}
78-
containerConfig := &container.Config{
79-
Image: f.imageNameTo,
80-
Cmd: []string{"tail", "-f", "/dev/null"}, // This keeps the container running
81-
}
82-
resp, err := f.cli.ContainerCreate(
83-
context.Background(),
84-
containerConfig,
85-
nil,
86-
nil,
87-
nil,
88-
"",
89-
)
90-
if err != nil {
91-
return nil, ErrFailedToCreateContainer.Wrap(err)
92-
}
93-
94-
defer func() {
95-
// Stop the container
96-
timeout := int(time.Duration(10) * time.Second)
97-
stopOptions := container.StopOptions{
98-
Timeout: &timeout,
99-
}
100-
101-
if err := f.cli.ContainerStop(context.Background(), resp.ID, stopOptions); err != nil {
102-
logrus.Warn(ErrFailedToStopContainer.Wrap(err))
103-
}
104-
105-
// Remove the container
106-
if err := f.cli.ContainerRemove(context.Background(), resp.ID, container.RemoveOptions{}); err != nil {
107-
logrus.Warn(ErrFailedToRemoveContainer.Wrap(err))
108-
}
109-
}()
110-
111-
if err := f.cli.ContainerStart(context.Background(), resp.ID, container.StartOptions{}); err != nil {
112-
return nil, ErrFailedToStartContainer.Wrap(err)
113-
}
114-
115-
// Now you can copy the file
116-
reader, _, err := f.cli.CopyFromContainer(context.Background(), resp.ID, filePath)
117-
if err != nil {
118-
return nil, ErrFailedToCopyFileFromContainer.Wrap(err)
119-
}
120-
defer reader.Close()
121-
122-
tarReader := tar.NewReader(reader)
123-
124-
for {
125-
header, err := tarReader.Next()
126-
127-
if err == io.EOF {
128-
break // End of archive
129-
}
130-
if err != nil {
131-
return nil, ErrFailedToReadFromTar.Wrap(err)
132-
}
133-
134-
if header.Typeflag == tar.TypeReg { // if it's a file then extract it
135-
data, err := io.ReadAll(tarReader)
136-
if err != nil {
137-
return nil, ErrFailedToReadFileFromTar.Wrap(err)
138-
}
139-
return data, nil
140-
}
141-
}
142-
143-
return nil, ErrFileNotFoundInTar
14453
}
14554

14655
// SetEnvVar sets the value of an environment variable in the builder.
147-
func (f *BuilderFactory) SetEnvVar(name, value string) error {
56+
func (f *BuilderFactory) SetEnvVar(name, value string) {
14857
f.dockerFileInstructions = append(f.dockerFileInstructions, "ENV "+name+"="+value)
149-
return nil
15058
}
15159

15260
// SetUser sets the user in the builder.
153-
func (f *BuilderFactory) SetUser(user string) error {
61+
func (f *BuilderFactory) SetUser(user string) {
15462
f.dockerFileInstructions = append(f.dockerFileInstructions, "USER "+user)
155-
return nil
15663
}
15764

15865
// Changed returns true if the builder has been modified, false otherwise.
@@ -178,6 +85,7 @@ func (f *BuilderFactory) PushBuilderImage(ctx context.Context, imageName string)
17885
return ErrFailedToCreateContextDir.Wrap(err)
17986
}
18087
}
88+
18189
dockerFile := strings.Join(f.dockerFileInstructions, "\n")
18290
err := os.WriteFile(dockerFilePath, []byte(dockerFile), 0644)
18391
if err != nil {
@@ -240,17 +148,6 @@ func (f *BuilderFactory) BuildImageFromGitRepo(ctx context.Context, gitCtx build
240148
return err
241149
}
242150

243-
func runCommand(cmd *exec.Cmd) error { // nolint: unused
244-
var stdout, stderr bytes.Buffer
245-
cmd.Stdout = &stdout
246-
cmd.Stderr = &stderr
247-
err := cmd.Run()
248-
if err != nil {
249-
return fmt.Errorf("command failed: %w\nstdout: %s\nstderr: %s", err, stdout.String(), stderr.String())
250-
}
251-
return nil
252-
}
253-
254151
// GenerateImageHash creates a hash value based on the contents of the Dockerfile instructions and all files in the build context.
255152
func (f *BuilderFactory) GenerateImageHash() (string, error) {
256153
hasher := sha256.New()

pkg/instance/build.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,7 @@ func (b *build) ExecuteCommand(command ...string) error {
119119
return ErrAddingCommandNotAllowed.WithParams(b.instance.state.String())
120120
}
121121

122-
_, err := b.builderFactory.ExecuteCmdInBuilder(command)
123-
if err != nil {
124-
return ErrExecutingCommandInInstance.WithParams(command, b.instance.name).Wrap(err)
125-
}
122+
b.builderFactory.AddCmdToBuilder(command)
126123
return nil
127124
}
128125

@@ -133,9 +130,7 @@ func (b *build) SetUser(user string) error {
133130
return ErrSettingUserNotAllowed.WithParams(b.instance.state.String())
134131
}
135132

136-
if err := b.builderFactory.SetUser(user); err != nil {
137-
return ErrSettingUser.WithParams(user, b.instance.name).Wrap(err)
138-
}
133+
b.builderFactory.SetUser(user)
139134
b.instance.Logger.WithFields(logrus.Fields{
140135
"instance": b.instance.name,
141136
"user": user,
@@ -224,14 +219,10 @@ func (b *build) getBuildDir() string {
224219
}
225220

226221
// addFileToBuilder adds a file to the builder
227-
func (b *build) addFileToBuilder(src, dest, chown string) error {
228-
_ = src
222+
func (b *build) addFileToBuilder(src, dest, chown string) {
229223
// dest is the same as src here, as we copy the file to the build dir with the subfolder structure of dest
230-
err := b.builderFactory.AddToBuilder(dest, dest, chown)
231-
if err != nil {
232-
return ErrAddingFileToInstance.WithParams(dest, b.instance.name).Wrap(err)
233-
}
234-
return nil
224+
_ = src
225+
b.builderFactory.AddToBuilder(dest, dest, chown)
235226
}
236227

237228
// SetEnvironmentVariable sets the given environment variable in the instance
@@ -247,7 +238,8 @@ func (b *build) SetEnvironmentVariable(key, value string) error {
247238
}).Debugf("Setting environment variable")
248239

249240
if b.instance.state == StatePreparing {
250-
return b.builderFactory.SetEnvVar(key, value)
241+
b.builderFactory.SetEnvVar(key, value)
242+
return nil
251243
}
252244
b.env[key] = value
253245
return nil

0 commit comments

Comments
 (0)