diagnose.c: add option to configure archive contents

Update 'create_diagnostics_archive()' to take an argument 'mode'. When archiving diagnostics for a repository, 'mode' is used to selectively include/exclude information based on its value. The initial options for 'mode' are: * DIAGNOSE_NONE: do not collect any diagnostics or create an archive (no-op). * DIAGNOSE_STATS: collect basic repository metadata (Git version, repo path, filesystem available space) as well as sizing and count statistics for the repository's objects and packfiles. * DIAGNOSE_ALL: collect basic repository metadata, sizing/count statistics, and copies of the '.git', '.git/hooks', '.git/info', '.git/logs', and '.git/objects/info' directories. These modes are introduced to provide users the option to collect diagnostics without the sensitive information included in copies of '.git' dir contents. At the moment, only 'scalar diagnose' uses 'create_diagnostics_archive()' (with a hardcoded 'DIAGNOSE_ALL' mode to match existing functionality), but more callers will be introduced in subsequent patches. Finally, refactor from a hardcoded set of 'add_directory_to_archiver()' calls to iterative invocations gated by 'DIAGNOSE_ALL'. This allows for easier future modification of the set of directories to archive and improves error reporting when 'add_directory_to_archiver()' fails. Helped-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Victoria Dye <vdye@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Victoria Dye committed Aug 12, 2022 at 20:10 UTC 33cba726f03e1e06b10b85cf4a1cbd1017810486
3 files changed +39 -10
contrib/scalar/scalar.c
+1 -1
@@ -534,7 +534,7 @@ static int cmd_diagnose(int argc, const char **argv)
534 goto diagnose_cleanup;
535 }
536
537 - res = create_diagnostics_archive(&zip_path);
537 + res = create_diagnostics_archive(&zip_path, DIAGNOSE_ALL);
538
539 diagnose_cleanup:
540 strbuf_release(&zip_path);
diagnose.c
+31 -8
@@ -8,6 +8,11 @@
8 #include "object-store.h"
9 #include "packfile.h"
10
11 +struct archive_dir {
12 + const char *path;
13 + int recursive;
14 +};
15 +
16 static void dir_file_stats_objects(const char *full_path, size_t full_path_len,
17 const char *file_name, void *data)
18 {
@@ -132,13 +137,25 @@ static int add_directory_to_archiver(struct strvec *archiver_args,
137 return res;
138 }
139
135 -int create_diagnostics_archive(struct strbuf *zip_path)
140 +int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode)
141 {
142 struct strvec archiver_args = STRVEC_INIT;
143 char **argv_copy = NULL;
144 int stdout_fd = -1, archiver_fd = -1;
145 struct strbuf buf = STRBUF_INIT;
141 - int res;
146 + int res, i;
147 + struct archive_dir archive_dirs[] = {
148 + { ".git", 0 },
149 + { ".git/hooks", 0 },
150 + { ".git/info", 0 },
151 + { ".git/logs", 1 },
152 + { ".git/objects/info", 0 }
153 + };
154 +
155 + if (mode == DIAGNOSE_NONE) {
156 + res = 0;
157 + goto diagnose_cleanup;
158 + }
159
160 stdout_fd = dup(STDOUT_FILENO);
161 if (stdout_fd < 0) {
@@ -177,12 +194,18 @@ int create_diagnostics_archive(struct strbuf *zip_path)
194 loose_objs_stats(&buf, ".git/objects");
195 strvec_push(&archiver_args, buf.buf);
196
180 - if ((res = add_directory_to_archiver(&archiver_args, ".git", 0)) ||
181 - (res = add_directory_to_archiver(&archiver_args, ".git/hooks", 0)) ||
182 - (res = add_directory_to_archiver(&archiver_args, ".git/info", 0)) ||
183 - (res = add_directory_to_archiver(&archiver_args, ".git/logs", 1)) ||
184 - (res = add_directory_to_archiver(&archiver_args, ".git/objects/info", 0)))
185 - goto diagnose_cleanup;
197 + /* Only include this if explicitly requested */
198 + if (mode == DIAGNOSE_ALL) {
199 + for (i = 0; i < ARRAY_SIZE(archive_dirs); i++) {
200 + if (add_directory_to_archiver(&archiver_args,
201 + archive_dirs[i].path,
202 + archive_dirs[i].recursive)) {
203 + res = error_errno(_("could not add directory '%s' to archiver"),
204 + archive_dirs[i].path);
205 + goto diagnose_cleanup;
206 + }
207 + }
208 + }
209
210 strvec_pushl(&archiver_args, "--prefix=",
211 oid_to_hex(the_hash_algo->empty_tree), "--", NULL);
diagnose.h
+7 -1
@@ -3,6 +3,12 @@
3
4 #include "strbuf.h"
5
6 -int create_diagnostics_archive(struct strbuf *zip_path);
6 +enum diagnose_mode {
7 + DIAGNOSE_NONE,
8 + DIAGNOSE_STATS,
9 + DIAGNOSE_ALL
10 +};
11 +
12 +int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode);
13
14 #endif /* DIAGNOSE_H */