diff --git a/.gitignore b/.gitignore index 995b532..aada1d3 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,12 @@ # End of https://www.toptal.com/developers/gitignore/api/go,vscode +chromeos_update_engine/build/ *.zip -**/payload.bin - +**/payload*.bin +payload-dumper-go extracted_*/ +*.img + .DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b308778 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,18 @@ +[submodule "chromeos_update_engine/brotli"] + path = chromeos_update_engine/brotli + url = https://github.com/anonymix007/brotli +[submodule "chromeos_update_engine/bsdiff"] + path = chromeos_update_engine/bsdiff + url = https://github.com/anonymix007/bsdiff +[submodule "chromeos_update_engine/bzip2"] + path = chromeos_update_engine/bzip2 + url = https://github.com/anonymix007/bzip2 +[submodule "chromeos_update_engine/libchrome"] + path = chromeos_update_engine/libchrome + url = https://github.com/anonymix007/libchrome +[submodule "chromeos_update_engine/puffin"] + path = chromeos_update_engine/puffin + url = https://github.com/anonymix007/puffin +[submodule "chromeos_update_engine/zucchini"] + path = chromeos_update_engine/zucchini + url = https://github.com/anonymix007/zucchini diff --git a/README.md b/README.md index dbde76c..dd30fba 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ See how fast payload-dumper-go is: https://imgur.com/a/X6HKJT4. (MacBook Pro 16- ### Limitations -- Incremental OTA (delta) payload is not supported. +- Incremental OTA (delta) payload is not fully tested and probably broken. ## Installation @@ -56,6 +56,20 @@ payload-dumper-go /path/to/payload.bin https://android.googlesource.com/platform/system/update_engine/+/master/update_metadata.proto +## Compilation + +### Linux and OSX +``` +git submodule update --init --recursive +go generate chromeos_update_engine/update_engine.go +go build . +``` + +### Windows + +#### TODO + + ## License This source code is licensed under the Apache License 2.0 as described in the LICENSE file. diff --git a/chromeos_update_engine/Makefile b/chromeos_update_engine/Makefile new file mode 100644 index 0000000..fa9d899 --- /dev/null +++ b/chromeos_update_engine/Makefile @@ -0,0 +1,60 @@ +CXXFLAGS=-std=gnu++17 +CFLAGS=-I. -Ibsdiff/include -Ipuffin/src/include -Izucchini/aosp/include -Ilibchrome -Igtest/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Ibuild -ggdb +LDFLAGS=-Wl,--copy-dt-needed-entries -labsl_log_internal_check_op + +libs: build build/libbrotli.a build/libbspatch.a build/libbz2.a build/libpuffpatch.a build/libzucchini.a build/libchrome.a + +build: + mkdir -p $@ + +build/%.o: %.cc + @ mkdir -p $(dir $@) + $(CXX) $(CFLAGS) $(CXXFLAGS) -c -o $@ $< $(LDFLAGS) + +build/%.o: %.c + @ mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< $(LDFLAGS) + +BSPATCH_SRC=bsdiff/brotli_decompressor.cc bsdiff/bspatch.cc bsdiff/bz2_decompressor.cc bsdiff/buffer_file.cc bsdiff/decompressor_interface.cc bsdiff/extents.cc bsdiff/extents_file.cc bsdiff/file.cc bsdiff/logging.cc bsdiff/memory_file.cc bsdiff/patch_reader.cc bsdiff/sink_file.cc bsdiff/utils.cc +BSPATCH_OBJ=$(addprefix build/,$(BSPATCH_SRC:.cc=.o)) + +build/libbspatch.a: $(BSPATCH_OBJ) + $(AR) rcs $@ $^ + +BROTLI_SRC=$(wildcard brotli/c/common/*.c brotli/c/dec/*.c brotli/c/enc/*.c) +BROTLI_OBJ=$(addprefix build/,$(BROTLI_SRC:.c=.o)) + +build/libbrotli.a: $(BROTLI_OBJ) + $(AR) rcs $@ $^ + +BZ2_SRC=bzip2/blocksort.c bzip2/huffman.c bzip2/crctable.c bzip2/randtable.c bzip2/compress.c bzip2/decompress.c bzip2/bzlib.c +BZ2_OBJ=$(addprefix build/,$(BZ2_SRC:.c=.o)) + +build/libbz2.a: $(BZ2_OBJ) + $(AR) rcs $@ $^ + +PUFFPATCH_SRC=puffin/src/bit_reader.cc puffin/src/bit_writer.cc puffin/src/brotli_util.cc puffin/src/huffer.cc puffin/src/huffman_table.cc puffin/src/memory_stream.cc puffin/src/puff_reader.cc puffin/src/puff_writer.cc puffin/src/puffer.cc puffin/src/puffin_stream.cc puffin/src/puffpatch.cc puffin/src/puffin.pb.cc +PUFFPATCH_OBJ=$(addprefix build/,$(PUFFPATCH_SRC:.cc=.o)) + +puffin/src/puffpatch.cc: build/puffin/src/puffin.pb.cc +build/puffin/src/puffin.pb.cc: puffin/src/puffin.proto + protoc -I=puffin/src/ --cpp_out=build/puffin/src/ $^ + +build/libpuffpatch.a: $(PUFFPATCH_OBJ) + $(AR) rcs $@ $^ + +ZUCHIINI_SRC=zucchini/abs32_utils.cc zucchini/address_translator.cc zucchini/arm_utils.cc zucchini/binary_data_histogram.cc zucchini/buffer_sink.cc zucchini/buffer_source.cc zucchini/crc32.cc zucchini/disassembler.cc zucchini/disassembler_dex.cc zucchini/disassembler_elf.cc zucchini/disassembler_no_op.cc zucchini/disassembler_win32.cc zucchini/disassembler_ztf.cc zucchini/element_detection.cc zucchini/encoded_view.cc zucchini/ensemble_matcher.cc zucchini/equivalence_map.cc zucchini/heuristic_ensemble_matcher.cc zucchini/image_index.cc zucchini/imposed_ensemble_matcher.cc zucchini/io_utils.cc zucchini/patch_reader.cc zucchini/patch_writer.cc zucchini/reference_bytes_mixer.cc zucchini/reference_set.cc zucchini/rel32_finder.cc zucchini/rel32_utils.cc zucchini/reloc_elf.cc zucchini/reloc_win32.cc zucchini/target_pool.cc zucchini/targets_affinity.cc zucchini/zucchini_apply.cc zucchini/zucchini_gen.cc zucchini/zucchini_tools.cc +ZUCCHINI_OBJ=$(addprefix build/,$(ZUCHIINI_SRC:.cc=.o)) + +build/libzucchini.a: $(ZUCCHINI_OBJ) + $(AR) rcs $@ $^ +#CHROME_SRC=$(wildcard libchrome/base/third_party/*/*.cc libchrome/base/synchronization/*.cc libchrome/base/strings/*.cc libchrome/base/metrics/*.c libchrome/base/timer/*.cc libchrome/base/time/*.cc libchrome/base/process/*.cc libchrome/base/posix/*.cc libchrome/base/memory/*.cc libchrome/base/debug/*.cc libchrome/base/files/*.cc libchrome/base/*.cc ) +CHROME_SRC=$(wildcard libchrome/base/third_party/*/*.cc libchrome/base/*/*.cc libchrome/base/*.cc) +CHROME_OBJ=$(addprefix build/,$(CHROME_SRC:.cc=.o)) + +build/libchrome.a: $(CHROME_OBJ) + $(AR) rcs $@ $^ + +ALL_OBJ=build/ +clean: + rm -rf $(ALL_OBJ) diff --git a/chromeos_update_engine/brotli b/chromeos_update_engine/brotli new file mode 160000 index 0000000..ee905ca --- /dev/null +++ b/chromeos_update_engine/brotli @@ -0,0 +1 @@ +Subproject commit ee905ca58e9835b665ea5d028ace7d43ba63a1b7 diff --git a/chromeos_update_engine/bsdiff b/chromeos_update_engine/bsdiff new file mode 160000 index 0000000..257fb6c --- /dev/null +++ b/chromeos_update_engine/bsdiff @@ -0,0 +1 @@ +Subproject commit 257fb6c620057942b282352cb8d22e9a4d464b41 diff --git a/chromeos_update_engine/bzip2 b/chromeos_update_engine/bzip2 new file mode 160000 index 0000000..0aa4760 --- /dev/null +++ b/chromeos_update_engine/bzip2 @@ -0,0 +1 @@ +Subproject commit 0aa4760e905236d21b7463a800b2bd748fc47d7e diff --git a/chromeos_update_engine/glog/gtest_prod_util.h b/chromeos_update_engine/glog/gtest_prod_util.h new file mode 100644 index 0000000..9ea870f --- /dev/null +++ b/chromeos_update_engine/glog/gtest_prod_util.h @@ -0,0 +1,11 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_GTEST_PROD_UTIL_H_ +#define BASE_GTEST_PROD_UTIL_H_ + +#define FRIEND_TEST_ALL_PREFIXES(...) +#define FORWARD_DECLARE_TEST(...) + +#endif // BASE_GTEST_PROD_UTIL_H_ diff --git a/chromeos_update_engine/glog/logging.h b/chromeos_update_engine/glog/logging.h new file mode 100644 index 0000000..1216d0e --- /dev/null +++ b/chromeos_update_engine/glog/logging.h @@ -0,0 +1,150 @@ +#ifndef CPP_LOGGING_H_ +#define CPP_LOGGING_H_ + +#include +#include +#include +#include +#include + +//#include "base/template_util.h" + +#ifndef DCHECK_IS_ON +#define DCHECK_IS_ON() 1 +#endif + +#ifndef EAT_STREAM_PARAMETERS +#define EAT_STREAM_PARAMETERS +#endif + + +#ifndef NOTREACHED +#define NOTREACHED() DCHECK(false) +#endif + +#ifndef ANALYZER_SKIP_THIS_PATH +#define ANALYZER_SKIP_THIS_PATH() +#endif + +#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS +#define DISALLOW_IMPLICIT_CONSTRUCTORS(...) +#endif + +#ifndef LOG +#define LOG(level) std::cout << #level << ": " +#endif + +#ifndef LOG_IF +#define LOG_IF(level, cond) if (cond) {} else LOG(level) +#endif + +#ifndef DLOG_IF +#define DLOG_IF(level, cond) if (cond) {} else LOG(level) +#endif + +#ifndef CHECK +#define CHECK(...) if (__VA_ARGS__) {} else std::cout << "Check failed" +#endif + +#ifndef PCHECK +#define PCHECK CHECK +#endif + +#ifndef DPCHECK +#define DPCHECK CHECK +#endif + +#ifndef DLOG +#define DLOG(level) LOG(level) +#endif + +#ifndef VLOG +#define VLOG(level) LOG(level) +#endif + +#ifndef PLOG +#define PLOG(level) LOG(level) +#endif + +#ifndef DVLOG +#define DVLOG(level) LOG(level) +#endif + +#ifndef DPLOG +#define DPLOG(level) LOG(level) +#endif + +#ifndef DVPLOG +#define DVPLOG(level) LOG(level) +#endif + +#ifndef VPLOG +#define VPLOG(level) LOG(level) +#endif + +#ifndef RAW_CHECK +#define RAW_CHECK(...) assert(__VA_ARGS__) +#endif + +#ifndef RAW_LOG +#define RAW_LOG(level, ...) LOG(level) << __VA_ARGS__ +#endif + +#ifndef DCHECK +#define DCHECK CHECK +#endif + +#ifndef DCHECK_GT +#define DCHECK_GT CHECK_GT +#endif + +#ifndef DCHECK_GE +#define DCHECK_GE CHECK_GE +#endif + +#ifndef DCHECK_LT +#define DCHECK_LT CHECK_LT +#endif + +#ifndef DCHECK_LE +#define DCHECK_LE CHECK_LE +#endif + +#ifndef DCHECK_NE +#define DCHECK_NE CHECK_NE +#endif + +#ifndef DCHECK_EQ +#define DCHECK_EQ CHECK_EQ +#endif + +#ifndef CHECK_OP +#define CHECK_OP(a, b, op) CHECK((a) op (b)) +#endif + + +#ifndef CHECK_GT +#define CHECK_GT(a, b) CHECK_OP(a, b, >) +#endif + +#ifndef CHECK_GE +#define CHECK_GE(a, b) CHECK_OP(a, b, >=) +#endif + +#ifndef CHECK_LT +#define CHECK_LT(a, b) CHECK_OP(a, b, <) +#endif + +#ifndef CHECK_LE +#define CHECK_LE(a, b) CHECK_OP(a, b, <=) +#endif + +#ifndef CHECK_NE +#define CHECK_NE(a, b) CHECK_OP(a, b, !=) +#endif + +#ifndef CHECK_EQ +#define CHECK_EQ(a, b) CHECK_OP(a, b, ==) +#endif + +#endif /* CPP_LOGGING_H_ */ diff --git a/chromeos_update_engine/libchrome b/chromeos_update_engine/libchrome new file mode 160000 index 0000000..0b07629 --- /dev/null +++ b/chromeos_update_engine/libchrome @@ -0,0 +1 @@ +Subproject commit 0b0762935b07e6c96d4722c5ece6c38075ad5431 diff --git a/chromeos_update_engine/puffin b/chromeos_update_engine/puffin new file mode 160000 index 0000000..b1088cf --- /dev/null +++ b/chromeos_update_engine/puffin @@ -0,0 +1 @@ +Subproject commit b1088cf39feb2e8283e116ec1ec8b145fb63a5f3 diff --git a/chromeos_update_engine/update_engine.cc b/chromeos_update_engine/update_engine.cc new file mode 100644 index 0000000..8ab262a --- /dev/null +++ b/chromeos_update_engine/update_engine.cc @@ -0,0 +1,95 @@ +#include "update_engine.h" +#include +#include +#include +#include + +class PuffinDataStream : public puffin::StreamInterface { + public: + PuffinDataStream(void *data, uint64_t size, bool is_read) + : data_(data), + size_(size), + offset_(0), + is_read_(is_read) {} + + ~PuffinDataStream() override = default; + + bool GetSize(uint64_t* size) const override { + *size = size_; + return true; + } + + bool GetOffset(uint64_t* offset) const override { + *offset = offset_; + return true; + } + + bool Seek(uint64_t offset) override { + if (is_read_) { + offset_ = offset; + } else { + // For writes technically there should be no change of position, or it + // should equivalent of current offset. + return offset_ != offset; + } + return true; + } + + bool Read(void* buffer, size_t count) override { + if (offset_ + count >= size_ || !is_read_) return false; + std::memcpy(buffer, data_, count); + offset_ += count; + return true; + } + + bool Write(const void* buffer, size_t count) override { + if (offset_ + count >= size_ || is_read_) return false; + std::memcpy(data_, buffer, count); + offset_ += count; + return true; + } + + bool Close() override { return true; } + + private: + + void *data_; + uint64_t size_; + uint64_t offset_; + bool is_read_; + + DISALLOW_COPY_AND_ASSIGN(PuffinDataStream); +}; + +extern "C" int64_t ExecuteSourcePuffDiffOperation(void *data, size_t data_size, + void *patch, size_t patch_size, + void *output, size_t output_size) { + constexpr size_t kMaxCacheSize = 5 * 1024 * 1024; // Total 5MB cache. + + puffin::UniqueStreamPtr src(new PuffinDataStream(data, data_size, true)); + puffin::UniqueStreamPtr dst(new PuffinDataStream(output, output_size, true)); + + return puffin::PuffPatch(std::move(src), std::move(dst), (const uint8_t *) patch, patch_size, kMaxCacheSize) ? -1 : output_size; +} + + +extern "C" int64_t ExecuteSourceBsdiffOperation(void *data, size_t data_size, + void *patch, size_t patch_size, + void *output, size_t output_size) { + + size_t written = 0; + + auto sink = [output, &written, output_size](const uint8_t *data, size_t count) -> size_t { + written += count; + if (written >= output_size) { + return 0; + } + std::memcpy(output, data, count); + return count; + }; + + int result = bsdiff::bspatch((const uint8_t *) data, data_size, (const uint8_t *) patch, patch_size, sink); + + return result == 0 ? written : -result; + +} diff --git a/chromeos_update_engine/update_engine.go b/chromeos_update_engine/update_engine.go new file mode 100644 index 0000000..f69f9ab --- /dev/null +++ b/chromeos_update_engine/update_engine.go @@ -0,0 +1,55 @@ +package chromeos_update_engine + +//go:generate make -B -j libs + +/* +#cgo CXXFLAGS: -Ibsdiff/include -Ipuffin/src/include +#cgo LDFLAGS: -labsl_log_internal_message -Lbuild -l:libpuffpatch.a -l:libbspatch.a -l:libzucchini.a -l:libbz2.a -l:libbrotli.a -l:libchrome.a -labsl_log_internal_check_op -lprotobuf +#include "update_engine.h" +*/ +import "C" +import ( + "unsafe" + "fmt" +) + +func ExecuteSourceBsdiffOperation(data []byte, patch []byte) ([]byte, error) { + output := make([]byte, len(data)) + result := int(C.ExecuteSourceBsdiffOperation( + unsafe.Pointer(&data[0]), C.ulong(len(data)), + unsafe.Pointer(&patch[0]), C.ulong(len(patch)), + unsafe.Pointer(&output[0]), C.ulong(len(output)), + )) + + if result < 0{ + return nil, fmt.Errorf("C++ ExecuteSourceBsdiffOperation call failed (returned %d)", result) + } + + if (result != len(output)) { + realloc := make([]byte, result) + copy(realloc, output) + return realloc, nil + } + + return output, nil +} + +func ExecuteSourcePuffDiffOperation(data []byte, patch []byte) ([]byte, error) { + output := make([]byte, len(data)) + result := int(C.ExecuteSourcePuffDiffOperation( + unsafe.Pointer(&data[0]), C.ulong(len(data)), + unsafe.Pointer(&patch[0]), C.ulong(len(patch)), + unsafe.Pointer(&output[0]), C.ulong(len(output)), + )) + if result < 0{ + return nil, fmt.Errorf("C++ ExecuteSourcePuffDiffOperation call failed (returned %d)", result) + } + + if (result != len(output)) { + realloc := make([]byte, result) + copy(realloc, output) + return realloc, nil + } + + return output, nil +} diff --git a/chromeos_update_engine/update_engine.h b/chromeos_update_engine/update_engine.h new file mode 100644 index 0000000..1d4f991 --- /dev/null +++ b/chromeos_update_engine/update_engine.h @@ -0,0 +1,25 @@ +#ifndef BSDIFF4_IMPL_H +#define BSDIFF4_IMPL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int64_t ExecuteSourceBsdiffOperation(void *data, size_t data_size, + void *patch, size_t patch_size, + void *output, size_t output_size); + +int64_t ExecuteSourcePuffDiffOperation(void *data, size_t data_size, + void *patch, size_t patch_size, + void *output, size_t output_size); + + + +#ifdef __cplusplus +} +#endif + +#endif /* BSDIFF4_IMPL_H */ diff --git a/chromeos_update_engine/update_metadata.pb.go b/chromeos_update_engine/update_metadata.pb.go index a9108ef..1174ac1 100644 --- a/chromeos_update_engine/update_metadata.pb.go +++ b/chromeos_update_engine/update_metadata.pb.go @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + // Update file format: An update file contains all the operations needed // to update a system to a specific version. It can be a full payload which // can update from any version, or a delta payload which can only update @@ -48,11 +49,14 @@ // char payload_signatures_message[payload_signatures_message_size]; // // }; + // The DeltaArchiveManifest protobuf is an ordered list of InstallOperation // objects. These objects are stored in a linear array in the // DeltaArchiveManifest. Each operation is applied in order by the client. + // The DeltaArchiveManifest also contains the initial and final // checksums for the device. + // The client will perform each InstallOperation in order, beginning even // before the entire delta file is downloaded (but after at least the // protobuf is downloaded). The types of operations are explained: @@ -87,14 +91,13 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.25.0 -// protoc v3.13.0 +// protoc-gen-go v1.32.0 +// protoc v5.27.0--dev // source: update_metadata.proto package chromeos_update_engine import ( - proto "github.com/golang/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -108,18 +111,14 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - type InstallOperation_Type int32 const ( InstallOperation_REPLACE InstallOperation_Type = 0 // Replace destination extents w/ attached data. InstallOperation_REPLACE_BZ InstallOperation_Type = 1 // Replace destination extents w/ attached bzipped data. - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in update_metadata.proto. InstallOperation_MOVE InstallOperation_Type = 2 // Move source extents to target extents. - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in update_metadata.proto. InstallOperation_BSDIFF InstallOperation_Type = 3 // The data is a bsdiff binary diff. // On minor version 2 or newer, these operations are supported: InstallOperation_SOURCE_COPY InstallOperation_Type = 4 // Copy from source to target partition @@ -133,6 +132,11 @@ const ( InstallOperation_BROTLI_BSDIFF InstallOperation_Type = 10 // Like SOURCE_BSDIFF, but compressed with brotli. // On minor version 5 or newer, these operations are supported: InstallOperation_PUFFDIFF InstallOperation_Type = 9 // The data is in puffdiff format. + // On minor version 8 or newer, these operations are supported: + InstallOperation_ZUCCHINI InstallOperation_Type = 11 + // On minor version 9 or newer, these operations are supported: + InstallOperation_LZ4DIFF_BSDIFF InstallOperation_Type = 12 + InstallOperation_LZ4DIFF_PUFFDIFF InstallOperation_Type = 13 ) // Enum value maps for InstallOperation_Type. @@ -149,19 +153,25 @@ var ( 7: "DISCARD", 10: "BROTLI_BSDIFF", 9: "PUFFDIFF", + 11: "ZUCCHINI", + 12: "LZ4DIFF_BSDIFF", + 13: "LZ4DIFF_PUFFDIFF", } InstallOperation_Type_value = map[string]int32{ - "REPLACE": 0, - "REPLACE_BZ": 1, - "MOVE": 2, - "BSDIFF": 3, - "SOURCE_COPY": 4, - "SOURCE_BSDIFF": 5, - "REPLACE_XZ": 8, - "ZERO": 6, - "DISCARD": 7, - "BROTLI_BSDIFF": 10, - "PUFFDIFF": 9, + "REPLACE": 0, + "REPLACE_BZ": 1, + "MOVE": 2, + "BSDIFF": 3, + "SOURCE_COPY": 4, + "SOURCE_BSDIFF": 5, + "REPLACE_XZ": 8, + "ZERO": 6, + "DISCARD": 7, + "BROTLI_BSDIFF": 10, + "PUFFDIFF": 9, + "ZUCCHINI": 11, + "LZ4DIFF_BSDIFF": 12, + "LZ4DIFF_PUFFDIFF": 13, } ) @@ -199,22 +209,28 @@ func (x *InstallOperation_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use InstallOperation_Type.Descriptor instead. func (InstallOperation_Type) EnumDescriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{4, 0} + return file_update_metadata_proto_rawDescGZIP(), []int{3, 0} } type CowMergeOperation_Type int32 const ( - CowMergeOperation_COW_COPY CowMergeOperation_Type = 0 // identical blocks + CowMergeOperation_COW_COPY CowMergeOperation_Type = 0 // identical blocks + CowMergeOperation_COW_XOR CowMergeOperation_Type = 1 // used when src/dst blocks are highly similar + CowMergeOperation_COW_REPLACE CowMergeOperation_Type = 2 // Raw replace operation ) // Enum value maps for CowMergeOperation_Type. var ( CowMergeOperation_Type_name = map[int32]string{ 0: "COW_COPY", + 1: "COW_XOR", + 2: "COW_REPLACE", } CowMergeOperation_Type_value = map[string]int32{ - "COW_COPY": 0, + "COW_COPY": 0, + "COW_XOR": 1, + "COW_REPLACE": 2, } ) @@ -252,21 +268,9 @@ func (x *CowMergeOperation_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use CowMergeOperation_Type.Descriptor instead. func (CowMergeOperation_Type) EnumDescriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{5, 0} -} - -// Data is packed into blocks on disk, always starting from the beginning -// of the block. If a file's data is too large for one block, it overflows -// into another block, which may or may not be the following block on the -// physical partition. An ordered list of extents is another -// representation of an ordered list of blocks. For example, a file stored -// in blocks 9, 10, 11, 2, 18, 12 (in that order) would be stored in -// extents { {9, 3}, {2, 1}, {18, 1}, {12, 1} } (in that order). -// In general, files are stored sequentially on disk, so it's more efficient -// to use extents to encode the block lists (this is effectively -// run-length encoding). -// A sentinel value (kuint64max) as the start block denotes a sparse-hole -// in a file whose block-length is specified by num_blocks. + return file_update_metadata_proto_rawDescGZIP(), []int{4, 0} +} + type Extent struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -322,17 +326,6 @@ func (x *Extent) GetNumBlocks() uint64 { return 0 } -// Signatures: Updates may be signed by the OS vendor. The client verifies -// an update's signature by hashing the entire download. The section of the -// download that contains the signature is at the end of the file, so when -// signing a file, only the part up to the signature part is signed. -// Then, the client looks inside the download's Signatures message for a -// Signature message that it knows how to handle. Generally, a client will -// only know how to handle one type of signature, but an update may contain -// many signatures to support many different types of client. Then client -// selects a Signature message and uses that, along with a known public key, -// to verify the download. The public key is expected to be part of the -// client. type Signatures struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -435,102 +428,6 @@ func (x *PartitionInfo) GetHash() []byte { return nil } -// Describe an image we are based on in a human friendly way. -// Examples: -// dev-channel, x86-alex, 1.2.3, mp-v3 -// nplusone-channel, x86-alex, 1.2.4, mp-v3, dev-channel, 1.2.3 -// -// All fields will be set, if this message is present. -type ImageInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Board *string `protobuf:"bytes,1,opt,name=board" json:"board,omitempty"` - Key *string `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` - Channel *string `protobuf:"bytes,3,opt,name=channel" json:"channel,omitempty"` - Version *string `protobuf:"bytes,4,opt,name=version" json:"version,omitempty"` - // If these values aren't present, they should be assumed to match - // the equivalent value above. They are normally only different for - // special image types such as nplusone images. - BuildChannel *string `protobuf:"bytes,5,opt,name=build_channel,json=buildChannel" json:"build_channel,omitempty"` - BuildVersion *string `protobuf:"bytes,6,opt,name=build_version,json=buildVersion" json:"build_version,omitempty"` -} - -func (x *ImageInfo) Reset() { - *x = ImageInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ImageInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ImageInfo) ProtoMessage() {} - -func (x *ImageInfo) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ImageInfo.ProtoReflect.Descriptor instead. -func (*ImageInfo) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{3} -} - -func (x *ImageInfo) GetBoard() string { - if x != nil && x.Board != nil { - return *x.Board - } - return "" -} - -func (x *ImageInfo) GetKey() string { - if x != nil && x.Key != nil { - return *x.Key - } - return "" -} - -func (x *ImageInfo) GetChannel() string { - if x != nil && x.Channel != nil { - return *x.Channel - } - return "" -} - -func (x *ImageInfo) GetVersion() string { - if x != nil && x.Version != nil { - return *x.Version - } - return "" -} - -func (x *ImageInfo) GetBuildChannel() string { - if x != nil && x.BuildChannel != nil { - return *x.BuildChannel - } - return "" -} - -func (x *ImageInfo) GetBuildVersion() string { - if x != nil && x.BuildVersion != nil { - return *x.BuildVersion - } - return "" -} - type InstallOperation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -571,7 +468,7 @@ type InstallOperation struct { func (x *InstallOperation) Reset() { *x = InstallOperation{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[4] + mi := &file_update_metadata_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -584,7 +481,7 @@ func (x *InstallOperation) String() string { func (*InstallOperation) ProtoMessage() {} func (x *InstallOperation) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[4] + mi := &file_update_metadata_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -597,7 +494,7 @@ func (x *InstallOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use InstallOperation.ProtoReflect.Descriptor instead. func (*InstallOperation) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{4} + return file_update_metadata_proto_rawDescGZIP(), []int{3} } func (x *InstallOperation) GetType() InstallOperation_Type { @@ -677,12 +574,20 @@ type CowMergeOperation struct { Type *CowMergeOperation_Type `protobuf:"varint,1,opt,name=type,enum=chromeos_update_engine.CowMergeOperation_Type" json:"type,omitempty"` SrcExtent *Extent `protobuf:"bytes,2,opt,name=src_extent,json=srcExtent" json:"src_extent,omitempty"` DstExtent *Extent `protobuf:"bytes,3,opt,name=dst_extent,json=dstExtent" json:"dst_extent,omitempty"` + // For COW_XOR, source location might be unaligned, so this field is in range + // [0, block_size), representing how much should the src_extent shift toward + // larger block number. If this field is non-zero, then src_extent will + // include 1 extra block in the end, as the merge op actually references the + // first |src_offset| bytes of that extra block. For example, if |dst_extent| + // is [10, 15], |src_offset| is 500, then src_extent might look like [25, 31]. + // Note that |src_extent| contains 1 extra block than the |dst_extent|. + SrcOffset *uint32 `protobuf:"varint,4,opt,name=src_offset,json=srcOffset" json:"src_offset,omitempty"` } func (x *CowMergeOperation) Reset() { *x = CowMergeOperation{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[5] + mi := &file_update_metadata_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -695,7 +600,7 @@ func (x *CowMergeOperation) String() string { func (*CowMergeOperation) ProtoMessage() {} func (x *CowMergeOperation) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[5] + mi := &file_update_metadata_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -708,7 +613,7 @@ func (x *CowMergeOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use CowMergeOperation.ProtoReflect.Descriptor instead. func (*CowMergeOperation) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{5} + return file_update_metadata_proto_rawDescGZIP(), []int{4} } func (x *CowMergeOperation) GetType() CowMergeOperation_Type { @@ -732,6 +637,13 @@ func (x *CowMergeOperation) GetDstExtent() *Extent { return nil } +func (x *CowMergeOperation) GetSrcOffset() uint32 { + if x != nil && x.SrcOffset != nil { + return *x.SrcOffset + } + return 0 +} + // Describes the update to apply to a single partition. type PartitionUpdate struct { state protoimpl.MessageState @@ -769,7 +681,6 @@ type PartitionUpdate struct { // Whether a failure in the postinstall step for this partition should be // ignored. PostinstallOptional *bool `protobuf:"varint,9,opt,name=postinstall_optional,json=postinstallOptional" json:"postinstall_optional,omitempty"` - // On minor version 6 or newer, these fields are supported: // The extent for data covered by verity hash tree. HashTreeDataExtent *Extent `protobuf:"bytes,10,opt,name=hash_tree_data_extent,json=hashTreeDataExtent" json:"hash_tree_data_extent,omitempty"` // The extent to store verity hash tree. @@ -792,6 +703,13 @@ type PartitionUpdate struct { // skip writing the raw bytes for these extents. During snapshot merge, the // bytes will read from the source partitions instead. MergeOperations []*CowMergeOperation `protobuf:"bytes,18,rep,name=merge_operations,json=mergeOperations" json:"merge_operations,omitempty"` + // Estimated size for COW image. This is used by libsnapshot + // as a hint. If set to 0, libsnapshot should use alternative + // methods for estimating size. + EstimateCowSize *uint64 `protobuf:"varint,19,opt,name=estimate_cow_size,json=estimateCowSize" json:"estimate_cow_size,omitempty"` + // Information about the cow used by Cow Writer to specify + // number of cow operations to be written + EstimateOpCountMax *uint64 `protobuf:"varint,20,opt,name=estimate_op_count_max,json=estimateOpCountMax" json:"estimate_op_count_max,omitempty"` } // Default values for PartitionUpdate fields. @@ -802,7 +720,7 @@ const ( func (x *PartitionUpdate) Reset() { *x = PartitionUpdate{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[6] + mi := &file_update_metadata_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -815,7 +733,7 @@ func (x *PartitionUpdate) String() string { func (*PartitionUpdate) ProtoMessage() {} func (x *PartitionUpdate) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[6] + mi := &file_update_metadata_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -828,7 +746,7 @@ func (x *PartitionUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use PartitionUpdate.ProtoReflect.Descriptor instead. func (*PartitionUpdate) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{6} + return file_update_metadata_proto_rawDescGZIP(), []int{5} } func (x *PartitionUpdate) GetPartitionName() string { @@ -957,6 +875,20 @@ func (x *PartitionUpdate) GetMergeOperations() []*CowMergeOperation { return nil } +func (x *PartitionUpdate) GetEstimateCowSize() uint64 { + if x != nil && x.EstimateCowSize != nil { + return *x.EstimateCowSize + } + return 0 +} + +func (x *PartitionUpdate) GetEstimateOpCountMax() uint64 { + if x != nil && x.EstimateOpCountMax != nil { + return *x.EstimateOpCountMax + } + return 0 +} + type DynamicPartitionGroup struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -974,7 +906,7 @@ type DynamicPartitionGroup struct { func (x *DynamicPartitionGroup) Reset() { *x = DynamicPartitionGroup{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[7] + mi := &file_update_metadata_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -987,7 +919,7 @@ func (x *DynamicPartitionGroup) String() string { func (*DynamicPartitionGroup) ProtoMessage() {} func (x *DynamicPartitionGroup) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[7] + mi := &file_update_metadata_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1000,7 +932,7 @@ func (x *DynamicPartitionGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use DynamicPartitionGroup.ProtoReflect.Descriptor instead. func (*DynamicPartitionGroup) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{7} + return file_update_metadata_proto_rawDescGZIP(), []int{6} } func (x *DynamicPartitionGroup) GetName() string { @@ -1024,6 +956,61 @@ func (x *DynamicPartitionGroup) GetPartitionNames() []string { return nil } +type VABCFeatureSet struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Threaded *bool `protobuf:"varint,1,opt,name=threaded" json:"threaded,omitempty"` + BatchWrites *bool `protobuf:"varint,2,opt,name=batch_writes,json=batchWrites" json:"batch_writes,omitempty"` +} + +func (x *VABCFeatureSet) Reset() { + *x = VABCFeatureSet{} + if protoimpl.UnsafeEnabled { + mi := &file_update_metadata_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VABCFeatureSet) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VABCFeatureSet) ProtoMessage() {} + +func (x *VABCFeatureSet) ProtoReflect() protoreflect.Message { + mi := &file_update_metadata_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VABCFeatureSet.ProtoReflect.Descriptor instead. +func (*VABCFeatureSet) Descriptor() ([]byte, []int) { + return file_update_metadata_proto_rawDescGZIP(), []int{7} +} + +func (x *VABCFeatureSet) GetThreaded() bool { + if x != nil && x.Threaded != nil { + return *x.Threaded + } + return false +} + +func (x *VABCFeatureSet) GetBatchWrites() bool { + if x != nil && x.BatchWrites != nil { + return *x.BatchWrites + } + return false +} + // Metadata related to all dynamic partitions. type DynamicPartitionMetadata struct { state protoimpl.MessageState @@ -1031,17 +1018,34 @@ type DynamicPartitionMetadata struct { unknownFields protoimpl.UnknownFields // All updatable groups present in |partitions| of this DeltaArchiveManifest. - // - If an updatable group is on the device but not in the manifest, it is - // not updated. Hence, the group will not be resized, and partitions cannot - // be added to or removed from the group. - // - If an updatable group is in the manifest but not on the device, the group - // is added to the device. + // - If an updatable group is on the device but not in the manifest, it is + // not updated. Hence, the group will not be resized, and partitions cannot + // be added to or removed from the group. + // - If an updatable group is in the manifest but not on the device, the group + // is added to the device. Groups []*DynamicPartitionGroup `protobuf:"bytes,1,rep,name=groups" json:"groups,omitempty"` // Whether dynamic partitions have snapshots during the update. If this is // set to true, the update_engine daemon creates snapshots for all dynamic // partitions if possible. If this is unset, the update_engine daemon MUST // NOT create snapshots for dynamic partitions. SnapshotEnabled *bool `protobuf:"varint,2,opt,name=snapshot_enabled,json=snapshotEnabled" json:"snapshot_enabled,omitempty"` + // If this is set to false, update_engine should not use VABC regardless. If + // this is set to true, update_engine may choose to use VABC if device + // supports it, but not guaranteed. + // VABC stands for Virtual AB Compression + VabcEnabled *bool `protobuf:"varint,3,opt,name=vabc_enabled,json=vabcEnabled" json:"vabc_enabled,omitempty"` + // The compression algorithm used by VABC. Available ones are "gz", "brotli". + // See system/core/fs_mgr/libsnapshot/cow_writer.cpp for available options, + // as this parameter is ultimated forwarded to libsnapshot's CowWriter + VabcCompressionParam *string `protobuf:"bytes,4,opt,name=vabc_compression_param,json=vabcCompressionParam" json:"vabc_compression_param,omitempty"` + // COW version used by VABC. The represents the major version in the COW + // header + CowVersion *uint32 `protobuf:"varint,5,opt,name=cow_version,json=cowVersion" json:"cow_version,omitempty"` + // A collection of knobs to tune Virtual AB Compression + VabcFeatureSet *VABCFeatureSet `protobuf:"bytes,6,opt,name=vabc_feature_set,json=vabcFeatureSet" json:"vabc_feature_set,omitempty"` + // Max bytes to be compressed at once during ota. Options: 4k, 8k, 16k, 32k, + // 64k, 128k + CompressionFactor *uint64 `protobuf:"varint,7,opt,name=compression_factor,json=compressionFactor" json:"compression_factor,omitempty"` } func (x *DynamicPartitionMetadata) Reset() { @@ -1090,19 +1094,168 @@ func (x *DynamicPartitionMetadata) GetSnapshotEnabled() bool { return false } +func (x *DynamicPartitionMetadata) GetVabcEnabled() bool { + if x != nil && x.VabcEnabled != nil { + return *x.VabcEnabled + } + return false +} + +func (x *DynamicPartitionMetadata) GetVabcCompressionParam() string { + if x != nil && x.VabcCompressionParam != nil { + return *x.VabcCompressionParam + } + return "" +} + +func (x *DynamicPartitionMetadata) GetCowVersion() uint32 { + if x != nil && x.CowVersion != nil { + return *x.CowVersion + } + return 0 +} + +func (x *DynamicPartitionMetadata) GetVabcFeatureSet() *VABCFeatureSet { + if x != nil { + return x.VabcFeatureSet + } + return nil +} + +func (x *DynamicPartitionMetadata) GetCompressionFactor() uint64 { + if x != nil && x.CompressionFactor != nil { + return *x.CompressionFactor + } + return 0 +} + +// Definition has been duplicated from +// $ANDROID_BUILD_TOP/build/tools/releasetools/ota_metadata.proto. Keep in sync. +type ApexInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PackageName *string `protobuf:"bytes,1,opt,name=package_name,json=packageName" json:"package_name,omitempty"` + Version *int64 `protobuf:"varint,2,opt,name=version" json:"version,omitempty"` + IsCompressed *bool `protobuf:"varint,3,opt,name=is_compressed,json=isCompressed" json:"is_compressed,omitempty"` + DecompressedSize *int64 `protobuf:"varint,4,opt,name=decompressed_size,json=decompressedSize" json:"decompressed_size,omitempty"` +} + +func (x *ApexInfo) Reset() { + *x = ApexInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_update_metadata_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApexInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApexInfo) ProtoMessage() {} + +func (x *ApexInfo) ProtoReflect() protoreflect.Message { + mi := &file_update_metadata_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApexInfo.ProtoReflect.Descriptor instead. +func (*ApexInfo) Descriptor() ([]byte, []int) { + return file_update_metadata_proto_rawDescGZIP(), []int{9} +} + +func (x *ApexInfo) GetPackageName() string { + if x != nil && x.PackageName != nil { + return *x.PackageName + } + return "" +} + +func (x *ApexInfo) GetVersion() int64 { + if x != nil && x.Version != nil { + return *x.Version + } + return 0 +} + +func (x *ApexInfo) GetIsCompressed() bool { + if x != nil && x.IsCompressed != nil { + return *x.IsCompressed + } + return false +} + +func (x *ApexInfo) GetDecompressedSize() int64 { + if x != nil && x.DecompressedSize != nil { + return *x.DecompressedSize + } + return 0 +} + +// Definition has been duplicated from +// $ANDROID_BUILD_TOP/build/tools/releasetools/ota_metadata.proto. Keep in sync. +type ApexMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ApexInfo []*ApexInfo `protobuf:"bytes,1,rep,name=apex_info,json=apexInfo" json:"apex_info,omitempty"` +} + +func (x *ApexMetadata) Reset() { + *x = ApexMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_update_metadata_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApexMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApexMetadata) ProtoMessage() {} + +func (x *ApexMetadata) ProtoReflect() protoreflect.Message { + mi := &file_update_metadata_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApexMetadata.ProtoReflect.Descriptor instead. +func (*ApexMetadata) Descriptor() ([]byte, []int) { + return file_update_metadata_proto_rawDescGZIP(), []int{10} +} + +func (x *ApexMetadata) GetApexInfo() []*ApexInfo { + if x != nil { + return x.ApexInfo + } + return nil +} + type DeltaArchiveManifest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Only present in major version = 1. List of install operations for the - // kernel and rootfs partitions. For major version = 2 see the |partitions| - // field. - // - // Deprecated: Do not use. - InstallOperations []*InstallOperation `protobuf:"bytes,1,rep,name=install_operations,json=installOperations" json:"install_operations,omitempty"` - // Deprecated: Do not use. - KernelInstallOperations []*InstallOperation `protobuf:"bytes,2,rep,name=kernel_install_operations,json=kernelInstallOperations" json:"kernel_install_operations,omitempty"` // (At time of writing) usually 4096 BlockSize *uint32 `protobuf:"varint,3,opt,name=block_size,json=blockSize,def=4096" json:"block_size,omitempty"` // If signatures are present, the offset into the blobs, generally @@ -1112,20 +1265,6 @@ type DeltaArchiveManifest struct { // file. SignaturesOffset *uint64 `protobuf:"varint,4,opt,name=signatures_offset,json=signaturesOffset" json:"signatures_offset,omitempty"` SignaturesSize *uint64 `protobuf:"varint,5,opt,name=signatures_size,json=signaturesSize" json:"signatures_size,omitempty"` - // Only present in major version = 1. Partition metadata used to validate the - // update. For major version = 2 see the |partitions| field. - // - // Deprecated: Do not use. - OldKernelInfo *PartitionInfo `protobuf:"bytes,6,opt,name=old_kernel_info,json=oldKernelInfo" json:"old_kernel_info,omitempty"` - // Deprecated: Do not use. - NewKernelInfo *PartitionInfo `protobuf:"bytes,7,opt,name=new_kernel_info,json=newKernelInfo" json:"new_kernel_info,omitempty"` - // Deprecated: Do not use. - OldRootfsInfo *PartitionInfo `protobuf:"bytes,8,opt,name=old_rootfs_info,json=oldRootfsInfo" json:"old_rootfs_info,omitempty"` - // Deprecated: Do not use. - NewRootfsInfo *PartitionInfo `protobuf:"bytes,9,opt,name=new_rootfs_info,json=newRootfsInfo" json:"new_rootfs_info,omitempty"` - // old_image_info will only be present for delta images. - OldImageInfo *ImageInfo `protobuf:"bytes,10,opt,name=old_image_info,json=oldImageInfo" json:"old_image_info,omitempty"` - NewImageInfo *ImageInfo `protobuf:"bytes,11,opt,name=new_image_info,json=newImageInfo" json:"new_image_info,omitempty"` // The minor version, also referred as "delta version", of the payload. // Minor version 0 is full payload, everything else is delta payload. MinorVersion *uint32 `protobuf:"varint,12,opt,name=minor_version,json=minorVersion,def=0" json:"minor_version,omitempty"` @@ -1143,6 +1282,12 @@ type DeltaArchiveManifest struct { DynamicPartitionMetadata *DynamicPartitionMetadata `protobuf:"bytes,15,opt,name=dynamic_partition_metadata,json=dynamicPartitionMetadata" json:"dynamic_partition_metadata,omitempty"` // If the payload only updates a subset of partitions on the device. PartialUpdate *bool `protobuf:"varint,16,opt,name=partial_update,json=partialUpdate" json:"partial_update,omitempty"` + // Information on compressed APEX to figure out how much space is required for + // their decompression + ApexInfo []*ApexInfo `protobuf:"bytes,17,rep,name=apex_info,json=apexInfo" json:"apex_info,omitempty"` + // Security patch level of the device, usually in the format of + // yyyy-mm-dd + SecurityPatchLevel *string `protobuf:"bytes,18,opt,name=security_patch_level,json=securityPatchLevel" json:"security_patch_level,omitempty"` } // Default values for DeltaArchiveManifest fields. @@ -1154,7 +1299,7 @@ const ( func (x *DeltaArchiveManifest) Reset() { *x = DeltaArchiveManifest{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[9] + mi := &file_update_metadata_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1167,7 +1312,7 @@ func (x *DeltaArchiveManifest) String() string { func (*DeltaArchiveManifest) ProtoMessage() {} func (x *DeltaArchiveManifest) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[9] + mi := &file_update_metadata_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1180,23 +1325,7 @@ func (x *DeltaArchiveManifest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeltaArchiveManifest.ProtoReflect.Descriptor instead. func (*DeltaArchiveManifest) Descriptor() ([]byte, []int) { - return file_update_metadata_proto_rawDescGZIP(), []int{9} -} - -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetInstallOperations() []*InstallOperation { - if x != nil { - return x.InstallOperations - } - return nil -} - -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetKernelInstallOperations() []*InstallOperation { - if x != nil { - return x.KernelInstallOperations - } - return nil + return file_update_metadata_proto_rawDescGZIP(), []int{11} } func (x *DeltaArchiveManifest) GetBlockSize() uint32 { @@ -1220,52 +1349,6 @@ func (x *DeltaArchiveManifest) GetSignaturesSize() uint64 { return 0 } -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetOldKernelInfo() *PartitionInfo { - if x != nil { - return x.OldKernelInfo - } - return nil -} - -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetNewKernelInfo() *PartitionInfo { - if x != nil { - return x.NewKernelInfo - } - return nil -} - -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetOldRootfsInfo() *PartitionInfo { - if x != nil { - return x.OldRootfsInfo - } - return nil -} - -// Deprecated: Do not use. -func (x *DeltaArchiveManifest) GetNewRootfsInfo() *PartitionInfo { - if x != nil { - return x.NewRootfsInfo - } - return nil -} - -func (x *DeltaArchiveManifest) GetOldImageInfo() *ImageInfo { - if x != nil { - return x.OldImageInfo - } - return nil -} - -func (x *DeltaArchiveManifest) GetNewImageInfo() *ImageInfo { - if x != nil { - return x.NewImageInfo - } - return nil -} - func (x *DeltaArchiveManifest) GetMinorVersion() uint32 { if x != nil && x.MinorVersion != nil { return *x.MinorVersion @@ -1301,12 +1384,26 @@ func (x *DeltaArchiveManifest) GetPartialUpdate() bool { return false } +func (x *DeltaArchiveManifest) GetApexInfo() []*ApexInfo { + if x != nil { + return x.ApexInfo + } + return nil +} + +func (x *DeltaArchiveManifest) GetSecurityPatchLevel() string { + if x != nil && x.SecurityPatchLevel != nil { + return *x.SecurityPatchLevel + } + return "" +} + type Signatures_Signature struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in update_metadata.proto. Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` // The DER encoded signature size of EC keys is nondeterministic for @@ -1322,7 +1419,7 @@ type Signatures_Signature struct { func (x *Signatures_Signature) Reset() { *x = Signatures_Signature{} if protoimpl.UnsafeEnabled { - mi := &file_update_metadata_proto_msgTypes[10] + mi := &file_update_metadata_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1335,7 +1432,7 @@ func (x *Signatures_Signature) String() string { func (*Signatures_Signature) ProtoMessage() {} func (x *Signatures_Signature) ProtoReflect() protoreflect.Message { - mi := &file_update_metadata_proto_msgTypes[10] + mi := &file_update_metadata_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1351,7 +1448,7 @@ func (*Signatures_Signature) Descriptor() ([]byte, []int) { return file_update_metadata_proto_rawDescGZIP(), []int{1, 0} } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in update_metadata.proto. func (x *Signatures_Signature) GetVersion() uint32 { if x != nil && x.Version != nil { return *x.Version @@ -1400,169 +1497,194 @@ var file_update_metadata_proto_rawDesc = []byte{ 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xb1, 0x01, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x68, - 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd9, 0x04, 0x0a, 0x10, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x41, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x2d, 0x2e, - 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x12, 0x3f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, - 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x72, 0x63, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x72, 0x63, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x12, 0x3f, 0x0a, 0x0b, 0x64, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, + 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x91, 0x05, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x73, 0x74, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x5f, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x73, 0x74, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x68, 0x61, - 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x64, 0x61, 0x74, 0x61, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, - 0x0a, 0x0f, 0x73, 0x72, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x72, 0x63, 0x53, 0x68, 0x61, 0x32, - 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x22, 0xad, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, - 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x42, 0x5a, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x04, - 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x02, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0e, 0x0a, 0x06, 0x42, 0x53, - 0x44, 0x49, 0x46, 0x46, 0x10, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x10, 0x05, 0x12, 0x0e, - 0x0a, 0x0a, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x58, 0x5a, 0x10, 0x08, 0x12, 0x08, - 0x0a, 0x04, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53, 0x43, - 0x41, 0x52, 0x44, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x52, 0x4f, 0x54, 0x4c, 0x49, 0x5f, - 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x10, 0x0a, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x55, 0x46, 0x46, - 0x44, 0x49, 0x46, 0x46, 0x10, 0x09, 0x22, 0xeb, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x77, 0x4d, 0x65, - 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x63, 0x68, 0x72, - 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x2e, 0x43, 0x6f, 0x77, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x3d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x73, 0x72, 0x63, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x3d, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x45, 0x78, 0x74, - 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x14, - 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x57, 0x5f, 0x43, 0x4f, - 0x50, 0x59, 0x10, 0x00, 0x22, 0xcc, 0x08, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, - 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x75, 0x6e, 0x50, 0x6f, 0x73, - 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x6f, 0x73, 0x74, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x64, 0x0a, 0x17, - 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, - 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x15, 0x6e, 0x65, 0x77, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x3f, 0x0a, 0x0b, 0x73, 0x72, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x72, 0x63, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x72, 0x63, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x3f, 0x0a, 0x0b, 0x64, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x64, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x64, 0x73, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x28, 0x0a, 0x10, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x64, 0x61, 0x74, 0x61, + 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x72, + 0x63, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x72, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, + 0x73, 0x68, 0x22, 0xe5, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x52, + 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x50, 0x4c, + 0x41, 0x43, 0x45, 0x5f, 0x42, 0x5a, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x04, 0x4d, 0x4f, 0x56, 0x45, + 0x10, 0x02, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0e, 0x0a, 0x06, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, + 0x10, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, + 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, + 0x50, 0x4c, 0x41, 0x43, 0x45, 0x5f, 0x58, 0x5a, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x45, + 0x52, 0x4f, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, + 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x52, 0x4f, 0x54, 0x4c, 0x49, 0x5f, 0x42, 0x53, 0x44, 0x49, + 0x46, 0x46, 0x10, 0x0a, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x55, 0x46, 0x46, 0x44, 0x49, 0x46, 0x46, + 0x10, 0x09, 0x12, 0x0c, 0x0a, 0x08, 0x5a, 0x55, 0x43, 0x43, 0x48, 0x49, 0x4e, 0x49, 0x10, 0x0b, + 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x5a, 0x34, 0x44, 0x49, 0x46, 0x46, 0x5f, 0x42, 0x53, 0x44, 0x49, + 0x46, 0x46, 0x10, 0x0c, 0x12, 0x14, 0x0a, 0x10, 0x4c, 0x5a, 0x34, 0x44, 0x49, 0x46, 0x46, 0x5f, + 0x50, 0x55, 0x46, 0x46, 0x44, 0x49, 0x46, 0x46, 0x10, 0x0d, 0x22, 0xa8, 0x02, 0x0a, 0x11, 0x43, + 0x6f, 0x77, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x6f, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x53, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x50, - 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x0a, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x51, 0x0a, 0x15, 0x68, 0x61, 0x73, - 0x68, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, + 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x43, 0x6f, 0x77, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x12, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, - 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x10, - 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, + 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x73, 0x72, 0x63, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, + 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x72, 0x63, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x22, 0x32, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x57, + 0x5f, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x57, 0x5f, 0x58, + 0x4f, 0x52, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x4f, 0x57, 0x5f, 0x52, 0x45, 0x50, 0x4c, + 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xab, 0x09, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x09, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x5f, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x75, 0x6e, 0x50, 0x6f, + 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x6f, 0x73, + 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x64, 0x0a, + 0x17, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, + 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x15, 0x6e, 0x65, + 0x77, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x6f, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x53, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x6e, 0x65, 0x77, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, + 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x14, 0x70, 0x6f, 0x73, 0x74, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x70, 0x6f, 0x73, 0x74, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x51, 0x0a, 0x15, 0x68, 0x61, + 0x73, 0x68, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, + 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x12, 0x68, 0x61, 0x73, 0x68, 0x54, + 0x72, 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, + 0x10, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, + 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, + 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x68, 0x5f, + 0x74, 0x72, 0x65, 0x65, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, 0x65, 0x41, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x24, 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x68, 0x5f, + 0x74, 0x72, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0c, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x46, 0x0a, + 0x0f, 0x66, 0x65, 0x63, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, 0x65, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, - 0x72, 0x65, 0x65, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x11, 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, 0x65, 0x41, 0x6c, 0x67, - 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x24, 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, - 0x72, 0x65, 0x65, 0x5f, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, - 0x68, 0x61, 0x73, 0x68, 0x54, 0x72, 0x65, 0x65, 0x53, 0x61, 0x6c, 0x74, 0x12, 0x46, 0x0a, 0x0f, - 0x66, 0x65, 0x63, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, - 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0d, 0x66, 0x65, 0x63, 0x44, 0x61, 0x74, 0x61, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0a, 0x66, 0x65, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x0d, 0x66, 0x65, 0x63, 0x44, 0x61, 0x74, 0x61, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0a, 0x66, 0x65, 0x63, 0x5f, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x72, 0x6f, + 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x66, 0x65, 0x63, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x09, 0x66, 0x65, 0x63, 0x5f, 0x72, 0x6f, 0x6f, 0x74, + 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x3a, 0x01, 0x32, 0x52, 0x08, 0x66, 0x65, 0x63, 0x52, + 0x6f, 0x6f, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, + 0x0a, 0x10, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x66, 0x65, 0x63, 0x45, 0x78, 0x74, - 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x09, 0x66, 0x65, 0x63, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x73, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x0d, 0x3a, 0x01, 0x32, 0x52, 0x08, 0x66, 0x65, 0x63, 0x52, 0x6f, - 0x6f, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x11, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, - 0x10, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, - 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x2e, 0x43, 0x6f, 0x77, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x68, 0x0a, 0x15, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, + 0x65, 0x2e, 0x43, 0x6f, 0x77, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, + 0x5f, 0x63, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0f, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x77, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x31, 0x0a, 0x15, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x12, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x4d, 0x61, 0x78, 0x22, 0x68, 0x0a, 0x15, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x8c, 0x01, - 0x0a, 0x18, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x68, 0x72, - 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xe3, 0x08, 0x0a, - 0x14, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x6e, - 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x02, 0x18, 0x01, 0x52, - 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x68, 0x0a, 0x19, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, - 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x02, 0x18, 0x01, 0x52, 0x17, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0a, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x4f, 0x0a, + 0x0e, 0x56, 0x41, 0x42, 0x43, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x62, + 0x61, 0x74, 0x63, 0x68, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x62, 0x61, 0x74, 0x63, 0x68, 0x57, 0x72, 0x69, 0x74, 0x65, 0x73, 0x22, 0x87, + 0x03, 0x0a, 0x18, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x45, 0x0a, 0x06, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x68, + 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x76, 0x61, 0x62, 0x63, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x76, 0x61, 0x62, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x62, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x14, 0x76, 0x61, 0x62, 0x63, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x77, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x6f, 0x77, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x10, 0x76, 0x61, 0x62, 0x63, 0x5f, + 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x56, 0x41, 0x42, 0x43, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x0e, 0x76, 0x61, 0x62, 0x63, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x99, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x65, + 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x43, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x63, 0x6f, 0x6d, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x10, 0x64, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, + 0x53, 0x69, 0x7a, 0x65, 0x22, 0x4d, 0x0a, 0x0c, 0x41, 0x70, 0x65, 0x78, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x70, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, + 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x2e, 0x41, 0x70, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61, 0x70, 0x65, 0x78, 0x49, + 0x6e, 0x66, 0x6f, 0x22, 0xdf, 0x04, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x41, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x3a, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x5f, @@ -1570,56 +1692,36 @@ var file_update_metadata_proto_rawDesc = []byte{ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x6b, - 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x6f, 0x6c, 0x64, - 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x51, 0x0a, 0x0f, 0x6e, 0x65, - 0x77, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, + 0x72, 0x65, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x26, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x3a, 0x01, + 0x30, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, - 0x6e, 0x65, 0x77, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x51, 0x0a, - 0x0f, 0x6f, 0x6c, 0x64, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, - 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x0d, 0x6f, 0x6c, 0x64, 0x52, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x51, 0x0a, 0x0f, 0x6e, 0x65, 0x77, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x68, 0x72, 0x6f, - 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x77, 0x52, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x47, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x68, - 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, - 0x6f, 0x6c, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x47, 0x0a, 0x0e, - 0x6e, 0x65, 0x77, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x3a, 0x01, 0x30, 0x52, - 0x0c, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, - 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, - 0x61, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x6e, 0x0a, 0x1a, 0x64, - 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x30, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x18, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x70, - 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x42, 0x02, 0x48, 0x03, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x6d, 0x61, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x6e, 0x0a, + 0x1a, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x18, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x25, 0x0a, + 0x0e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x09, 0x61, 0x70, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, + 0x6f, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x2e, 0x41, 0x70, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61, 0x70, 0x65, 0x78, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x61, 0x74, 0x63, 0x68, + 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, + 0x03, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x4a, 0x04, 0x08, + 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x0a, 0x10, 0x0b, 0x4a, + 0x04, 0x08, 0x0b, 0x10, 0x0c, } var ( @@ -1635,55 +1737,52 @@ func file_update_metadata_proto_rawDescGZIP() []byte { } var file_update_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_update_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_update_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_update_metadata_proto_goTypes = []interface{}{ (InstallOperation_Type)(0), // 0: chromeos_update_engine.InstallOperation.Type (CowMergeOperation_Type)(0), // 1: chromeos_update_engine.CowMergeOperation.Type (*Extent)(nil), // 2: chromeos_update_engine.Extent (*Signatures)(nil), // 3: chromeos_update_engine.Signatures (*PartitionInfo)(nil), // 4: chromeos_update_engine.PartitionInfo - (*ImageInfo)(nil), // 5: chromeos_update_engine.ImageInfo - (*InstallOperation)(nil), // 6: chromeos_update_engine.InstallOperation - (*CowMergeOperation)(nil), // 7: chromeos_update_engine.CowMergeOperation - (*PartitionUpdate)(nil), // 8: chromeos_update_engine.PartitionUpdate - (*DynamicPartitionGroup)(nil), // 9: chromeos_update_engine.DynamicPartitionGroup + (*InstallOperation)(nil), // 5: chromeos_update_engine.InstallOperation + (*CowMergeOperation)(nil), // 6: chromeos_update_engine.CowMergeOperation + (*PartitionUpdate)(nil), // 7: chromeos_update_engine.PartitionUpdate + (*DynamicPartitionGroup)(nil), // 8: chromeos_update_engine.DynamicPartitionGroup + (*VABCFeatureSet)(nil), // 9: chromeos_update_engine.VABCFeatureSet (*DynamicPartitionMetadata)(nil), // 10: chromeos_update_engine.DynamicPartitionMetadata - (*DeltaArchiveManifest)(nil), // 11: chromeos_update_engine.DeltaArchiveManifest - (*Signatures_Signature)(nil), // 12: chromeos_update_engine.Signatures.Signature + (*ApexInfo)(nil), // 11: chromeos_update_engine.ApexInfo + (*ApexMetadata)(nil), // 12: chromeos_update_engine.ApexMetadata + (*DeltaArchiveManifest)(nil), // 13: chromeos_update_engine.DeltaArchiveManifest + (*Signatures_Signature)(nil), // 14: chromeos_update_engine.Signatures.Signature } var file_update_metadata_proto_depIdxs = []int32{ - 12, // 0: chromeos_update_engine.Signatures.signatures:type_name -> chromeos_update_engine.Signatures.Signature + 14, // 0: chromeos_update_engine.Signatures.signatures:type_name -> chromeos_update_engine.Signatures.Signature 0, // 1: chromeos_update_engine.InstallOperation.type:type_name -> chromeos_update_engine.InstallOperation.Type 2, // 2: chromeos_update_engine.InstallOperation.src_extents:type_name -> chromeos_update_engine.Extent 2, // 3: chromeos_update_engine.InstallOperation.dst_extents:type_name -> chromeos_update_engine.Extent 1, // 4: chromeos_update_engine.CowMergeOperation.type:type_name -> chromeos_update_engine.CowMergeOperation.Type 2, // 5: chromeos_update_engine.CowMergeOperation.src_extent:type_name -> chromeos_update_engine.Extent 2, // 6: chromeos_update_engine.CowMergeOperation.dst_extent:type_name -> chromeos_update_engine.Extent - 12, // 7: chromeos_update_engine.PartitionUpdate.new_partition_signature:type_name -> chromeos_update_engine.Signatures.Signature + 14, // 7: chromeos_update_engine.PartitionUpdate.new_partition_signature:type_name -> chromeos_update_engine.Signatures.Signature 4, // 8: chromeos_update_engine.PartitionUpdate.old_partition_info:type_name -> chromeos_update_engine.PartitionInfo 4, // 9: chromeos_update_engine.PartitionUpdate.new_partition_info:type_name -> chromeos_update_engine.PartitionInfo - 6, // 10: chromeos_update_engine.PartitionUpdate.operations:type_name -> chromeos_update_engine.InstallOperation + 5, // 10: chromeos_update_engine.PartitionUpdate.operations:type_name -> chromeos_update_engine.InstallOperation 2, // 11: chromeos_update_engine.PartitionUpdate.hash_tree_data_extent:type_name -> chromeos_update_engine.Extent 2, // 12: chromeos_update_engine.PartitionUpdate.hash_tree_extent:type_name -> chromeos_update_engine.Extent 2, // 13: chromeos_update_engine.PartitionUpdate.fec_data_extent:type_name -> chromeos_update_engine.Extent 2, // 14: chromeos_update_engine.PartitionUpdate.fec_extent:type_name -> chromeos_update_engine.Extent - 7, // 15: chromeos_update_engine.PartitionUpdate.merge_operations:type_name -> chromeos_update_engine.CowMergeOperation - 9, // 16: chromeos_update_engine.DynamicPartitionMetadata.groups:type_name -> chromeos_update_engine.DynamicPartitionGroup - 6, // 17: chromeos_update_engine.DeltaArchiveManifest.install_operations:type_name -> chromeos_update_engine.InstallOperation - 6, // 18: chromeos_update_engine.DeltaArchiveManifest.kernel_install_operations:type_name -> chromeos_update_engine.InstallOperation - 4, // 19: chromeos_update_engine.DeltaArchiveManifest.old_kernel_info:type_name -> chromeos_update_engine.PartitionInfo - 4, // 20: chromeos_update_engine.DeltaArchiveManifest.new_kernel_info:type_name -> chromeos_update_engine.PartitionInfo - 4, // 21: chromeos_update_engine.DeltaArchiveManifest.old_rootfs_info:type_name -> chromeos_update_engine.PartitionInfo - 4, // 22: chromeos_update_engine.DeltaArchiveManifest.new_rootfs_info:type_name -> chromeos_update_engine.PartitionInfo - 5, // 23: chromeos_update_engine.DeltaArchiveManifest.old_image_info:type_name -> chromeos_update_engine.ImageInfo - 5, // 24: chromeos_update_engine.DeltaArchiveManifest.new_image_info:type_name -> chromeos_update_engine.ImageInfo - 8, // 25: chromeos_update_engine.DeltaArchiveManifest.partitions:type_name -> chromeos_update_engine.PartitionUpdate - 10, // 26: chromeos_update_engine.DeltaArchiveManifest.dynamic_partition_metadata:type_name -> chromeos_update_engine.DynamicPartitionMetadata - 27, // [27:27] is the sub-list for method output_type - 27, // [27:27] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 6, // 15: chromeos_update_engine.PartitionUpdate.merge_operations:type_name -> chromeos_update_engine.CowMergeOperation + 8, // 16: chromeos_update_engine.DynamicPartitionMetadata.groups:type_name -> chromeos_update_engine.DynamicPartitionGroup + 9, // 17: chromeos_update_engine.DynamicPartitionMetadata.vabc_feature_set:type_name -> chromeos_update_engine.VABCFeatureSet + 11, // 18: chromeos_update_engine.ApexMetadata.apex_info:type_name -> chromeos_update_engine.ApexInfo + 7, // 19: chromeos_update_engine.DeltaArchiveManifest.partitions:type_name -> chromeos_update_engine.PartitionUpdate + 10, // 20: chromeos_update_engine.DeltaArchiveManifest.dynamic_partition_metadata:type_name -> chromeos_update_engine.DynamicPartitionMetadata + 11, // 21: chromeos_update_engine.DeltaArchiveManifest.apex_info:type_name -> chromeos_update_engine.ApexInfo + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_update_metadata_proto_init() } @@ -1729,7 +1828,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImageInfo); i { + switch v := v.(*InstallOperation); i { case 0: return &v.state case 1: @@ -1741,7 +1840,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstallOperation); i { + switch v := v.(*CowMergeOperation); i { case 0: return &v.state case 1: @@ -1753,7 +1852,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CowMergeOperation); i { + switch v := v.(*PartitionUpdate); i { case 0: return &v.state case 1: @@ -1765,7 +1864,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PartitionUpdate); i { + switch v := v.(*DynamicPartitionGroup); i { case 0: return &v.state case 1: @@ -1777,7 +1876,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicPartitionGroup); i { + switch v := v.(*VABCFeatureSet); i { case 0: return &v.state case 1: @@ -1801,7 +1900,7 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeltaArchiveManifest); i { + switch v := v.(*ApexInfo); i { case 0: return &v.state case 1: @@ -1813,6 +1912,30 @@ func file_update_metadata_proto_init() { } } file_update_metadata_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApexMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_update_metadata_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeltaArchiveManifest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_update_metadata_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Signatures_Signature); i { case 0: return &v.state @@ -1831,7 +1954,7 @@ func file_update_metadata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_update_metadata_proto_rawDesc, NumEnums: 2, - NumMessages: 11, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/chromeos_update_engine/zucchini b/chromeos_update_engine/zucchini new file mode 160000 index 0000000..61f3212 --- /dev/null +++ b/chromeos_update_engine/zucchini @@ -0,0 +1 @@ +Subproject commit 61f3212a8b08c38530a2e2ee21f58de0ebee402c diff --git a/main.go b/main.go index 2696b19..d7140ec 100644 --- a/main.go +++ b/main.go @@ -52,6 +52,7 @@ func main() { list bool partitions string outputDirectory string + inputDirectory string concurrency int ) @@ -61,6 +62,8 @@ func main() { flag.BoolVar(&list, "list", false, "Show list of partitions in payload.bin") flag.StringVar(&outputDirectory, "o", "", "Set output directory (shorthand)") flag.StringVar(&outputDirectory, "output", "", "Set output directory") + flag.StringVar(&inputDirectory, "d", "", "Set input directory for delta payload (shorthand)") + flag.StringVar(&inputDirectory, "delta", "", "Set input directory for delta payload") flag.StringVar(&partitions, "p", "", "Dump only selected partitions (comma-separated) (shorthand)") flag.StringVar(&partitions, "partitions", "", "Dump only selected partitions (comma-separated)") flag.Parse() @@ -74,6 +77,8 @@ func main() { log.Fatalf("File does not exist: %s\n", filename) } + log.Printf("Delta: %s, partitions: %s\n", inputDirectory, partitions) + payloadBin := filename if strings.HasSuffix(filename, ".zip") { fmt.Println("Please wait while extracting payload.bin from the archive.") @@ -107,16 +112,16 @@ func main() { log.Fatal("Failed to create target directory") } } - + var sourceDirectory = inputDirectory payload.SetConcurrency(concurrency) fmt.Printf("Number of workers: %d\n", payload.GetConcurrency()) if partitions != "" { - if err := payload.ExtractSelected(targetDirectory, strings.Split(partitions, ",")); err != nil { + if err := payload.ExtractSelected(sourceDirectory, targetDirectory, strings.Split(partitions, ",")); err != nil { log.Fatal(err) } } else { - if err := payload.ExtractAll(targetDirectory); err != nil { + if err := payload.ExtractAll(sourceDirectory, targetDirectory); err != nil { log.Fatal(err) } } diff --git a/payload.go b/payload.go index ed10072..f66a29b 100644 --- a/payload.go +++ b/payload.go @@ -23,6 +23,7 @@ import ( type request struct { partition *chromeos_update_engine.PartitionUpdate + sourceDirectory string targetDirectory string } @@ -178,6 +179,8 @@ func (p *Payload) Init() error { } p.deltaArchiveManifest = deltaArchiveManifest + fmt.Printf("Payload Minor Version: %d\n", deltaArchiveManifest.GetMinorVersion()) + // Read Signatures signatures, err := p.readMetadataSignature() if err != nil { @@ -217,9 +220,10 @@ func (p *Payload) readDataBlob(offset int64, length int64) ([]byte, error) { return buf, nil } -func (p *Payload) Extract(partition *chromeos_update_engine.PartitionUpdate, out *os.File) error { +func (p *Payload) Extract(partition *chromeos_update_engine.PartitionUpdate, out *os.File, in *os.File) error { name := partition.GetPartitionName() info := partition.GetNewPartitionInfo() + isDelta := in != nil totalOperations := len(partition.Operations) barName := fmt.Sprintf("%s (%s)", name, humanize.Bytes(info.GetSize())) bar := p.progress.AddBar( @@ -251,6 +255,10 @@ func (p *Payload) Extract(partition *chromeos_update_engine.PartitionUpdate, out bufSha := sha256.New() teeReader := io.TeeReader(io.NewSectionReader(p.file, dataOffset, dataLength), bufSha) + dataBuf := make([]byte, dataLength) + + teeReader.Read(dataBuf) + switch operation.GetType() { case chromeos_update_engine.InstallOperation_REPLACE: n, err := io.Copy(out, teeReader) @@ -299,8 +307,147 @@ func (p *Payload) Extract(partition *chromeos_update_engine.PartitionUpdate, out } break + case chromeos_update_engine.InstallOperation_SOURCE_COPY: + if !isDelta { + return fmt.Errorf("%s: SOURCE_COPY is only supported for delta", name) + } + + for _, e := range operation.SrcExtents { + _, err := in.Seek(int64(e.GetStartBlock()) * blockSize, 0) + if err != nil { + return err + } + + expectedInputBlockSize := int64(e.GetNumBlocks()) * blockSize + + data := make([]byte, expectedInputBlockSize) + n, err := in.Read(data) + + if err != nil { + fmt.Printf("%s: SOURCE_COPY error: %s (read %d)\n", name, err, n) + return err + } + + if int64(n) != expectedInputBlockSize { + return fmt.Errorf("%s: SOURCE_COPY expected %d bytes, but got %d", name, expectedInputBlockSize, n) + } + + if _, err := out.Write(data[:n]); err != nil { + return err + } + } + break + + case chromeos_update_engine.InstallOperation_SOURCE_BSDIFF: + case chromeos_update_engine.InstallOperation_BSDIFF: + case chromeos_update_engine.InstallOperation_BROTLI_BSDIFF: + if !isDelta { + return fmt.Errorf("%s: %s is only supported for delta", name, operation.GetType().String()) + } + + buf := make([]byte, 0) + + for _, e := range operation.SrcExtents { + _, err := in.Seek(int64(e.GetStartBlock()) * blockSize, 0) + if err != nil { + return err + } + + expectedInputBlockSize := int64(e.GetNumBlocks()) * blockSize + + data := make([]byte, expectedInputBlockSize) + n, err := in.Read(data) + + if err != nil { + fmt.Printf("%s: %s error: %s (read %d)\n", name, operation.GetType().String(), err, n) + return err + } + + if int64(n) != expectedInputBlockSize { + return fmt.Errorf("%s: %s expected %d bytes, but got %d", name, operation.GetType().String(), expectedInputBlockSize, n) + } + + buf = append(buf, data...) + } + + buf, err := chromeos_update_engine.ExecuteSourceBsdiffOperation(buf, dataBuf) + + if err != nil { + return err + } + + n := uint64(0) + + for _, e := range operation.DstExtents { + _, err := out.Seek(int64(e.GetStartBlock())*blockSize, 0) + if err != nil { + return err + } + + data := make([]byte, e.GetNumBlocks() * blockSize) + copy(data, buf[n*blockSize:]) + if _, err := out.Write(data); err != nil { + return err + } + n += e.GetNumBlocks() + } + break + case chromeos_update_engine.InstallOperation_PUFFDIFF: + if !isDelta { + return fmt.Errorf("%s: %s is only supported for delta", name, operation.GetType().String()) + } + + buf := make([]byte, 0) + + for _, e := range operation.SrcExtents { + _, err := in.Seek(int64(e.GetStartBlock()) * blockSize, 0) + if err != nil { + return err + } + + expectedInputBlockSize := int64(e.GetNumBlocks()) * blockSize + + data := make([]byte, expectedInputBlockSize) + n, err := in.Read(data) + + if err != nil { + fmt.Printf("%s: %s error: %s (read %d)\n", name, operation.GetType().String(), err, n) + return err + } + + if int64(n) != expectedInputBlockSize { + return fmt.Errorf("%s: %s expected %d bytes, but got %d", name, operation.GetType().String(), expectedInputBlockSize, n) + } + + buf = append(buf, data...) + } + + buf, err := chromeos_update_engine.ExecuteSourcePuffDiffOperation(buf, dataBuf) + + if err != nil { + return err + } + + n := uint64(0) + + for _, e := range operation.DstExtents { + _, err := out.Seek(int64(e.GetStartBlock())*blockSize, 0) + if err != nil { + return err + } + + data := make([]byte, e.GetNumBlocks() * blockSize) + copy(data, buf[n*blockSize:]) + if _, err := out.Write(data); err != nil { + return err + } + n += e.GetNumBlocks() + } + break + return fmt.Errorf("%s: PUFFDIFF is not yet implemented!", name) + default: - return fmt.Errorf("Unhandled operation type: %s", operation.GetType().String()) + return fmt.Errorf("%s: Unhandled operation type: %s", name, operation.GetType().String()) } // verify hash @@ -318,13 +465,28 @@ func (p *Payload) worker() { for req := range p.requests { partition := req.partition targetDirectory := req.targetDirectory + sourceDirectory := req.sourceDirectory + isDelta := sourceDirectory != "" name := fmt.Sprintf("%s.img", partition.GetPartitionName()) filepath := fmt.Sprintf("%s/%s", targetDirectory, name) file, err := os.OpenFile(filepath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0755) if err != nil { } - if err := p.Extract(partition, file); err != nil { + + + sourcepath := fmt.Sprintf("%s/%s", sourceDirectory, name) + sourcefile, err := os.OpenFile(sourcepath, os.O_RDONLY, 0755) + if isDelta { + if err != nil { + fmt.Println(err.Error()) + } + } else { + sourcefile = nil + } + + + if err := p.Extract(partition, file, sourcefile); err != nil { fmt.Println(err.Error()) } @@ -338,7 +500,7 @@ func (p *Payload) spawnExtractWorkers(n int) { } } -func (p *Payload) ExtractSelected(targetDirectory string, partitions []string) error { +func (p *Payload) ExtractSelected(sourceDirectory string, targetDirectory string, partitions []string) error { if !p.initialized { return errors.New("Payload has not been initialized") } @@ -360,6 +522,7 @@ func (p *Payload) ExtractSelected(targetDirectory string, partitions []string) e p.workerWG.Add(1) p.requests <- &request{ partition: partition, + sourceDirectory: sourceDirectory, targetDirectory: targetDirectory, } } @@ -370,6 +533,6 @@ func (p *Payload) ExtractSelected(targetDirectory string, partitions []string) e return nil } -func (p *Payload) ExtractAll(targetDirectory string) error { - return p.ExtractSelected(targetDirectory, nil) +func (p *Payload) ExtractAll(sourceDirectory string, targetDirectory string) error { + return p.ExtractSelected(sourceDirectory, targetDirectory, nil) } diff --git a/update_metadata.proto b/update_metadata.proto index a2eccb5..6d16da4 100644 --- a/update_metadata.proto +++ b/update_metadata.proto @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + // Update file format: An update file contains all the operations needed // to update a system to a specific version. It can be a full payload which // can update from any version, or a delta payload which can only update @@ -48,11 +49,14 @@ // char payload_signatures_message[payload_signatures_message_size]; // // }; + // The DeltaArchiveManifest protobuf is an ordered list of InstallOperation // objects. These objects are stored in a linear array in the // DeltaArchiveManifest. Each operation is applied in order by the client. + // The DeltaArchiveManifest also contains the initial and final // checksums for the device. + // The client will perform each InstallOperation in order, beginning even // before the entire delta file is downloaded (but after at least the // protobuf is downloaded). The types of operations are explained: @@ -84,9 +88,11 @@ // // The operations allowed in the payload (supported by the client) depend on the // major and minor version. See InstallOperation.Type below for details. + syntax = "proto2"; + package chromeos_update_engine; -option optimize_for = LITE_RUNTIME; + // Data is packed into blocks on disk, always starting from the beginning // of the block. If a file's data is too large for one block, it overflows // into another block, which may or may not be the following block on the @@ -99,10 +105,12 @@ option optimize_for = LITE_RUNTIME; // run-length encoding). // A sentinel value (kuint64max) as the start block denotes a sparse-hole // in a file whose block-length is specified by num_blocks. + message Extent { optional uint64 start_block = 1; optional uint64 num_blocks = 2; } + // Signatures: Updates may be signed by the OS vendor. The client verifies // an update's signature by hashing the entire download. The section of the // download that contains the signature is at the end of the file, so when @@ -114,10 +122,12 @@ message Extent { // selects a Signature message and uses that, along with a known public key, // to verify the download. The public key is expected to be part of the // client. + message Signatures { message Signature { optional uint32 version = 1 [deprecated = true]; optional bytes data = 2; + // The DER encoded signature size of EC keys is nondeterministic for // different input of sha256 hash. However, we need the size of the // serialized signatures protobuf string to be fixed before signing; @@ -129,47 +139,44 @@ message Signatures { } repeated Signature signatures = 1; } + message PartitionInfo { optional uint64 size = 1; optional bytes hash = 2; } -// Describe an image we are based on in a human friendly way. -// Examples: -// dev-channel, x86-alex, 1.2.3, mp-v3 -// nplusone-channel, x86-alex, 1.2.4, mp-v3, dev-channel, 1.2.3 -// -// All fields will be set, if this message is present. -message ImageInfo { - optional string board = 1; - optional string key = 2; - optional string channel = 3; - optional string version = 4; - // If these values aren't present, they should be assumed to match - // the equivalent value above. They are normally only different for - // special image types such as nplusone images. - optional string build_channel = 5; - optional string build_version = 6; -} + message InstallOperation { enum Type { REPLACE = 0; // Replace destination extents w/ attached data. REPLACE_BZ = 1; // Replace destination extents w/ attached bzipped data. MOVE = 2 [deprecated = true]; // Move source extents to target extents. BSDIFF = 3 [deprecated = true]; // The data is a bsdiff binary diff. + // On minor version 2 or newer, these operations are supported: - SOURCE_COPY = 4; // Copy from source to target partition - SOURCE_BSDIFF = 5; // Like BSDIFF, but read from source partition + SOURCE_COPY = 4; // Copy from source to target partition + SOURCE_BSDIFF = 5; // Like BSDIFF, but read from source partition + // On minor version 3 or newer and on major version 2 or newer, these // operations are supported: - REPLACE_XZ = 8; // Replace destination extents w/ attached xz data. + REPLACE_XZ = 8; // Replace destination extents w/ attached xz data. + // On minor version 4 or newer, these operations are supported: - ZERO = 6; // Write zeros in the destination. + ZERO = 6; // Write zeros in the destination. DISCARD = 7; // Discard the destination blocks, reading as undefined. BROTLI_BSDIFF = 10; // Like SOURCE_BSDIFF, but compressed with brotli. + // On minor version 5 or newer, these operations are supported: PUFFDIFF = 9; // The data is in puffdiff format. + + // On minor version 8 or newer, these operations are supported: + ZUCCHINI = 11; + + // On minor version 9 or newer, these operations are supported: + LZ4DIFF_BSDIFF = 12; + LZ4DIFF_PUFFDIFF = 13; } required Type type = 1; + // Only minor version 6 or newer support 64 bits |data_offset| and // |data_length|, older client will read them as uint32. // The offset into the delta file (after the protobuf) @@ -177,6 +184,7 @@ message InstallOperation { optional uint64 data_offset = 2; // The length of the data in the delta file optional uint64 data_length = 3; + // Ordered list of extents that are read from (if any) and written to. repeated Extent src_extents = 4; // Byte length of src, equal to the number of blocks in src_extents * @@ -184,22 +192,26 @@ message InstallOperation { // pass that external program the number of bytes to read from the blocks we // pass it. This is not used in any other operation. optional uint64 src_length = 5; + repeated Extent dst_extents = 6; // Byte length of dst, equal to the number of blocks in dst_extents * // block_size. Used for BSDIFF and SOURCE_BSDIFF, but not in any other // operation. optional uint64 dst_length = 7; + // Optional SHA 256 hash of the blob associated with this operation. // This is used as a primary validation for http-based downloads and // as a defense-in-depth validation for https-based downloads. If // the operation doesn't refer to any blob, this field will have // zero bytes. optional bytes data_sha256_hash = 8; + // Indicates the SHA 256 hash of the source data referenced in src_extents at // the time of applying the operation. If present, the update_engine daemon // MUST read and verify the source data before applying the operation. optional bytes src_sha256_hash = 9; } + // Hints to VAB snapshot to skip writing some blocks if these blocks are // identical to the ones on the source image. The src & dst extents for each // CowMergeOperation should be contiguous, and they're a subset of an OTA @@ -208,78 +220,125 @@ message InstallOperation { // read after write, similar to the inplace update schema. message CowMergeOperation { enum Type { - COW_COPY = 0; // identical blocks + COW_COPY = 0; // identical blocks + COW_XOR = 1; // used when src/dst blocks are highly similar + COW_REPLACE = 2; // Raw replace operation } optional Type type = 1; + optional Extent src_extent = 2; optional Extent dst_extent = 3; + // For COW_XOR, source location might be unaligned, so this field is in range + // [0, block_size), representing how much should the src_extent shift toward + // larger block number. If this field is non-zero, then src_extent will + // include 1 extra block in the end, as the merge op actually references the + // first |src_offset| bytes of that extra block. For example, if |dst_extent| + // is [10, 15], |src_offset| is 500, then src_extent might look like [25, 31]. + // Note that |src_extent| contains 1 extra block than the |dst_extent|. + optional uint32 src_offset = 4; } + // Describes the update to apply to a single partition. message PartitionUpdate { // A platform-specific name to identify the partition set being updated. For // example, in Chrome OS this could be "ROOT" or "KERNEL". required string partition_name = 1; + // Whether this partition carries a filesystem with post-install program that // must be run to finalize the update process. See also |postinstall_path| and // |filesystem_type|. optional bool run_postinstall = 2; + // The path of the executable program to run during the post-install step, // relative to the root of this filesystem. If not set, the default "postinst" // will be used. This setting is only used when |run_postinstall| is set and // true. optional string postinstall_path = 3; + // The filesystem type as passed to the mount(2) syscall when mounting the new // filesystem to run the post-install program. If not set, a fixed list of // filesystems will be attempted. This setting is only used if // |run_postinstall| is set and true. optional string filesystem_type = 4; + // If present, a list of signatures of the new_partition_info.hash signed with // different keys. If the update_engine daemon requires vendor-signed images // and has its public key installed, one of the signatures should be valid // for /postinstall to run. repeated Signatures.Signature new_partition_signature = 5; + optional PartitionInfo old_partition_info = 6; optional PartitionInfo new_partition_info = 7; + // The list of operations to be performed to apply this PartitionUpdate. The // associated operation blobs (in operations[i].data_offset, data_length) // should be stored contiguously and in the same order. repeated InstallOperation operations = 8; + // Whether a failure in the postinstall step for this partition should be // ignored. optional bool postinstall_optional = 9; + // On minor version 6 or newer, these fields are supported: + // The extent for data covered by verity hash tree. optional Extent hash_tree_data_extent = 10; + // The extent to store verity hash tree. optional Extent hash_tree_extent = 11; + // The hash algorithm used in verity hash tree. optional string hash_tree_algorithm = 12; + // The salt used for verity hash tree. optional bytes hash_tree_salt = 13; + // The extent for data covered by FEC. optional Extent fec_data_extent = 14; + // The extent to store FEC. optional Extent fec_extent = 15; + // The number of FEC roots. optional uint32 fec_roots = 16 [default = 2]; + // Per-partition version used for downgrade detection, added // as an effort to support partial updates. For most partitions, // this is the build timestamp. optional string version = 17; + // A sorted list of CowMergeOperation. When writing cow, we can choose to // skip writing the raw bytes for these extents. During snapshot merge, the // bytes will read from the source partitions instead. repeated CowMergeOperation merge_operations = 18; + + // Estimated size for COW image. This is used by libsnapshot + // as a hint. If set to 0, libsnapshot should use alternative + // methods for estimating size. + optional uint64 estimate_cow_size = 19; + + // Information about the cow used by Cow Writer to specify + // number of cow operations to be written + optional uint64 estimate_op_count_max = 20; } + message DynamicPartitionGroup { // Name of the group. required string name = 1; + // Maximum size of the group. The sum of sizes of all partitions in the group // must not exceed the maximum size of the group. optional uint64 size = 2; + // A list of partitions that belong to the group. repeated string partition_names = 3; } + +message VABCFeatureSet { + optional bool threaded = 1; + optional bool batch_writes = 2; +} + // Metadata related to all dynamic partitions. message DynamicPartitionMetadata { // All updatable groups present in |partitions| of this DeltaArchiveManifest. @@ -289,20 +348,60 @@ message DynamicPartitionMetadata { // - If an updatable group is in the manifest but not on the device, the group // is added to the device. repeated DynamicPartitionGroup groups = 1; + // Whether dynamic partitions have snapshots during the update. If this is // set to true, the update_engine daemon creates snapshots for all dynamic // partitions if possible. If this is unset, the update_engine daemon MUST // NOT create snapshots for dynamic partitions. optional bool snapshot_enabled = 2; + + // If this is set to false, update_engine should not use VABC regardless. If + // this is set to true, update_engine may choose to use VABC if device + // supports it, but not guaranteed. + // VABC stands for Virtual AB Compression + optional bool vabc_enabled = 3; + + // The compression algorithm used by VABC. Available ones are "gz", "brotli". + // See system/core/fs_mgr/libsnapshot/cow_writer.cpp for available options, + // as this parameter is ultimated forwarded to libsnapshot's CowWriter + optional string vabc_compression_param = 4; + + // COW version used by VABC. The represents the major version in the COW + // header + optional uint32 cow_version = 5; + + // A collection of knobs to tune Virtual AB Compression + optional VABCFeatureSet vabc_feature_set = 6; + + // Max bytes to be compressed at once during ota. Options: 4k, 8k, 16k, 32k, + // 64k, 128k + optional uint64 compression_factor = 7; +} + +// Definition has been duplicated from +// $ANDROID_BUILD_TOP/build/tools/releasetools/ota_metadata.proto. Keep in sync. +message ApexInfo { + optional string package_name = 1; + optional int64 version = 2; + optional bool is_compressed = 3; + optional int64 decompressed_size = 4; +} + +// Definition has been duplicated from +// $ANDROID_BUILD_TOP/build/tools/releasetools/ota_metadata.proto. Keep in sync. +message ApexMetadata { + repeated ApexInfo apex_info = 1; } + message DeltaArchiveManifest { // Only present in major version = 1. List of install operations for the // kernel and rootfs partitions. For major version = 2 see the |partitions| // field. - repeated InstallOperation install_operations = 1 [deprecated = true]; - repeated InstallOperation kernel_install_operations = 2 [deprecated = true]; + reserved 1, 2; + // (At time of writing) usually 4096 optional uint32 block_size = 3 [default = 4096]; + // If signatures are present, the offset into the blobs, generally // tacked onto the end of the file, and the length. We use an offset // rather than a bool to allow for more flexibility in future file formats. @@ -310,18 +409,14 @@ message DeltaArchiveManifest { // file. optional uint64 signatures_offset = 4; optional uint64 signatures_size = 5; - // Only present in major version = 1. Partition metadata used to validate the - // update. For major version = 2 see the |partitions| field. - optional PartitionInfo old_kernel_info = 6 [deprecated = true]; - optional PartitionInfo new_kernel_info = 7 [deprecated = true]; - optional PartitionInfo old_rootfs_info = 8 [deprecated = true]; - optional PartitionInfo new_rootfs_info = 9 [deprecated = true]; - // old_image_info will only be present for delta images. - optional ImageInfo old_image_info = 10; - optional ImageInfo new_image_info = 11; + + // Fields deprecated in major version 2. + reserved 6,7,8,9,10,11; + // The minor version, also referred as "delta version", of the payload. // Minor version 0 is full payload, everything else is delta payload. optional uint32 minor_version = 12 [default = 0]; + // Only present in major version >= 2. List of partitions that will be // updated, in the order they will be updated. This field replaces the // |install_operations|, |kernel_install_operations| and the @@ -329,11 +424,22 @@ message DeltaArchiveManifest { // array can have more than two partitions if needed, and they are identified // by the partition name. repeated PartitionUpdate partitions = 13; + // The maximum timestamp of the OS allowed to apply this payload. // Can be used to prevent downgrading the OS. optional int64 max_timestamp = 14; + // Metadata related to all dynamic partitions. optional DynamicPartitionMetadata dynamic_partition_metadata = 15; + // If the payload only updates a subset of partitions on the device. optional bool partial_update = 16; + + // Information on compressed APEX to figure out how much space is required for + // their decompression + repeated ApexInfo apex_info = 17; + + // Security patch level of the device, usually in the format of + // yyyy-mm-dd + optional string security_patch_level = 18; }