Summary Of LFX’21 Summer Mentorship With CNCF: Buildpacks

Haimantika Mitra
Buildpacks
Published in
7 min readAug 25, 2021

The world of Open-Source is vast. There is an enormous opportunity to learn, but it often gets overwhelming for beginners. If you are someone who is eager to learn and explore the world of Open-Source the LFX mentorship program is for you. Before we start with my experience, here’s a sneak-peek of what LFX mentorship is. It happens thrice: Spring, Summer and Fall. You get to choose and apply to maximum three projects from a pool of some amazing ones.

Some tips to make your application standout:

  1. Join the slack channel of the project you want to contribute in. Introduce yourself there (this is a good start to interact with the community).
  2. Start understanding the project, by reading their docs, going through their code-base and setting up the development environment.
  3. Stay in touch with your potential mentors and let them know about your progress, ask your queries.
  4. Draft a proposal mentioning the project goals, a detailed summary of your understanding of the project and how you plan to solve it in three months and share it with your mentor for reviews.

Once all of these are done, apply from the LFX portal and wait for the good news to drop by your email!

Let’s jump to my experience and take-away from the program. Being an absolute beginner, with great zeal to start contributing to open-source, the mentorship not only helped me learn, write quality code, it also helped me build connections for life. While I was super pumped to start working, life decided to take a different turn for me, I had to undergo an immediate surgery, which led to 2 weeks of complete bed-rest and months to recover (still under progress). Altogether I was having a very hard time, both mentally and physically. I even thought of withdrawing from the program, but here I am writing this blog as I come closer to completing the project and this wouldn’t have been possible without the enormous help and support from my mentor : Javier Romero. From being very responsive to every text to pair-programming, just to get me started, Javier helped me get the needed confidence (+ learn some cool tricks and shortcuts). It goes without mentioning, the entire community is very supportive and will always be there for you. Special mention to Anthony, someone who helps your learn and have great conversations. I can go on writing about the community, but in the interest of reader’s time, let’s get started with the project.

What is Buildpacks?

Buildpacks is a tool that make use of Docker and Golang majorly to convert our source code into runnable app image . It is very quick and saves time by auto detecting the group of buildpacks required for our source code.

Typical buildpacks are a set of at least three files:

  • buildpack.toml – provides metadata about your buildpack
  • bin/detect – determines whether buildpack should be applied
  • bin/build – executes buildpack logic

The Epic: Embed source metadata in OCI image

I had to build a solution where a pack user, would be able to inspect the final app image and determine where the source of the code is located as well as what version.

It had three parts:

The solution:

To build the solution I had to understand how pack works, learn how lifecycle and pack are related and then decide a workflow. Going through the concepts helped me have an understanding of the entire project and some terms, which I needed further.

The issue I took up first, wanted to have the source and version information from project.toml file embedded as metadata in the final app image.

It had the following acceptance criteria:

Given I have a `project.toml` with the following contents:
[project]
version = “1.0.2”
source-url = “https://github.com/buildpacks/pack"
And I run `pack build my-app`
When I run the following command `docker inspect my-app | jq -r ‘.[0].Config.Labels[“io.buildpacks.project.metadata”] | fromjson’`
Then I should see:
{
“type”: “project”,
“version”: { “declared”: “1.0.2” },
“metadata”: {
“url”: “https://github.com/buildpacks/pack"
}
}

Steps followed to get the solution:

  1. Parse the project descriptor (project.toml). This required to add the version and source-url in the project.go file, makes changes accordingly to the project_test.go file and then check if the test is working fine.

2. We wanted to provide <layers>/project-metadata.toml in this format which would be translated into the io.buildpacks.project.metadata label on the image.

3. Our next step was to code the ProjectMetadata func that writes the `project.toml` file, which on further research was found to be similar to `stack.toml` and made our task easier. This required us to make changes in the `container_ops.go` file and `container_test.ops. go` file.

The code below writes a `project.toml` based on the ProjectMetadata provided to the destination path.

5. Now that we were done writing the platform.ProjectMetadata in the non-creator case, it still needed to be sent when the builder is trusted. For this we made changes to the lifecycle_execution.go and lifecycle_excecution.go file where we included the path ( mountPaths.projectPath() ) containing the ProjectMetadata .

6. To get the above step up and running, we had to make the following changes in the lifecycle_executor.go file and mounth_paths.go file.

7. As we proceed towards the solution, we are left we some final changes before testing. We had to leverage the lifecycle to provide the desired data structures.

8. Before we could test, we needed to write the build.go file that fetches the version and sourceURL from the ProjectDescriptor and passes it to the label.

9. Lastly we write the acceptance_test.go file that tests our if our io.buildpacks.project.metadata label has our required output.

This was achieved with the following code addition:

t.Log("sets the source metadata") assertImage.HasLabelWithData(repoName, "io.buildpacks.project.metadata", (`{"source":{"type":"project","version":{"declared":"1.0.2"},"metadata":{"url":"https://github.com/buildpacks/pack"}}}`))

10. To test, we need to have a project.toml file in the pack directory and within acceptance/testdata/mock_app to verify our test cases.

project.toml file

The output:

Before we verify our output, let us see what was required to be done:

  • We build an image by running pack build my-app.
  • On running the docker inspect my-app | jq -r ‘.[0].Config.Labels[“io.buildpacks.project.metadata”] | fromjson’ command, the output received should be:
{
"type": "project",
"version": { "declared": "1.0.2" },
"metadata": {
"url": "https://github.com/buildpacks/pack"
}
}

After multiple commits, working on the changes suggested by mentors and other community members, we finally reached the solution.

This is how to looks:

The PR link with the changes that achieved the above solution can be found here.

Takeaways:

  • This being my first open-source contribution, it has been an exciting learning journey to work with a mentor as helpful and kind as Javier Romero.
  • When I started with the project, my knowledge on Golang was very basic, at the end of three months I not only have a good understanding of the language, but have also learned to write quality code, test cases and more.
  • Apart from that, the bonding and the social skills developed due to community meetings at Buildpacks and the inclusiveness of every member of this community just made me a better open-source student.

Before I good-bye I extend my gratitude to my mentor and the entire community who has been there to assist me, be it through texts or pair-programming.

While the program might have come to an end, the contribution from my side doesn’t end here. I shall go forward and complete the pending issues.

--

--

Haimantika Mitra
Buildpacks

Training and testing in real and reel life. 👩‍💻