### Install the YAML package Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/gopkg.in/yaml.v2/README.md Use the go get command to download the package into your environment. ```bash go get gopkg.in/yaml.v2 ``` -------------------------------- ### Advanced JMESPath Queries Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/jmespath/go-jmespath/README.md Examples demonstrating object selection, projection, and filtering. ```go > var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data > var data interface{} > err := json.Unmarshal(jsondata, &data) > result, err := jmespath.search("foo.bar", data) result = { "baz": [ 0, 1, 2, 3, 4 ] } > var jsondata = []byte(`{"foo": [{"first": "a", "last": "b"}, {"first": "c", "last": "d"}]}`) // your data > var data interface{} > err := json.Unmarshal(jsondata, &data) > result, err := jmespath.search({"foo[*].first", data) result [ 'a', 'c' ] > var jsondata = []byte(`{"foo": [{"age": 20}, {"age": 25}, {"age": 30}, {"age": 35}, {"age": 40}]}`) // your data > var data interface{} > err := json.Unmarshal(jsondata, &data) > result, err := jmespath.search("foo[?age > `30`]") result = [ { age: 35 }, { age: 40 } ] ``` -------------------------------- ### Install Counterfeiter Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Install the tool to the GOPATH bin directory to allow shell invocation. ```shell $ go install github.com/maxbrunsfeld/counterfeiter/v6 $ ~/go/bin/counterfeiter USAGE counterfeiter [-generate>] [-o ] [-p] [--fake-name ] [-header ] [] [-] ``` -------------------------------- ### YAML example output Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/gopkg.in/yaml.v2/README.md The expected output generated by running the provided Go example code. ```text --- t: {Easy! {2 [3 4]}} --- t dump: a: Easy! b: c: 2 d: [3, 4] --- m: map[a:Easy! b:map[c:2 d:[3 4]]] --- m dump: a: Easy! b: c: 2 d: - 3 - 4 ``` -------------------------------- ### Define AMI Configuration Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/README.md Example configuration file defining virtualization type, tags, and regional credentials for AMI creation. ```json { "ami_configuration": { "description": "Your description here", "virtualization_type": "hvm", "visibility": "public", "tags" : { "distro": "distro name, e.g. ubuntu-jammy", "version": "e.g. 1.0.0" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "US_ACCESS_KEY_ID", "secret_key": "US_ACCESS_SECRET_KEY" }, "bucket_name": "US_BUCKET_NAME", "destinations": ["us-west-1", "us-west-2"] }, { "name": "cn-north-1", "credentials": { "access_key": "CN_ACCESS_KEY_ID", "secret_key": "CN_ACCESS_SECRET_KEY" }, "bucket_name": "CN_BUCKET_NAME" } ] } ``` -------------------------------- ### Go Example: Load and Parse Configuration Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Demonstrates loading a JSON configuration file using `os.Open` and parsing it into a `config.Config` struct using `config.NewFromReader`. Handles potential errors during file operations and parsing. ```go package main import ( "os" "light-stemcell-builder/config" ) func main() { // Load configuration from file configFile, err := os.Open("config.json") if err != nil { panic(err) } defer configFile.Close() // Parse and validate configuration cfg, err := config.NewFromReader(configFile) if err != nil { panic(err) // Validation errors: missing description, invalid regions, etc. } // Access AMI configuration amiConfig := cfg.AmiConfiguration // amiConfig.AmiName - Auto-generated UUID if not specified // amiConfig.Description - Required // amiConfig.VirtualizationType - Defaults to "hvm" // amiConfig.Visibility - Defaults to "public" // amiConfig.Encrypted - Enable KMS encryption // amiConfig.KmsKeyId - KMS key ARN for encryption // amiConfig.Tags - Custom tags for the AMI // Iterate over regions for _, region := range cfg.AmiRegions { awsConfig := region.Credentials.GetAwsConfig() // awsConfig is ready for use with AWS SDK // Handles static credentials, EC2 role credentials, and role assumption // region.IsolatedRegion is auto-detected for cn-north-1 // region.Destinations contains copy target regions } } ``` -------------------------------- ### Create Root Logger with Implementation Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-logr/logr/README.md Initialize the root logger early in your application's lifecycle. This example shows creating a logger using a hypothetical 'logimpl' implementation. ```go func main() { // ... other setup code ... // Create the "root" logger. We have chosen the "logimpl" implementation, // which takes some initial parameters and returns a logr.Logger. logger := logimpl.New(param1, param2) // ... other setup code ... } ``` -------------------------------- ### Convert format-string logs to structured key-value pairs Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-logr/logr/README.md Examples demonstrating the migration from klog format-string logging to structured logr-style logging. ```go klog.V(4).Infof("Client is returning errors: code %v, error %v", responseCode, err) ``` ```go logger.Error(err, "client returned an error", "code", responseCode) ``` ```go klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v", seconds, retries, url) ``` ```go logger.V(4).Info("got a retry-after response when requesting url", "attempt", retries, "after seconds", seconds, "url", url) ``` ```go log.Printf("unable to reflect over type %T") ``` ```go logger.Info("unable to reflect over type", "type", fmt.Sprintf("%T")) ``` -------------------------------- ### Example Output Manifest Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt An example of the generated stemcell manifest in YAML format, showing AMI IDs for different regions. ```yaml # name:bosh-aws-xen-hvm-ubuntu-trusty-go_agent # version: "3202" #bosh_protocol: "1" # sha1: f0c10bb5e8b7fee9c29db15bbb4ae481e398eab6 # operating_system: ubuntu-trusty # stemcell_formats: # - aws-light # cloud_properties: # ami: # cn-north-1: ami-69ae6504 # us-east-1: ami-e62f158c # us-west-1: ami-947e0df4 # us-west-2: ami-54328238 ``` -------------------------------- ### Ginkgo Spec Example Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/ginkgo/v2/README.md This is an example of a Ginkgo spec that tests book checkout functionality from a library. It uses BeforeEach, When, Context, and It blocks to structure the tests. It also demonstrates the use of SpecTimeout for setting test durations. ```go import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ... ) var _ = Describe("Checking books out of the library", Label("library"), func() { var library *libraries.Library var book *books.Book var valjean *users.User BeforeEach(func() { library = libraries.NewClient() book = &books.Book{ Title: "Les Miserables", Author: "Victor Hugo", } valjean = users.NewUser("Jean Valjean") }) When("the library has the book in question", func() { BeforeEach(func(ctx SpecContext) { Expect(library.Store(ctx, book)).To(Succeed()) }) Context("and the book is available", func() { It("lends it to the reader", func(ctx SpecContext) { Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books()).To(ContainElement(book)) Expect(library.UserWithBook(ctx, book)).To(Equal(valjean)) }, SpecTimeout(time.Second * 5)) }) Context("but the book has already been checked out", func() { var javert *users.User BeforeEach(func(ctx SpecContext) { javert = users.NewUser("Javert") Expect(javert.Checkout(ctx, library, "Les Miserables")).To(Succeed()) }) It("tells the user", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is currently checked out")) }, SpecTimeout(time.Second * 5)) It("lets the user place a hold and get notified later", func(ctx SpecContext) { Expect(valjean.Hold(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Holds(ctx)).To(ContainElement(book)) By("when Javert returns the book") Expect(javert.Return(ctx, library, book)).To(Succeed()) By("it eventually informs Valjean") notification := "Les Miserables is ready for pick up" Eventually(ctx, valjean.Notifications).Should(ContainElement(notification)) Expect(valjean.Checkout(ctx, library, "Les Miserables")).To(Succeed()) Expect(valjean.Books(ctx)).To(ContainElement(book)) Expect(valjean.Holds(ctx)).To(BeEmpty()) }, SpecTimeout(time.Second * 10)) }) }) When("the library does not have the book in question", func() { It("tells the reader the book is unavailable", func(ctx SpecContext) { err := valjean.Checkout(ctx, library, "Les Miserables") Expect(err).To(MatchError("Les Miserables is not in the library catalog")) }, SpecTimeout(time.Second * 5)) }) }) ``` -------------------------------- ### View Stemcell Manifest Output Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/README.md Example output showing the generated AMI IDs for various regions. ```yml name: bosh-aws-xen-hvm-ubuntu-trusty-go_agent version: "3202" bosh_protocol: "1" sha1: f0c10bb5e8b7fee9c29db15bbb4ae481e398eab6 operating_system: ubuntu-trusty stemcell_formats: - aws-light cloud_properties: ami: cn-north-1: ami-69ae6504 us-east-1: ami-e62f158c us-west-1: ami-947e0df4 us-west-2: ami-54328238 ``` -------------------------------- ### Use Slim-Sprig Functions in Templates Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-task/slim-sprig/v3/README.md Call Slim-Sprig functions within Go templates using lowercase names. This example demonstrates chaining the 'upper' and 'repeat' functions. ```go-template {{ "hello!" | upper | repeat 5 }} ``` ```text HELLO!HELLO!HELLO!HELLO!HELLO! ``` -------------------------------- ### Build All Files (Old System) Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/golang.org/x/sys/unix/README.md Use this command to build Go files for your current OS and architecture with the old build system. Ensure GOOS and GOARCH are set correctly. Running with -n shows the commands that will be executed. ```bash mkall.sh ``` ```bash mkall.sh -n ``` -------------------------------- ### Instantiate Fakes Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Import the generated package and instantiate the fake object. ```go import "my-repo/path/to/foo/foofakes" var fake = &foofakes.FakeMySpecialInterface{} ``` -------------------------------- ### Run Gomega linter Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/gomega/CONTRIBUTING.md Check the codebase for potential issues using the Go vet tool. ```bash go vet ./... ``` -------------------------------- ### Syscall Entry Points Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/golang.org/x/sys/unix/README.md These are the entry points for the hand-written assembly file that implements system call dispatch. They differ in the number of arguments that can be passed to the kernel. ```go func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) ``` ```go func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) ``` ```go func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) ``` -------------------------------- ### Execute Stemcell Builder Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/README.md Run the builder tool with a configuration file, source image, and manifest file. ```shell ./light-stemcell-builder -c config.json --image root.img --manifest stemcell.MF > updated-stemcell.MF ``` -------------------------------- ### Build and Test Commands Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/ginkgo/v2/CONTRIBUTING.md Commands used to build, test, and verify changes within the Ginkgo project. ```bash make ``` ```bash go install ./... ``` ```bash ginkgo -r -p ``` ```bash go vet ./... ``` ```bash bundle && bundle exec jekyll serve ``` -------------------------------- ### Basic Configuration File Structure Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Defines AMI properties like name, description, virtualization type, visibility, EFI support, encryption, and tags. Also specifies target AWS regions with credentials and bucket names. ```json { "ami_configuration": { "name": "my-custom-stemcell", "description": "Ubuntu Jammy stemcell for BOSH deployments", "virtualization_type": "hvm", "visibility": "public", "efi": false, "encrypted": false, "tags": { "distro": "ubuntu-jammy", "version": "1.234" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }, "bucket_name": "my-stemcell-bucket", "destinations": ["us-west-1", "us-west-2", "eu-west-1"] } ] } ``` -------------------------------- ### Execute Project Tests with Ginkgo Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Commands for running unit and integration tests, including coverage generation. ```bash # Run unit tests (excludes driver and integration tests) ginkgo -r --skip-package driver,integration # Run all tests including integration (requires AWS credentials) ginkgo -r # Run specific package tests ginkgo ./config ginkgo ./manifest ginkgo ./publisher ginkgo ./collection # Run with verbose output ginkgo -v -r --skip-package driver,integration # Generate test coverage ginkgo -r --skip-package driver,integration --cover --coverprofile=coverage.out go tool cover -html=coverage.out ``` -------------------------------- ### Run Unit Tests Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/README.md Execute unit tests using Ginkgo while skipping integration and driver packages. ```shell ginkgo -r --skipPackage driver,integration ``` -------------------------------- ### Build AMIs from Raw Image Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Use the CLI to create AMIs from a raw machine image. Specify the configuration file, image path, and manifest file. The output is the updated stemcell manifest. ```bash ./light-stemcell-builder \ -c config.json \ --image root.img \ --manifest stemcell.MF \ > updated-stemcell.MF ``` -------------------------------- ### Run `go generate` Command Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Execute the `go generate ./...` command to trigger the generation of fake implementations for all interfaces with `go:generate` or `counterfeiter:generate` directives in your module. ```shell go generate ./... ``` -------------------------------- ### Define AWS Resource Configuration in Go Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Configures AMI properties, machine image drivers, and snapshot settings using the resources package. ```go package main import ( "light-stemcell-builder/resources" ) func main() { // AMI properties for creation props := resources.AmiProperties{ Name: "my-stemcell-ami", Description: "Custom BOSH stemcell", Accessibility: resources.PublicAmiAccessibility, // "public" or "private" VirtualizationType: resources.HvmAmiVirtualization, // "hvm" Efi: false, Encrypted: true, KmsKeyId: "arn:aws:kms:us-east-1:123456789012:key/...", KmsKeyAliasName: "alias/my-key", Tags: map[string]string{ "distro": "ubuntu-jammy", "version": "1.0.0", }, SharedWithAccounts: []string{"111122223333"}, } // Machine image configuration for S3 upload machineImageConfig := resources.MachineImageDriverConfig{ MachineImagePath: "/path/to/root.img", BucketName: "my-bucket", ServerSideEncryption: "AES256", FileFormat: resources.VolumeRawFormat, // "RAW" or "vmdk" VolumeSizeGB: 3, } // Snapshot configuration snapshotConfig := resources.SnapshotDriverConfig{ MachineImageURL: "s3://my-bucket/bosh-machine-image-1234567890", FileFormat: "RAW", AmiProperties: props, } // AMI driver configuration amiConfig := resources.AmiDriverConfig{ SnapshotID: "snap-12345678", ExistingAmiID: "", // For copies only DestinationRegion: "", // For copies only AmiProperties: props, } _ = machineImageConfig _ = snapshotConfig _ = amiConfig } ``` -------------------------------- ### Run Gomega tests locally Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/gomega/CONTRIBUTING.md Execute all unit tests in the project to ensure stability before submission. ```bash ginkgo -r -p ``` -------------------------------- ### Build AMIs with VMDK Format Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Create AMIs from a VMDK image, specifying the format and volume size. This is useful for VMDK images that require explicit size definition. ```bash ./light-stemcell-builder \ -c config.json \ --image root.vmdk \ --format vmdk \ --volume-size 3 \ --manifest stemcell.MF \ > updated-stemcell.MF ``` -------------------------------- ### Track Tool Dependencies with tools.go Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use a `tools.go` file to manage tool dependencies for `go generate`. This ensures consistent tool versions across your project. ```go //go:build tools package tools import ( _ "github.com/maxbrunsfeld/counterfeiter/v6" ) // This file imports packages that are used when running go generate, or used // during the development process but not otherwise depended on by built code. ``` -------------------------------- ### Commit, Push, and Create GitHub Release Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Standard Git commands to commit changes, push to the remote repository, and create a new release on GitHub. Fetch tags to ensure local repository is up-to-date. ```bash git commit -m "vM.m.p" git push gh release create "vM.m.p" git fetch --tags origin master ``` -------------------------------- ### Generate and Parse UUIDs in Go Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/satori/go.uuid/README.md Demonstrates creating a version 4 UUID and parsing a UUID string into an object. ```go package main import ( "fmt" "github.com/satori/go.uuid" ) func main() { // Creating UUID Version 4 u1 := uuid.NewV4() fmt.Printf("UUIDv4: %s\n", u1) // Parsing UUID from string input u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") if err != nil { fmt.Printf("Something gone wrong: %s", err) } fmt.Printf("Successfully parsed: %s", u2) } ``` -------------------------------- ### Unmarshal and Marshal YAML data Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/gopkg.in/yaml.v2/README.md Demonstrates how to unmarshal YAML into a struct or a map, and how to marshal data back into YAML format. Struct fields must be exported for the unmarshaler to populate them. ```go package main import ( "fmt" "log" "gopkg.in/yaml.v2" ) var data = ` a: Easy! b: c: 2 d: [3, 4] ` // Note: struct fields must be public in order for unmarshal to // correctly populate the data. type T struct { A string B struct { RenamedC int `yaml:"c"` D []int `yaml:",flow"` } } func main() { t := T{} err := yaml.Unmarshal([]byte(data), &t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t:\n%v\n\n", t) d, err := yaml.Marshal(&t) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- t dump:\n%s\n\n", string(d)) m := make(map[interface{}]interface{}) err = yaml.Unmarshal([]byte(data), &m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m:\n%v\n\n", m) d, err = yaml.Marshal(&m) if err != nil { log.Fatalf("error: %v", err) } fmt.Printf("--- m dump:\n%s\n\n", string(d)) } ``` -------------------------------- ### Load Slim-Sprig FuncMap in Go Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-task/slim-sprig/v3/README.md Load the Slim-Sprig FuncMap before parsing templates. Ensure the FuncMap is set prior to loading templates to avoid errors. ```go import ( "html/template" "github.com/go-task/slim-sprig" ) // This example illustrates that the FuncMap *must* be set before the // templates themselves are loaded. tpl := template.Must( template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html") ) ``` -------------------------------- ### Publish AMI for Standard AWS Regions Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Orchestrate the AMI creation workflow for standard AWS regions using the Publisher Package API. This involves configuring credentials, specifying AMI details, and using driver sets to publish the image. ```go package main import ( "os" "light-stemcell-builder/config" "light-stemcell-builder/driverset" "light-stemcell-builder/publisher" ) func main() { // For standard AWS regions (us-east-1, eu-west-1, etc.) creds := config.Credentials{ AccessKey: "AKIAIOSFODNN7EXAMPLE", SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", Region: "us-east-1", } publisherConfig := publisher.Config{ AmiRegion: config.AmiRegion{ RegionName: "us-east-1", BucketName: "my-bucket", Destinations: []string{"us-west-1", "us-west-2"}, }, AmiConfiguration: config.AmiConfiguration{ Description: "My custom stemcell", VirtualizationType: "hvm", Visibility: "public", Tags: map[string]string{ "distro": "ubuntu-jammy", "version": "1.0.0", }, }, } // Create standard region publisher and driver set ds := driverset.NewStandardRegionDriverSet(os.Stderr, creds) p := publisher.NewStandardRegionPublisher(os.Stderr, publisherConfig) imageConfig := publisher.MachineImageConfig{ LocalPath: "/path/to/root.img", FileFormat: "RAW", VolumeSizeGB: 0, // Auto-detect for RAW format } // Publish AMI (uploads to S3, creates snapshot, registers AMI, copies to destinations) amis, err := p.Publish(ds, imageConfig) if err != nil { panic(err) } // amis.GetAll() returns []resources.Ami with IDs for all regions for _, ami := range amis.GetAll() { // ami.ID - "ami-12345678" // ami.Region - "us-east-1", "us-west-1", etc. } } ``` -------------------------------- ### Run Ginkgo specs in parallel Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/ginkgo/v2/README.md Executes the test suite in parallel mode to improve performance. ```bash ginkgo -p ``` -------------------------------- ### Stub Fake Return Values Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Configure the fake to return specific values when called. ```go fake.DoThingsReturns(3, errors.New("the-error")) num, err := fake.DoThings("stuff", 5) Expect(num).To(Equal(3)) Expect(err).To(Equal(errors.New("the-error"))) ``` -------------------------------- ### Read and Write BOSH Stemcell Manifests Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Use the Manifest Package API to read an existing stemcell manifest (stemcell.MF), modify its fields such as adding published AMIs, and write the updated manifest to standard output. ```go package main import ( "bytes" "os" "light-stemcell-builder/manifest" "light-stemcell-builder/resources" ) func main() { // Read existing stemcell manifest manifestFile, _ := os.Open("stemcell.MF") defer manifestFile.Close() m, err := manifest.NewFromReader(manifestFile) if err != nil { panic(err) } // Access manifest fields // m.Name - "bosh-aws-xen-hvm-ubuntu-trusty-go_agent" // m.Version - "3202" // m.OperatingSystem - "ubuntu-trusty" // m.BoshProtocol - "1" // Add published AMIs from different regions m.PublishedAmis = []resources.Ami{ {ID: "ami-12345678", Region: "us-east-1", VirtualizationType: "hvm"}, {ID: "ami-87654321", Region: "us-west-2", VirtualizationType: "hvm"}, {ID: "ami-abcdef12", Region: "eu-west-1", VirtualizationType: "hvm"}, } // Write updated manifest to stdout err = m.Write(os.Stdout) if err != nil { panic(err) } // Output YAML: // name: bosh-aws-xen-hvm-ubuntu-trusty-go_agent // version: "3202" // stemcell_formats: // - aws-light // cloud_properties: // ami: // eu-west-1: ami-abcdef12 // us-east-1: ami-12345678 // us-west-2: ami-87654321 } ``` -------------------------------- ### Generate Fakes for Multiple Interfaces with counterfeiter:generate Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md When a package has multiple interfaces requiring fake implementations, use the `counterfeiter:generate` directive. This directive allows you to specify multiple interfaces within the same package for generation. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate //counterfeiter:generate . MySpecialInterface type MySpecialInterface interface { DoThings(string, uint64) (int, error) } //counterfeiter:generate . MyOtherInterface type MyOtherInterface interface { DoOtherThings(string, uint64) (int, error) } ``` -------------------------------- ### Pre-compile JMESPath Queries Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/jmespath/go-jmespath/README.md Compile a query once to reuse it for multiple search operations. ```go > var jsondata = []byte(`{"foo": "bar"}`) > var data interface{} > err := json.Unmarshal(jsondata, &data) > precompiled, err := Compile("foo") > if err != nil{ > // ... handle the error > } > result, err := precompiled.Search(data) result = "bar" ``` -------------------------------- ### Verify Fake Calls Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Use the generated methods to verify call counts and inspect arguments passed to the fake. ```go fake.DoThings("stuff", 5) Expect(fake.DoThingsCallCount()).To(Equal(1)) str, num := fake.DoThingsArgsForCall(0) Expect(str).To(Equal("stuff")) Expect(num).To(Equal(uint64(5))) ``` -------------------------------- ### Generate Fake for Single Interface with go:generate Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Add a `go:generate` directive to your Go file to automatically generate a fake implementation for a specific interface. This command runs `counterfeiter` during the `go generate` process. ```go //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . MySpecialInterface type MySpecialInterface interface { DoThings(string, uint64) (int, error) } ``` -------------------------------- ### Generate Fakes for Third-Party Interfaces Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Generate test doubles for external interfaces using the package path syntax. ```shell $ go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/go-redis/redis.Pipeliner ``` -------------------------------- ### Generate Test Doubles Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Generate a fake implementation for a specified interface within a Go package. ```shell $ cat path/to/foo/file.go ``` ```go package foo type MySpecialInterface interface { DoThings(string, uint64) (int, error) } ``` ```shell $ go run github.com/maxbrunsfeld/counterfeiter/v6 path/to/foo MySpecialInterface Wrote `FakeMySpecialInterface` to `path/to/foo/foofakes/fake_my_special_interface.go` ``` -------------------------------- ### Configure IAM Role Assumption for Publishing Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Configure credentials to assume an IAM role for cross-account or elevated privilege publishing. Ensure the role ARN is correctly specified. ```json { "ami_configuration": { "description": "Cross-account stemcell publishing", "virtualization_type": "hvm", "visibility": "public", "tags": { "distro": "ubuntu-jammy", "version": "1.0.0" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "role_arn": "arn:aws:iam::123456789012:role/StemcellPublisher" }, "bucket_name": "cross-account-bucket", "destinations": ["us-west-2"] } ] } ``` -------------------------------- ### Pass Logger to Other Objects Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-logr/logr/README.md Demonstrates how to pass the logr.Logger object to other parts of your application, such as structs or other libraries. ```go app := createTheAppObject(logger) app.Run() ``` -------------------------------- ### Log Messages from Application Code Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/go-logr/logr/README.md Shows how an application object uses its received logr.Logger to emit log messages. The logger can be stored in structs or used as a package-global variable. ```go type appObject struct { // ... other fields ... logger logr.Logger // ... other fields ... } func (app *appObject) Run() { app.logger.Info("starting up", "timestamp", time.Now()) // ... app code ... } ``` -------------------------------- ### Configure Non-Standard AWS Partition Publishing Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Use this configuration to publish stemcells to non-standard AWS partitions like EU Sovereign Cloud by specifying custom endpoint domains. ```json { "ami_configuration": { "description": "Stemcell for EU Sovereign Cloud", "virtualization_type": "hvm", "visibility": "private", "tags": { "distro": "ubuntu-jammy", "version": "1.0.0" } }, "ami_regions": [ { "name": "eusc-de-east-1", "endpoint_base": "amazonaws.eu", "credentials": { "access_key": "AKIAEUSC7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEUSCKEY" }, "bucket_name": "eusc-stemcell-bucket" } ] } ``` -------------------------------- ### Private AMI with Account Sharing Configuration Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Create private AMIs and configure sharing with specific AWS account IDs for controlled distribution. ```json { "ami_configuration": { "description": "Private stemcell shared with partner accounts", "virtualization_type": "hvm", "visibility": "private", "shared_with_accounts": [ "111122223333", "444455556666" ], "tags": { "distro": "ubuntu-jammy", "version": "2.0.0" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }, "bucket_name": "private-stemcell-bucket" } ] } ``` -------------------------------- ### Configure AWS IAM Policy for Publishing Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Defines the minimum required permissions for the publishing user to interact with S3 and EC2. ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:ListAllMyBuckets"], "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:DeleteBucket", "s3:DeleteObject", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::your-stemcell-bucket", "arn:aws:s3:::your-stemcell-bucket/*" ] }, { "Effect": "Allow", "Action": [ "ec2:CancelConversionTask", "ec2:CancelImportTask", "ec2:CopyImage", "ec2:CreateImage", "ec2:CreateSnapshot", "ec2:CreateTags", "ec2:CreateVolume", "ec2:DeleteTags", "ec2:DeleteVolume", "ec2:DescribeAvailabilityZones", "ec2:DescribeImages", "ec2:DescribeImportImageTasks", "ec2:DescribeImportSnapshotTasks", "ec2:DescribeSnapshots", "ec2:DescribeTags", "ec2:ImportImage", "ec2:ImportSnapshot", "ec2:ImportVolume", "ec2:ModifyImageAttribute", "ec2:ModifySnapshotAttribute", "ec2:RegisterImage" ], "Resource": "*" } ] } ``` -------------------------------- ### Invoke Counterfeiter from Shell Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/maxbrunsfeld/counterfeiter/v6/README.md Directly invoke `counterfeiter` from your shell within a Go module to generate fakes. This command provides various options for output path, fake name, and header files. ```shell go run github.com/maxbrunsfeld/counterfeiter/v6 USAGE counterfeiter [-generate>] [-o ] [-p] [--fake-name ] [-header ] [] [-] ``` -------------------------------- ### Publish AMI for Isolated AWS China Regions Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Handle AMI creation for isolated AWS China regions using the Isolated Region Publisher API. This method uses a volume-based snapshot creation workflow and requires specific configuration for isolated regions. ```go package main import ( "os" "light-stemcell-builder/config" "light-stemcell-builder/driverset" "light-stemcell-builder/publisher" ) func main() { // For isolated regions (cn-north-1) creds := config.Credentials{ AccessKey: "AKIACHINA7EXAMPLE", SecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYCHINAKEY", Region: "cn-north-1", } publisherConfig := publisher.Config{ AmiRegion: config.AmiRegion{ RegionName: "cn-north-1", BucketName: "china-bucket", IsolatedRegion: true, // Destinations not allowed for isolated regions }, AmiConfiguration: config.AmiConfiguration{ Description: "China region stemcell", VirtualizationType: "hvm", Visibility: "public", }, } // Create isolated region driver set (uses volume-based workflow) ds := driverset.NewIsolatedRegionDriverSet(os.Stderr, creds) p := publisher.NewIsolatedRegionPublisher(os.Stderr, publisherConfig) imageConfig := publisher.MachineImageConfig{ LocalPath: "/path/to/root.vmdk", FileFormat: "vmdk", VolumeSizeGB: 3, // Required for non-RAW formats } // Publish creates: machine image manifest -> volume -> snapshot -> AMI amis, err := p.Publish(ds, imageConfig) if err != nil { panic(err) } // amis contains single AMI for cn-north-1 } ``` -------------------------------- ### Search JSON with JMESPath Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/jmespath/go-jmespath/README.md Use jmespath.search to extract specific data from a JSON structure. ```go > import "github.com/jmespath/go-jmespath" > > var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data > var data interface{} > err := json.Unmarshal(jsondata, &data) > result, err := jmespath.Search("foo.bar.baz[2]", data) result = 2 ``` -------------------------------- ### Encrypted Stemcell Configuration Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Configure encrypted AMIs using KMS keys. Supports multi-region key replication and specifies server-side encryption for the S3 bucket. ```json { "ami_configuration": { "description": "Encrypted Ubuntu stemcell", "virtualization_type": "hvm", "visibility": "private", "encrypted": true, "kms_key_id": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012", "kms_key_alias_name": "alias/my-stemcell-key", "tags": { "distro": "ubuntu-jammy", "version": "1.0.0" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "AKIAIOSFODNN7EXAMPLE", "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }, "bucket_name": "encrypted-stemcell-bucket", "server_side_encryption": "AES256", "destinations": ["us-west-2"] } ] } ``` -------------------------------- ### Configure Multi-Region Stemcell Publishing Source: https://context7.com/cloudfoundry/bosh-aws-light-stemcell-builder/llms.txt Publish stemcells to multiple AWS regions simultaneously. Each region can have its own credentials and a list of destination regions for copying. ```json { "ami_configuration": { "description": "Global stemcell distribution", "virtualization_type": "hvm", "visibility": "public", "tags": { "distro": "ubuntu-jammy", "version": "3.0.0" } }, "ami_regions": [ { "name": "us-east-1", "credentials": { "access_key": "AKIAUSEAST1EXAMPLE", "secret_key": "useast1secretkey" }, "bucket_name": "us-east-stemcells", "destinations": ["us-west-1", "us-west-2"] }, { "name": "eu-west-1", "credentials": { "access_key": "AKIAEUWEST1EXAMPLE", "secret_key": "euwest1secretkey" }, "bucket_name": "eu-west-stemcells", "destinations": ["eu-central-1", "eu-north-1"] }, { "name": "ap-northeast-1", "credentials": { "access_key": "AKIAAPNE1EXAMPLE", "secret_key": "apne1secretkey" }, "bucket_name": "ap-stemcells", "destinations": ["ap-southeast-1", "ap-southeast-2"] } ] } ``` -------------------------------- ### Configure Custom AWS Endpoint Domain Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/README.md Override the default endpoint domain for non-standard AWS partitions by setting the endpoint_base property. ```json { "ami_regions": [ { "name": "eusc-de-east-1", "endpoint_base": "amazonaws.eu", "credentials": { "access_key": "ACCESS_KEY_ID", "secret_key": "ACCESS_SECRET_KEY" }, "bucket_name": "BUCKET_NAME" } ] } ``` -------------------------------- ### Update CHANGELOG.md Source: https://github.com/cloudfoundry/bosh-aws-light-stemcell-builder/blob/master/vendor/github.com/onsi/ginkgo/v2/RELEASING.md Use this bash script to automatically update the CHANGELOG.md file with recent git log entries. Ensure the CHANGELOG.md is categorized correctly after running. ```bash LAST_VERSION=$(git tag --sort=version:refname | tail -n1) CHANGES=$(git log --pretty=format:'- %s [%h]' HEAD...$LAST_VERSION) echo -e "## NEXT\n\n$CHANGES\n\n### Features\n\n### Fixes\n\n### Maintenance\n\n$(cat CHANGELOG.md)" > CHANGELOG.md ```