...

Source file src/github.com/opencontainers/image-spec/identity/chainid.go

Documentation: github.com/opencontainers/image-spec/identity

     1  // Copyright 2016 The Linux Foundation
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package identity provides implementations of subtle calculations pertaining
    16  // to image and layer identity.  The primary item present here is the ChainID
    17  // calculation used in identifying the result of subsequent layer applications.
    18  //
    19  // Helpers are also provided here to ease transition to the
    20  // github.com/opencontainers/go-digest package, but that package may be used
    21  // directly.
    22  package identity
    23  
    24  import "github.com/opencontainers/go-digest"
    25  
    26  // ChainID takes a slice of digests and returns the ChainID corresponding to
    27  // the last entry. Typically, these are a list of layer DiffIDs, with the
    28  // result providing the ChainID identifying the result of sequential
    29  // application of the preceding layers.
    30  func ChainID(dgsts []digest.Digest) digest.Digest {
    31  	chainIDs := make([]digest.Digest, len(dgsts))
    32  	copy(chainIDs, dgsts)
    33  	ChainIDs(chainIDs)
    34  
    35  	if len(chainIDs) == 0 {
    36  		return ""
    37  	}
    38  	return chainIDs[len(chainIDs)-1]
    39  }
    40  
    41  // ChainIDs calculates the recursively applied chain id for each identifier in
    42  // the slice. The result is written direcly back into the slice such that the
    43  // ChainID for each item will be in the respective position.
    44  //
    45  // By definition of ChainID, the zeroth element will always be the same before
    46  // and after the call.
    47  //
    48  // As an example, given the chain of ids `[A, B, C]`, the result `[A,
    49  // ChainID(A|B), ChainID(A|B|C)]` will be written back to the slice.
    50  //
    51  // The input is provided as a return value for convenience.
    52  //
    53  // Typically, these are a list of layer DiffIDs, with the
    54  // result providing the ChainID for each the result of each layer application
    55  // sequentially.
    56  func ChainIDs(dgsts []digest.Digest) []digest.Digest {
    57  	if len(dgsts) < 2 {
    58  		return dgsts
    59  	}
    60  
    61  	parent := digest.FromBytes([]byte(dgsts[0] + " " + dgsts[1]))
    62  	next := dgsts[1:]
    63  	next[0] = parent
    64  	ChainIDs(next)
    65  
    66  	return dgsts
    67  }
    68  

View as plain text