Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: generate_delta_main.cc

Issue 6305002: AU: Add options to delta_generator to hash and sign generated payloads. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git@master
Patch Set: review comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <sys/types.h> 5 #include <sys/types.h>
6 #include <sys/stat.h> 6 #include <sys/stat.h>
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 10
11 #include <set> 11 #include <set>
12 #include <string> 12 #include <string>
13 #include <vector> 13 #include <vector>
14 14
15 #include <base/command_line.h> 15 #include <base/command_line.h>
16 #include <base/logging.h> 16 #include <base/logging.h>
17 #include <gflags/gflags.h> 17 #include <gflags/gflags.h>
18 #include <glib.h> 18 #include <glib.h>
19 19
20 #include "update_engine/delta_diff_generator.h" 20 #include "update_engine/delta_diff_generator.h"
21 #include "update_engine/delta_performer.h" 21 #include "update_engine/delta_performer.h"
22 #include "update_engine/payload_signer.h"
22 #include "update_engine/prefs.h" 23 #include "update_engine/prefs.h"
23 #include "update_engine/subprocess.h" 24 #include "update_engine/subprocess.h"
24 #include "update_engine/terminator.h" 25 #include "update_engine/terminator.h"
25 #include "update_engine/update_metadata.pb.h" 26 #include "update_engine/update_metadata.pb.h"
26 #include "update_engine/utils.h" 27 #include "update_engine/utils.h"
27 28
28 DEFINE_string(old_dir, "", 29 DEFINE_string(old_dir, "",
29 "Directory where the old rootfs is loop mounted read-only"); 30 "Directory where the old rootfs is loop mounted read-only");
30 DEFINE_string(new_dir, "", 31 DEFINE_string(new_dir, "",
31 "Directory where the new rootfs is loop mounted read-only"); 32 "Directory where the new rootfs is loop mounted read-only");
32 DEFINE_string(old_image, "", "Path to the old rootfs"); 33 DEFINE_string(old_image, "", "Path to the old rootfs");
33 DEFINE_string(new_image, "", "Path to the new rootfs"); 34 DEFINE_string(new_image, "", "Path to the new rootfs");
34 DEFINE_string(out_file, "", "Path to output file");
35 DEFINE_string(old_kernel, "", "Path to the old kernel partition image"); 35 DEFINE_string(old_kernel, "", "Path to the old kernel partition image");
36 DEFINE_string(new_kernel, "", "Path to the new kernel partition image"); 36 DEFINE_string(new_kernel, "", "Path to the new kernel partition image");
37 DEFINE_string(in_file, "",
38 "Path to input delta payload file used to hash/sign payloads "
39 "and apply delta over old_image (for debugging)");
40 DEFINE_string(out_file, "", "Path to output delta payload file");
41 DEFINE_string(out_hash_file, "", "Path to output hash file");
37 DEFINE_string(private_key, "", "Path to private key in .pem format"); 42 DEFINE_string(private_key, "", "Path to private key in .pem format");
38 DEFINE_string(apply_delta, "",
39 "If set, apply delta over old_image. (For debugging.)");
40 DEFINE_string(prefs_dir, "/tmp/update_engine_prefs", 43 DEFINE_string(prefs_dir, "/tmp/update_engine_prefs",
41 "Preferences directory, used with apply_delta."); 44 "Preferences directory, used with apply_delta");
45 DEFINE_int32(signature_size, 0, "Raw signature size used for hash calculation");
46 DEFINE_string(signature_file, "", "Raw signature file to sign payload with");
42 47
43 // This file contains a simple program that takes an old path, a new path, 48 // This file contains a simple program that takes an old path, a new path,
44 // and an output file as arguments and the path to an output file and 49 // and an output file as arguments and the path to an output file and
45 // generates a delta that can be sent to Chrome OS clients. 50 // generates a delta that can be sent to Chrome OS clients.
46 51
47 using std::set; 52 using std::set;
48 using std::string; 53 using std::string;
49 using std::vector; 54 using std::vector;
50 55
51 namespace chromeos_update_engine { 56 namespace chromeos_update_engine {
52 57
53 namespace { 58 namespace {
54 59
55 bool IsDir(const char* path) { 60 bool IsDir(const char* path) {
56 struct stat stbuf; 61 struct stat stbuf;
57 TEST_AND_RETURN_FALSE_ERRNO(lstat(path, &stbuf) == 0); 62 TEST_AND_RETURN_FALSE_ERRNO(lstat(path, &stbuf) == 0);
58 return S_ISDIR(stbuf.st_mode); 63 return S_ISDIR(stbuf.st_mode);
59 } 64 }
60 65
66 void CalculatePayloadHashForSigning() {
67 LOG(INFO) << "Calculating payload hash for signing.";
68 LOG_IF(FATAL, FLAGS_in_file.empty())
69 << "Must pass --in_file to calculate hash for signing.";
70 LOG_IF(FATAL, FLAGS_out_hash_file.empty())
71 << "Must pass --out_hash_file to calculate hash for signing.";
72 LOG_IF(FATAL, FLAGS_signature_size <= 0)
73 << "Must pass --signature_size to calculate hash for signing.";
74 vector<char> hash;
75 CHECK(PayloadSigner::HashPayloadForSigning(
76 FLAGS_in_file, FLAGS_signature_size, &hash));
77 CHECK(utils::WriteFile(
78 FLAGS_out_hash_file.c_str(), hash.data(), hash.size()));
79 LOG(INFO) << "Done calculating payload hash for signing.";
80 }
81
82 void SignPayload() {
83 LOG(INFO) << "Signing payload.";
84 LOG_IF(FATAL, FLAGS_in_file.empty())
85 << "Must pass --in_file to sign payload.";
86 LOG_IF(FATAL, FLAGS_out_file.empty())
87 << "Must pass --out_file to sign payload.";
88 LOG_IF(FATAL, FLAGS_signature_file.empty())
89 << "Must pass --signature_file to sign payload.";
90 vector<char> signature;
91 CHECK(utils::ReadFile(FLAGS_signature_file, &signature));
92 CHECK(PayloadSigner::AddSignatureToPayload(
93 FLAGS_in_file, signature, FLAGS_out_file));
94 LOG(INFO) << "Done signing payload.";
95 }
96
97 void ApplyDelta() {
98 LOG(INFO) << "Applying delta.";
99 LOG_IF(FATAL, FLAGS_old_image.empty())
100 << "Must pass --old_image to apply delta.";
101 Prefs prefs;
102 LOG(INFO) << "Setting up preferences under: " << FLAGS_prefs_dir;
103 LOG_IF(ERROR, !prefs.Init(FilePath(FLAGS_prefs_dir)))
104 << "Failed to initialize preferences.";
105 // Get original checksums
106 LOG(INFO) << "Calculating original checksums";
107 PartitionInfo kern_info, root_info;
108 CHECK(DeltaDiffGenerator::InitializePartitionInfo(true, // is_kernel
109 FLAGS_old_kernel,
110 &kern_info));
111 CHECK(DeltaDiffGenerator::InitializePartitionInfo(false, // is_kernel
112 FLAGS_old_image,
113 &root_info));
114 vector<char> kern_hash(kern_info.hash().begin(),
115 kern_info.hash().end());
116 vector<char> root_hash(root_info.hash().begin(),
117 root_info.hash().end());
118 DeltaPerformer performer(&prefs);
119 performer.set_current_kernel_hash(kern_hash);
120 performer.set_current_rootfs_hash(root_hash);
121 CHECK_EQ(performer.Open(FLAGS_old_image.c_str(), 0, 0), 0);
122 CHECK(performer.OpenKernel(FLAGS_old_kernel.c_str()));
123 vector<char> buf(1024 * 1024);
124 int fd = open(FLAGS_in_file.c_str(), O_RDONLY, 0);
125 CHECK_GE(fd, 0);
126 ScopedFdCloser fd_closer(&fd);
127 for (off_t offset = 0;; offset += buf.size()) {
128 ssize_t bytes_read;
129 CHECK(utils::PReadAll(fd, &buf[0], buf.size(), offset, &bytes_read));
130 if (bytes_read == 0)
131 break;
132 CHECK_EQ(performer.Write(&buf[0], bytes_read), bytes_read);
133 }
134 CHECK_EQ(performer.Close(), 0);
135 DeltaPerformer::ResetUpdateProgress(&prefs, false);
136 LOG(INFO) << "Done applying delta.";
137 }
138
61 int Main(int argc, char** argv) { 139 int Main(int argc, char** argv) {
62 g_thread_init(NULL); 140 g_thread_init(NULL);
63 google::ParseCommandLineFlags(&argc, &argv, true); 141 google::ParseCommandLineFlags(&argc, &argv, true);
64 CommandLine::Init(argc, argv); 142 CommandLine::Init(argc, argv);
65 Terminator::Init(); 143 Terminator::Init();
66 Subprocess::Init(); 144 Subprocess::Init();
67 logging::InitLogging("delta_generator.log", 145 logging::InitLogging("delta_generator.log",
68 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, 146 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
69 logging::DONT_LOCK_LOG_FILE, 147 logging::DONT_LOCK_LOG_FILE,
70 logging::APPEND_TO_OLD_LOG_FILE); 148 logging::APPEND_TO_OLD_LOG_FILE);
71 if (!FLAGS_apply_delta.empty()) { 149 if (FLAGS_signature_size > 0 || !FLAGS_out_hash_file.empty()) {
72 if (FLAGS_old_image.empty()) { 150 CalculatePayloadHashForSigning();
73 LOG(FATAL) << "Must pass --old_image with --apply_delta."; 151 return 0;
74 } 152 }
75 Prefs prefs; 153 if (!FLAGS_signature_file.empty()) {
76 LOG(INFO) << "Setting up preferences under: " << FLAGS_prefs_dir; 154 SignPayload();
77 LOG_IF(ERROR, !prefs.Init(FilePath(FLAGS_prefs_dir))) 155 return 0;
78 << "Failed to initialize preferences."; 156 }
79 // Get original checksums 157 if (!FLAGS_in_file.empty()) {
80 LOG(INFO) << "Calculating original checksums"; 158 ApplyDelta();
81 PartitionInfo kern_info, root_info;
82 CHECK(DeltaDiffGenerator::InitializePartitionInfo(true, // is_kernel
83 FLAGS_old_kernel,
84 &kern_info));
85 CHECK(DeltaDiffGenerator::InitializePartitionInfo(false, // is_kernel
86 FLAGS_old_image,
87 &root_info));
88 vector<char> kern_hash(kern_info.hash().begin(),
89 kern_info.hash().end());
90 vector<char> root_hash(root_info.hash().begin(),
91 root_info.hash().end());
92 DeltaPerformer performer(&prefs);
93 performer.set_current_kernel_hash(kern_hash);
94 performer.set_current_rootfs_hash(root_hash);
95 CHECK_EQ(performer.Open(FLAGS_old_image.c_str(), 0, 0), 0);
96 CHECK(performer.OpenKernel(FLAGS_old_kernel.c_str()));
97 vector<char> buf(1024 * 1024);
98 int fd = open(FLAGS_apply_delta.c_str(), O_RDONLY, 0);
99 CHECK_GE(fd, 0);
100 ScopedFdCloser fd_closer(&fd);
101 for (off_t offset = 0;; offset += buf.size()) {
102 ssize_t bytes_read;
103 CHECK(utils::PReadAll(fd, &buf[0], buf.size(), offset, &bytes_read));
104 if (bytes_read == 0)
105 break;
106 CHECK_EQ(performer.Write(&buf[0], bytes_read), bytes_read);
107 }
108 CHECK_EQ(performer.Close(), 0);
109 DeltaPerformer::ResetUpdateProgress(&prefs, false);
110 LOG(INFO) << "done applying delta.";
111 return 0; 159 return 0;
112 } 160 }
113 CHECK(!FLAGS_new_image.empty()); 161 CHECK(!FLAGS_new_image.empty());
114 CHECK(!FLAGS_out_file.empty()); 162 CHECK(!FLAGS_out_file.empty());
115 CHECK(!FLAGS_new_kernel.empty()); 163 CHECK(!FLAGS_new_kernel.empty());
116 if (FLAGS_old_image.empty()) { 164 if (FLAGS_old_image.empty()) {
117 LOG(INFO) << "Generating full update"; 165 LOG(INFO) << "Generating full update";
118 } else { 166 } else {
119 LOG(INFO) << "Generating delta update"; 167 LOG(INFO) << "Generating delta update";
120 CHECK(!FLAGS_old_dir.empty()); 168 CHECK(!FLAGS_old_dir.empty());
(...skipping 14 matching lines...) Expand all
135 return 0; 183 return 0;
136 } 184 }
137 185
138 } // namespace {} 186 } // namespace {}
139 187
140 } // namespace chromeos_update_engine 188 } // namespace chromeos_update_engine
141 189
142 int main(int argc, char** argv) { 190 int main(int argc, char** argv) {
143 return chromeos_update_engine::Main(argc, argv); 191 return chromeos_update_engine::Main(argc, argv);
144 } 192 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698