github.com/openshift/installer@v1.4.17/pkg/asset/releaseimage/default.go (about)

     1  package releaseimage
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  // This file handles correctly identifying the default release image, which is expected to be
     9  // replaced in the binary post-compile after being extracted from a payload. The expected modification is:
    10  //
    11  // 1. Extract a release binary from the installer image referenced within the release image
    12  // 2. Identify the release image pull spec, add a NUL terminator byte (0x00) to the end, calculate length
    13  // 3. Length must be less than the marker length
    14  // 4. Search through the installer binary looking for `\x00_RELEASE_IMAGE_LOCATION_\x00<PADDING_TO_LENGTH>`
    15  //    where padding is the ASCII character X and length is the total length of the marker
    16  // 5. Overwrite the beginning of the marker with the release pullspec and a NUL terminator byte (0x00)
    17  //
    18  // On start the installer examines the constant and if it has been modified from the default the installer
    19  // will use that image.
    20  
    21  var (
    22  	// defaultReleaseImageOriginal is the value served when defaultReleaseImagePadded is unmodified.
    23  	defaultReleaseImageOriginal = "registry.ci.openshift.org/origin/release:4.16"
    24  	// defaultReleaseImagePadded may be replaced in the binary with a pull spec that overrides defaultReleaseImage as
    25  	// a null-terminated string within the allowed character length. This allows a distributor to override the payload
    26  	// location without having to rebuild the source.
    27  	defaultReleaseImagePadded = "\x00_RELEASE_IMAGE_LOCATION_\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00"
    28  	defaultReleaseImagePrefix = "\x00_RELEASE_IMAGE_LOCATION_\x00"
    29  	defaultReleaseImageLength = len(defaultReleaseImagePadded)
    30  )
    31  
    32  // Default abstracts how the binary loads the default release payload. We want to lock the binary
    33  // to the pull spec of the payload we test it with, and since a payload contains an installer image we can't
    34  // know that at build time. Instead, we make it possible to replace the release string after build via a
    35  // known constant in the binary.
    36  func Default() (string, error) {
    37  	if strings.HasPrefix(defaultReleaseImagePadded, defaultReleaseImagePrefix) {
    38  		// the defaultReleaseImagePadded constant hasn't been altered in the binary, fall back to the default
    39  		return defaultReleaseImageOriginal, nil
    40  	}
    41  	nullTerminator := strings.IndexByte(defaultReleaseImagePadded, '\x00')
    42  	if nullTerminator == -1 {
    43  		// the binary has been altered, but we didn't find a null terminator within the constant which is an error
    44  		return "", fmt.Errorf("release image location was replaced but without a null terminator before %d bytes", defaultReleaseImageLength)
    45  	}
    46  	if nullTerminator > len(defaultReleaseImagePadded) {
    47  		// the binary has been altered, but the null terminator is *longer* than the constant encoded in the binary
    48  		return "", fmt.Errorf("release image location contains no null-terminator and constant is corrupted")
    49  	}
    50  	pullspec := defaultReleaseImagePadded[:nullTerminator]
    51  	if len(pullspec) == 0 {
    52  		// the binary has been altered, but the replaced image is empty which is incorrect
    53  		return "", fmt.Errorf("release image location is empty, this binary was incorrectly generated")
    54  	}
    55  	return pullspec, nil
    56  }