From d2aac5e12c06b0244d092a7500f457ba4a215377 Mon Sep 17 00:00:00 2001 From: Mojtaba Date: Fri, 19 Apr 2024 16:05:21 +0200 Subject: [PATCH] feat: download file from running instance (#283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jose Ramon MaƱes <32740567+jrmanes@users.noreply.github.com> --- pkg/knuu/instance.go | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/pkg/knuu/instance.go b/pkg/knuu/instance.go index 99a6b94..458e0c5 100644 --- a/pkg/knuu/instance.go +++ b/pkg/knuu/instance.go @@ -737,15 +737,42 @@ func (i *Instance) GetIP() (string, error) { // GetFileBytes returns the content of the given file // This function can only be called in the states 'Preparing' and 'Committed' func (i *Instance) GetFileBytes(file string) ([]byte, error) { - if !i.IsInState(Preparing, Committed) { - return nil, fmt.Errorf("getting file is only allowed in state 'Preparing' or 'Committed'. Current state is '%s'", i.state.String()) + if !i.IsInState(Preparing, Committed, Started) { + return nil, fmt.Errorf("getting file is only allowed in state 'Started', 'Preparing' or 'Committed'. Current state is '%s'", i.state.String()) + } + + if i.state != Started { + bytes, err := i.builderFactory.ReadFileFromBuilder(file) + if err != nil { + return nil, fmt.Errorf("error getting file '%s' from instance '%s': %w", file, i.name, err) + } + return bytes, nil + } + + ctx, cancel := context.WithTimeout(context.Background(), k8s.Timeout()) + defer cancel() + + rc, err := i.ReadFileFromRunningInstance(ctx, file) + if err != nil { + return nil, fmt.Errorf("error reading file '%s' from running instance '%s': %w", file, i.name, err) + } + + defer rc.Close() + return io.ReadAll(rc) +} + +func (i *Instance) ReadFileFromRunningInstance(ctx context.Context, filePath string) (io.ReadCloser, error) { + if !i.IsInState(Started) { + return nil, fmt.Errorf("reading file is only allowed in state 'Started'. Current state is '%s'", i.state.String()) } - bytes, err := i.builderFactory.ReadFileFromBuilder(file) + // Not the best solution, we need to find a better one. + // Tested with a 110MB+ file and it worked. + fileContent, err := i.ExecuteCommandWithContext(ctx, "cat", filePath) if err != nil { - return nil, fmt.Errorf("error getting file '%s' from instance '%s': %w", file, i.name, err) + return nil, fmt.Errorf("error reading file '%s' from running instance '%s': %v", filePath, i.name, err) } - return bytes, nil + return io.NopCloser(strings.NewReader(fileContent)), nil } // AddPolicyRule adds a policy rule to the instance