Building OCI Metadata Parser: Extracting Image Metadata from JSON & YAML


Introduction

When working with containerized environments, analyzing OCI image metadata is crucial for understanding image structure, layers, and versions. To simplify this, we built OCI Metadata Parser, a Go-based tool that extracts metadata from JSON and YAML OCI manifests.

In this article, we'll walk through the development, challenges, and how this tool works.

Why OCI Metadata Parser?

  • Extracts image details from OCI-compliant manifests.

  • Supports both JSON and YAML formats.

  • Provides a structured way to analyze image layers and versions.

  • Useful for container security, debugging, and observability.

Tech Stack

  • Go for high-performance parsing.

  • gopkg.in/yaml.v2 for YAML parsing.

  • encoding/json for JSON parsing.

Project Overview

The OCI Metadata Parser reads an OCI image manifest and extracts:

  • Image Name

  • Version

  • Layers

The project is structured as follows:

oci-metadata-parser/
│── cmd/
│   └── main.go  # Entry point
│── parser/
│   ├── parser.go  # Parsing logic
│   ├── json_parser.go  # JSON parser
│   ├── yaml_parser.go  # YAML parser
│── sample.json  # Sample JSON manifest
│── sample.yaml  # Sample YAML manifest
│── go.mod

Implementing the Parser

1. Parsing JSON OCI Metadata

We implemented a function to parse OCI image JSON manifests:

package parser

import (
    "encoding/json"
    "io/ioutil"
    "os"
)

type ImageMetadata struct {
    Name    string   `json:"name"`
    Version string   `json:"version"`
    Layers  []string `json:"layers"`
}

func ParseJSON(filename string) (ImageMetadata, error) {
    var metadata ImageMetadata
    file, err := os.Open(filename)
    if err != nil {
        return metadata, err
    }
    defer file.Close()

    byteValue, _ := ioutil.ReadAll(file)
    err = json.Unmarshal(byteValue, &metadata)
    return metadata, err
}

2. Parsing YAML OCI Metadata

Similarly, we implemented YAML parsing using gopkg.in/yaml.v2:

package parser

import (
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "os"
)

type YamlMetadata struct {
    Name    string   `yaml:"name"`
    Version string   `yaml:"version"`
    Layers  []string `yaml:"layers"`
}

func ParseYAML(filename string) (YamlMetadata, error) {
    var metadata YamlMetadata
    file, err := os.Open(filename)
    if err != nil {
        return metadata, err
    }
    defer file.Close()

    byteValue, _ := ioutil.ReadAll(file)
    err = yaml.Unmarshal(byteValue, &metadata)
    return metadata, err
}

3. Running the Program

To parse JSON metadata:

go run ./cmd/main.go json sample.json

To parse YAML metadata:

go run ./cmd/main.go yaml sample.yaml

Sample JSON Input (sample.json)

{
    "name": "nginx",
    "version": "1.14.2",
    "layers": [
        "layer1",
        "layer2"
    ]
}

Sample YAML Input (sample.yaml)

name: nginx
version: 1.14.2
layers:
  - layer1
  - layer2

Expected Output

Image Name: nginx
Version: 1.14.2
Layers: [layer1 layer2]

Debugging Issues

  1. File Not Found Error

    • Ensure sample.yaml or sample.json exists in the current directory.

    • Provide the full file path when running the program.

  2. Empty Output

    • Check if the YAML or JSON file structure matches the expected schema.

    • Add debugging print statements in ParseJSON and ParseYAML.

Future Enhancements

  • Validate OCI Manifest Spec to ensure correctness.

  • Support more metadata fields (e.g., architecture, OS).

  • Build a CLI tool for enhanced usability.

Conclusion

The OCI Metadata Parser simplifies image metadata extraction for Kubernetes, Docker, and OCI environments. This project is a stepping stone toward more advanced container analysis and observability tools.

🚀 Follow me on Hashnode for more cloud-native and Go-based projects!

0
Subscribe to my newsletter

Read articles from Sumangal Chhetri directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sumangal Chhetri
Sumangal Chhetri