project-copacetic / copacetic

🧵 CLI tool for directly patching container images!
https://project-copacetic.github.io/copacetic/
Apache License 2.0
1.05k stars 70 forks source link

[REQ] Add support for other output modes as buildctl does #604

Open ashnamehrotra opened 6 months ago

ashnamehrotra commented 6 months ago

What kind of request is this?

None

What is your request or suggestion?

https://github.com/project-copacetic/copacetic/blob/d648155f5424a9f4cb13acd7209195846791873b/pkg/patch/patch.go#L209

Turning copacetic TODO comments into issues from https://docs.google.com/spreadsheets/d/1XwNj1J6e2FrUhlqaIsV10l8_tgov7WodlkvpNZXYZMU/edit#gid=1386834576.

Are you willing to submit PRs to contribute to this feature request?

h4l0gen commented 6 months ago

Hi @ashnamehrotra, I'm interested in this issue. Could you please assign it to me? This way, other contributors won't work on the same issue, and we can avoid wasting valuable time. Thank you!

h4l0gen commented 6 months ago

Hey @ashnamehrotra in first look I thought of this solution. I've added support for multiple output formats to the patch command in the patch.go file. This includes support for Docker images, OCI images. Proposed key changes from my side are:

  1. Added a new parameter outputFormat to the Patch and patchWithContext functions.
  2. In the patchWithContext function, I've added a switch statement to handle the different output formats.
  3. Updated the cmd.go file to add a new flag for the outputFormat and map it to the patchArgs struct.

Here is an example of updated patchWithContext function

func patchWithContext(ctx context.Context, ch chan error, image, reportFile, patchedTag, workingFolder, scanner, format, output, outputFormat string, ignoreError bool, bkOpts buildkit.Opts) error {
// ...
    solveOpt := client.SolveOpt{
        Exports: []client.ExportEntry{},
        Frontend: "",
        Session:  attachable,
    }

    switch outputFormat {
    case "docker":
        solveOpt.Exports = append(solveOpt.Exports, client.ExportEntry{
            Type: client.ExporterDocker,
            Attrs: map[string]string{
                "name": patchedImageName,
            },
            Output: func(_ map[string]string) (io.WriteCloser, error) {
                return pipeW, nil
            },
        })
    case "oci":
        solveOpt.Exports = append(solveOpt.Exports, client.ExportEntry{
            Type:  client.ExporterOCI,
            Attrs: map[string]string{},
            Output: func(_ map[string]string) (io.WriteCloser, error) {
                return os.Create(fmt.Sprintf("%s.tar", patchedImageName))
            },
        })
    default:
        return fmt.Errorf("unsupported output format: %s", outputFormat)
    }

This should provide the necessary flexibility to users, allowing them to choose the desired output format for the patched image. This is required change in cmd.go

func NewPatchCmd() *cobra.Command {
// ...
    flags.StringVarP(&ua.outputFormat, "output-format", "F", "docker", "Output format for the patched image (docker, oci)")

and default value is set to docker

h4l0gen commented 6 months ago

Please take a look and provide your thoughts on this and let me know if you feel any changes or modifications. I've done all changes with this approach and creating WIP:PR for now, and modify it accordingly if you feel any changes. Thank you!

ChristofferNissen commented 6 months ago

Hello :wave:

I am in need of also have the option of exporting as OCI image tar archieve directly to local filesystem. I have copied the code from v0.6.2 and modified in my own repository, you can see what i did to implement the functionality. Would like to get rid of this local copy by having it integrated into the main code base :)

Example

h4l0gen commented 6 months ago

Hi @ChristofferNissen thankyou for your wonderful work. I will surely like to take a look on it, i am just little busy with some other work. I will be back in some time, and we will discuss this implementation along with @ashnamehrotra. BTW I've raised a PR, It has only a small problem, it is just stopping after sending tarball, if you like to take a look on that. I will give you complete problem scenario in some time, not on my laptop right now. Thank you 👍

MiahaCybersec commented 3 months ago

Now that discard patch layer has been added to Copa, adding OCI support will require storing the base image in OCI annotations, as well as determining whether the image being passed in is an OCI or Docker image.

While I was adding Docker labels support, I found the following code snippet which could make adding OCI annotations easier.

Screenshot 2024-08-02 15 36 34