github.com/coreos/mantle@v0.13.0/update/metadata/update_metadata.proto (about)

     1  // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package chromeos_update_engine;
     6  
     7  // Update file format: A delta update file contains all the deltas needed
     8  // to update a system from one specific version to another specific
     9  // version. The update format is represented by this struct pseudocode:
    10  // struct delta_update_file {
    11  //   char magic[4] = "CrAU";
    12  //   uint64 file_format_version = 1;
    13  //   uint64 manifest_size;  // Size of protobuf DeltaArchiveManifest
    14  //   // The Bzip2 compressed DeltaArchiveManifest
    15  //   char manifest[];
    16  //
    17  //   // Data blobs for files, no specific format. The specific offset
    18  //   // and length of each data blob is recorded in the DeltaArchiveManifest.
    19  //   struct {
    20  //     char data[];
    21  //   } blobs[];
    22  //
    23  //   // These two are not signed:
    24  //   uint64 signatures_message_size;
    25  //   char signatures_message[];
    26  //
    27  // };
    28  
    29  // The DeltaArchiveManifest protobuf is an ordered list of InstallOperation
    30  // objects. These objects are stored in a linear array in the
    31  // DeltaArchiveManifest. Each operation is applied in order by the client.
    32  
    33  // The DeltaArchiveManifest also contains the initial and final
    34  // checksums for the device.
    35  
    36  // The client will perform each InstallOperation in order, beginning even
    37  // before the entire delta file is downloaded (but after at least the
    38  // protobuf is downloaded). The types of operations are explained:
    39  // - REPLACE: Replace the dst_extents on the drive with the attached data,
    40  //   zero padding out to block size.
    41  // - REPLACE_BZ: bzip2-uncompress the attached data and write it into
    42  //   dst_extents on the drive, zero padding to block size.
    43  // - MOVE: Copy the data in src_extents to dst_extents. Extents may overlap,
    44  //   so it may be desirable to read all src_extents data into memory before
    45  //   writing it out.
    46  // - BSDIFF: Read src_length bytes from src_extents into memory, perform
    47  //   bspatch with attached data, write new data to dst_extents, zero padding
    48  //   to block size.
    49  message InstallOperation {
    50    enum Type {
    51      REPLACE = 0;  // Replace destination extents w/ attached data
    52      REPLACE_BZ = 1;  // Replace destination extents w/ attached bzipped data
    53      MOVE = 2;  // Move source extents to destination extents
    54      BSDIFF = 3;  // The data is a bsdiff binary diff
    55    }
    56    required Type type = 1;
    57    // The offset into the delta file (after the protobuf)
    58    // where the data (if any) is stored
    59    optional uint32 data_offset = 2;
    60    // The length of the data in the delta file
    61    optional uint32 data_length = 3;
    62  
    63    // Ordered list of extents that are read from (if any) and written to.
    64    repeated Extent src_extents = 4;
    65    // Byte length of src, not necessarily block aligned. It's only used for
    66    // BSDIFF, because we need to pass that external program the number
    67    // of bytes to read from the blocks we pass it.
    68    optional uint64 src_length = 5;
    69  
    70    repeated Extent dst_extents = 6;
    71    // byte length of dst, not necessarily block aligned. It's only used for
    72    // BSDIFF, because we need to fill in the rest of the last block
    73    // that bsdiff writes with '\0' bytes.
    74    optional uint64 dst_length = 7;
    75  
    76    // Optional SHA 256 hash of the blob associated with this operation.
    77    // This is used as a primary validation for http-based downloads and
    78    // as a defense-in-depth validation for https-based downloads. If
    79    // the operation doesn't refer to any blob, this field will have
    80    // zero bytes.
    81    optional bytes data_sha256_hash = 8;
    82  }
    83  
    84  // Data is packed into blocks on disk, always starting from the beginning
    85  // of the block. If a file's data is too large for one block, it overflows
    86  // into another block, which may or may not be the following block on the
    87  // physical partition. An ordered list of extents is another
    88  // representation of an ordered list of blocks. For example, a file stored
    89  // in blocks 9, 10, 11, 2, 18, 12 (in that order) would be stored in
    90  // extents { {9, 3}, {2, 1}, {18, 1}, {12, 1} } (in that order).
    91  // In general, files are stored sequentially on disk, so it's more efficient
    92  // to use extents to encode the block lists (this is effectively
    93  // run-length encoding).
    94  // A sentinel value (UINT64_MAX) as the start block denotes a sparse-hole
    95  // in a file whose block-length is specified by num_blocks.
    96  message Extent {
    97    optional uint64 start_block = 1;
    98    optional uint64 num_blocks = 2;
    99  }
   100  
   101  // Signatures: Updates may be signed by the OS vendor. The client verifies
   102  // an update's signature by hashing the entire download. The section of the
   103  // download that contains the signature is at the end of the file, so when
   104  // signing a file, only the part up to the signature part is signed.
   105  // Then, the client looks inside the download's Signatures message for a
   106  // Signature message that it knows how to handle. Generally, a client will
   107  // only know how to handle one type of signature, but an update may contain
   108  // many signatures to support many different types of client. Then client
   109  // selects a Signature message and uses that, along with a known public key,
   110  // to verify the download. The public key is expected to be part of the
   111  // client.
   112  message Signatures {
   113    message Signature {
   114      optional uint32 version = 1;
   115      optional bytes data = 2;
   116    }
   117    repeated Signature signatures = 1;
   118  }
   119  
   120  // Info is used to validate the source prior to the update or
   121  // the destination after the list of InstallOperations has run.
   122  
   123  message InstallInfo {
   124    optional uint64 size = 1;
   125    optional bytes hash = 2;
   126  }
   127  
   128  // InstallProcedure defines the update procedure for a single file or block
   129  // device (except for /usr which is in DeltaArchiveManifest).
   130  message InstallProcedure {
   131    enum Type {
   132      KERNEL = 0;  // A kernel image to install to the boot partition.
   133    }
   134    required Type type = 1;
   135  
   136    repeated InstallOperation operations = 2;
   137  
   138    optional InstallInfo old_info = 3;
   139    optional InstallInfo new_info = 4;
   140  }
   141  
   142  message DeltaArchiveManifest {
   143    // The update procedure for the main partition (USR-A or USR-B). Once
   144    // complete it should match the hash specified in new_partition_info.
   145    repeated InstallOperation partition_operations = 1;
   146  
   147    // This field is maintained for compatibility with older update_engine
   148    // clients. In the ChromeOS days it covered the kernel partition but in
   149    // CoreOS it has only been used to insert a dummy operation to account for
   150    // the signatures tacked onto the end of the payload. The code was not smart
   151    // enough to stop passing data to the filesystem writer code after the
   152    // signatures_offset had been reached, instead using the magic punch-hole
   153    // value to skip over the extra data. Since CoreOS versions of update_engine
   154    // only partially removed support kernel partitions passing anything other
   155    // than dummy operations will trigger broken code paths but omitting the
   156    // dummy operations will fail when the filesystem writer receives unexpected
   157    // data. Therefore to work with old versions it strictly *must* look like:
   158    //
   159    //   noop_operations: {
   160    //     type: REPLACE
   161    //     data_offset: signatures_offset
   162    //     data_length: signatures_size
   163    //     dst_extents: {
   164    //       start_block: UINT64_MAX
   165    //       num_blocks: (signature_size + block_size - 1) / block_size
   166    //     }
   167    //   }
   168    //
   169    repeated InstallOperation noop_operations = 2;
   170  
   171    // (At time of writing) usually 4096
   172    optional uint32 block_size = 3 [default = 4096];
   173  
   174    // If signatures are present, the offset into the blobs, generally
   175    // tacked onto the end of the file, and the length. We use an offset
   176    // rather than a bool to allow for more flexibility in future file formats.
   177    // If either is absent, it means signatures aren't supported in this
   178    // file.
   179    optional uint64 signatures_offset = 4;
   180    optional uint64 signatures_size = 5;
   181  
   182    // Deprecated IDs 6 and 7, do not reuse.
   183  
   184    // Partition data that can be used to validate the update.
   185    optional InstallInfo old_partition_info = 8;
   186    optional InstallInfo new_partition_info = 9;
   187  
   188    // In addition to the partition update, process updates for additional
   189    // files, such as kernels. Versions of update_engine that can interpret
   190    // this list *MUST* ignore noop_operations and properly account for the
   191    // signature data at the end of the payload.
   192    repeated InstallProcedure procedures = 10;
   193  }