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 }