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 }