Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"kn workflow run" freezes when pulling registry.redhat.io images #55

Open
wants to merge 2 commits into
base: 9.101.x-prod
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/kn-plugin-workflow/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api v0.0.0
github.com/apache/incubator-kie-tools/packages/sonataflow-operator/workflowproj v0.0.0
github.com/beevik/etree v1.2.0
github.com/docker/distribution v2.8.2+incompatible
github.com/docker/docker v24.0.9+incompatible
github.com/docker/go-connections v0.4.0
github.com/jstemmer/go-junit-report/v2 v2.0.0
Expand All @@ -31,7 +32,6 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
Expand Down
36 changes: 30 additions & 6 deletions packages/kn-plugin-workflow/pkg/common/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/docker/distribution/reference"
"io"
"os"
"os/exec"
Expand All @@ -35,7 +36,6 @@ import (
"github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow/pkg/metadata"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/go-connections/nat"
Expand All @@ -51,6 +51,10 @@ type DockerLogMessage struct {
ID string `json:"id,omitempty"`
}

type DockerClient interface {
ImageList(ctx context.Context, options types.ImageListOptions) ([]types.ImageSummary, error)
}

func getDockerClient() (*client.Client, error) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
Expand Down Expand Up @@ -203,16 +207,13 @@ func pullDockerImage(cli *client.Client, ctx context.Context) (io.ReadCloser, er
// For that we should check only the image name and tag, removing the registry,
// as `docker image ls --filter reference=<image_full_url>` will return empty if the image_full_url is not the first tag
// of an image.
imageNameWithoutRegistry := strings.Split(metadata.DevModeImage, "/")
imageFilters := filters.NewArgs()
imageFilters.Add("reference", fmt.Sprintf("*/%s", imageNameWithoutRegistry[len(imageNameWithoutRegistry)-1]))
images, err := cli.ImageList(ctx, types.ImageListOptions{Filters: imageFilters})
exists, err := CheckImageExists(cli, ctx, metadata.DevModeImage)
if err != nil {
return nil, fmt.Errorf("error listing images: %s", err)
}

// If the image is not found locally, pull it from the remote registry
if len(images) == 0 {
if !exists {
reader, err := cli.ImagePull(ctx, metadata.DevModeImage, types.ImagePullOptions{})
if err != nil {
return nil, fmt.Errorf("\nError pulling image: %s. Error is: %s", metadata.DevModeImage, err)
Expand All @@ -223,6 +224,29 @@ func pullDockerImage(cli *client.Client, ctx context.Context) (io.ReadCloser, er
return nil, nil
}

func CheckImageExists(cli DockerClient, ctx context.Context, imageName string) (bool, error) {
named, err := reference.ParseNormalizedNamed(imageName)

if tagged, ok := named.(reference.Tagged); ok {
imageName = fmt.Sprintf("%s:%s", reference.Path(named), tagged.Tag())
} else {
imageName = fmt.Sprintf("%s:%s", reference.Path(named), "latest")
}
images, err := cli.ImageList(ctx, types.ImageListOptions{All: true})
if err != nil {
return false, fmt.Errorf("error listing images: %s", err)
}

for _, image := range images {
for _, tag := range image.RepoTags {
if strings.HasSuffix(tag, imageName) {
return true, nil
}
}
}
return false, nil
}

func processDockerImagePullLogs(reader io.ReadCloser) error {
for {
err := waitToImageBeReady(reader)
Expand Down
Loading