public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
* [PATCH 0/4] Introduce a "promisor-remote" capability
@ 2024-07-31 13:40 Christian Couder
  2024-07-31 13:40 ` [PATCH 1/4] version: refactor strbuf_sanitize() Christian Couder
                   ` (6 more replies)
  0 siblings, 7 replies; 111+ messages in thread
From: Christian Couder @ 2024-07-31 13:40 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, John Cai, Patrick Steinhardt, Christian Couder

Earlier this year, I sent 3 versions of a patch series with the goal
of allowing a client C to clone from a server S while using the same
promisor remote X that S already use. See:

https://lore.kernel.org/git/20240418184043.2900955-1-christian.couder@gmail.com/

Junio suggested to instead implement that feature using:

"a protocol extension that lets S tell C that S wants C to fetch
missing objects from X (which means that if C knows about X in its
".git/config" then there is no need for end-user interaction at all),
or a protocol extension that C tells S that C is willing to see
objects available from X omitted when S does not have them (again,
this could be done by looking at ".git/config" at C, but there may be
security implications???)"

This patch series implements that protocol extension called
"promisor-remote" (that name is open to change or simplification)
which allows S and C to agree on C using X directly or not.

I have tried to implement it in a quite generic way that could allow S
and C to share more information about promisor remotes and how to use
them.

For now C doesn't use the information it gets from S when cloning.
That information is only used to decide if C is Ok to use the promisor
remotes advertised by S. But this could change which could make it
much simpler for clients than using the current way of passing
information about X with the `-c` option of `git clone` many times on
the command line.

Another improvement could be to not require GIT_NO_LAZY_FETCH=0 when S
and C have agreed on using S.

Christian Couder (4):
  version: refactor strbuf_sanitize()
  strbuf: refactor strbuf_trim_trailing_ch()
  Add 'promisor-remote' capability to protocol v2
  promisor-remote: check advertised name or URL

 Documentation/config/promisor.txt     |  18 ++
 Documentation/gitprotocol-v2.txt      |  37 +++++
 connect.c                             |   7 +
 promisor-remote.c                     | 228 ++++++++++++++++++++++++++
 promisor-remote.h                     |  26 ++-
 serve.c                               |  21 +++
 strbuf.c                              |  16 ++
 strbuf.h                              |  10 ++
 t/t5555-http-smart-common.sh          |   1 +
 t/t5701-git-serve.sh                  |   1 +
 t/t5710-promisor-remote-capability.sh | 192 ++++++++++++++++++++++
 trace2/tr2_cfg.c                      |  10 +-
 upload-pack.c                         |   3 +
 version.c                             |   9 +-
 14 files changed, 563 insertions(+), 16 deletions(-)
 create mode 100755 t/t5710-promisor-remote-capability.sh

-- 
2.46.0.4.gbcb884ee16


^ permalink raw reply	[flat|nested] 111+ messages in thread
* [PATCH v3 6/6] connect: advertise OS version
@ 2025-01-24 12:21 Usman Akinyemi
  2025-02-05 18:52 ` [PATCH v4 0/6][Outreachy] extend agent capability to include OS name Usman Akinyemi
  0 siblings, 1 reply; 111+ messages in thread
From: Usman Akinyemi @ 2025-01-24 12:21 UTC (permalink / raw)
  To: git, christian.couder
  Cc: gitster, ps, johncai86, Johannes.Schindelin, me, phillip.wood,
	rsbecker, sunshine, Christian Couder

As some issues that can happen with a Git client can be operating system
specific, it can be useful for a server to know which OS a client is
using. In the same way it can be useful for a client to know which OS
a server is using.

Let's introduce a new protocol (`os-version`) allowing Git clients and
servers to exchange operating system information.

Having the `os-version` protocol capability separately from other protocol
capabilities like `agent` is beneficial in ways like:

- It provides a clear separation between Git versioning and OS-specific,
concerns making troubleshooting and environment analysis more modular.
- It ensures we do not disrupt people's scripts that collect statistics
from other protocol capabilities like `agent`.
- It offers flexibility for possible future extensibility, allowing us to
add additional system-level details without modifying existing `agent`
parsing logic.
- It provides better control over privacy and security by allowing
selective exposure of OS information.

Add the `transfer.advertiseOSVersion` config option to address
privacy concerns. It defaults to `true` and can be changed to
`false`. When enabled, this option makes clients and servers send each
other the OS name (e.g., "Linux" or "Windows"). The information is
retrieved using the 'sysname' field of the `uname(2)` system call or its
equivalent.

However, there are differences between `uname(1)` (command-line utility)
and `uname(2)` (system call) outputs on Windows. These discrepancies
complicate testing on Windows platforms. For example:
  - `uname(1)` output: MINGW64_NT-10.0-20348.3.4.10-87d57229.x86_64\
  .2024-02-14.20:17.UTC.x86_64
  - `uname(2)` output: Windows.10.0.20348

On Windows, uname(2) is not actually system-supplied but is instead
already faked up by Git itself. We could have overcome the test issue
on Windows by implementing a new `uname` subcommand in `test-tool`
using uname(2), but except uname(2), which would be tested against
itself, there would be nothing platform specific, so it's just simpler
to disable the tests on Windows.

Mentored-by: Christian Couder <chriscool@tuxfamily•org>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail•com>
---
 Documentation/config/transfer.txt |  7 +++++++
 Documentation/gitprotocol-v2.txt  | 17 +++++++++++++++++
 connect.c                         |  3 +++
 serve.c                           | 14 ++++++++++++++
 t/t5555-http-smart-common.sh      | 10 +++++++++-
 t/t5701-git-serve.sh              | 22 +++++++++++++++++++---
 t/test-lib-functions.sh           |  8 ++++++++
 version.c                         | 29 +++++++++++++++++++++++++++++
 version.h                         | 15 +++++++++++++++
 9 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.txt
index f1ce50f4a6..016eb27430 100644
--- a/Documentation/config/transfer.txt
+++ b/Documentation/config/transfer.txt
@@ -125,3 +125,10 @@ transfer.bundleURI::
 transfer.advertiseObjectInfo::
 	When `true`, the `object-info` capability is advertised by
 	servers. Defaults to false.
+
+transfer.advertiseOSVersion::
+	When set to `true` on the server, the server will advertise its
+	`os-version` capability to the client. On the client side, if set
+	to `true`, it will advertise its `os-version` capability to the
+	server only if the server also advertises its `os-version` capability.
+	Defaults to true.
diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt
index 1652fef3ae..62f7ae3423 100644
--- a/Documentation/gitprotocol-v2.txt
+++ b/Documentation/gitprotocol-v2.txt
@@ -190,6 +190,23 @@ printable ASCII characters except space (i.e., the byte range 32 < x <
 and debugging purposes, and MUST NOT be used to programmatically assume
 the presence or absence of particular features.
 
+os-version
+~~~~~~~~~~
+
+In the same way as the `agent` capability above, the server can
+advertise the `os-version` capability to notify the client the
+kind of operating system it is running on. The client may optionally
+send its own `os-version` capability, to notify the server the kind
+of operating system it is also running on in its request to the server
+(but it MUST NOT do so if the server did not advertise the os-version
+capability). The value of this capability may consist of ASCII printable
+characters(from 33 to 126 inclusive) and are typically made from the
+result of `uname -s`(OS name e.g Linux). The os-version capability can
+be disabled entirely by setting the `transfer.advertiseOSVersion` config
+option to `false`. The `os-version` strings are purely informative for
+statistics and debugging purposes, and MUST NOT be used to
+programmatically assume the presence or absence of particular features.
+
 ls-refs
 ~~~~~~~
 
diff --git a/connect.c b/connect.c
index 10fad43e98..6d5792b63c 100644
--- a/connect.c
+++ b/connect.c
@@ -492,6 +492,9 @@ static void send_capabilities(int fd_out, struct packet_reader *reader)
 	if (server_supports_v2("agent"))
 		packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
 
+	if (server_supports_v2("os-version") && advertise_os_version(the_repository))
+		packet_write_fmt(fd_out, "os-version=%s", os_version_sanitized());
+
 	if (server_feature_v2("object-format", &hash_name)) {
 		int hash_algo = hash_algo_by_name(hash_name);
 		if (hash_algo == GIT_HASH_UNKNOWN)
diff --git a/serve.c b/serve.c
index c8694e3751..5b0d54ae9a 100644
--- a/serve.c
+++ b/serve.c
@@ -31,6 +31,16 @@ static int agent_advertise(struct repository *r UNUSED,
 	return 1;
 }
 
+static int os_version_advertise(struct repository *r,
+			   struct strbuf *value)
+{
+	if (!advertise_os_version(r))
+		return 0;
+	if (value)
+		strbuf_addstr(value, os_version_sanitized());
+	return 1;
+}
+
 static int object_format_advertise(struct repository *r,
 				   struct strbuf *value)
 {
@@ -123,6 +133,10 @@ static struct protocol_capability capabilities[] = {
 		.name = "agent",
 		.advertise = agent_advertise,
 	},
+	{
+		.name = "os-version",
+		.advertise = os_version_advertise,
+	},
 	{
 		.name = "ls-refs",
 		.advertise = ls_refs_advertise,
diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh
index e47ea1ad10..b1af37a4a2 100755
--- a/t/t5555-http-smart-common.sh
+++ b/t/t5555-http-smart-common.sh
@@ -123,9 +123,17 @@ test_expect_success 'git receive-pack --advertise-refs: v1' '
 '
 
 test_expect_success 'git upload-pack --advertise-refs: v2' '
+	printf "agent=FAKE\n" >agent_and_osversion &&
+	if test_have_prereq WINDOWS
+	then
+		git config transfer.advertiseOSVersion false
+	else
+		printf "os-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_osversion
+	fi &&
+
 	cat >expect <<-EOF &&
 	version 2
-	agent=FAKE
+	$(cat agent_and_osversion)
 	ls-refs=unborn
 	fetch=shallow wait-for-done
 	server-option
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
index 9394235fa0..2616132b95 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -23,13 +23,29 @@ test_expect_success 'setup to generate files with expected content' '
 	server-option
 	object-format=$(test_oid algo)
 	EOF
-	cat >expect.trailer <<-EOF
+	cat >expect.trailer <<-EOF &&
 	0000
 	EOF
+
+	if test_have_prereq WINDOWS
+	then
+		git config transfer.advertiseOSVersion false
+	else
+		printf "os-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_osversion
+	fi &&
+
+	cat >expect_osversion.base <<-EOF
+	version 2
+	$(cat agent_and_osversion)
+	ls-refs=unborn
+	fetch=shallow wait-for-done
+	server-option
+	object-format=$(test_oid algo)
+	EOF
 '
 
 test_expect_success 'test capability advertisement' '
-	cat expect.base expect.trailer >expect &&
+	cat expect_osversion.base expect.trailer >expect &&
 
 	GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
 		--advertise-capabilities >out &&
@@ -357,7 +373,7 @@ test_expect_success 'test capability advertisement with uploadpack.advertiseBund
 	cat >expect.extra <<-EOF &&
 	bundle-uri
 	EOF
-	cat expect.base \
+	cat expect_osversion.base \
 	    expect.extra \
 	    expect.trailer >expect &&
 
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 78e054ab50..3465904323 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -2007,3 +2007,11 @@ test_trailing_hash () {
 		test-tool hexdump |
 		sed "s/ //g"
 }
+
+# Trim and replace each character with ascii code below 32 or above
+# 127 (included) using a dot '.' character.
+# Octal intervals \001-\040 and \177-\377
+# correspond to decimal intervals 1-32 and 127-255
+test_redact_non_printables () {
+    tr -d "\n\r" | tr "[\001-\040][\177-\377]" "."
+}
diff --git a/version.c b/version.c
index d95221a72a..083154a6cb 100644
--- a/version.c
+++ b/version.c
@@ -4,6 +4,7 @@
 #include "strbuf.h"
 #include "sane-ctype.h"
 #include "gettext.h"
+#include "config.h"
 
 const char git_version_string[] = GIT_VERSION;
 const char git_built_from_commit_string[] = GIT_BUILT_FROM_COMMIT;
@@ -69,3 +70,31 @@ int get_uname_info(struct strbuf *buf, unsigned int full)
 	     strbuf_addf(buf, "%s\n", uname_info.sysname);
 	return 0;
 }
+
+const char *os_version_sanitized(void)
+{
+	static const char *os = NULL;
+
+	if (!os) {
+		struct strbuf buf = STRBUF_INIT;
+
+		get_uname_info(&buf, 0);
+		/* Sanitize the os information immediately */
+		redact_non_printables(&buf);
+		os = strbuf_detach(&buf, NULL);
+	}
+
+	return os;
+}
+
+int advertise_os_version(struct repository *r)
+{
+	static int transfer_advertise_os_version = -1;
+
+	if (transfer_advertise_os_version == -1) {
+		repo_config_get_bool(r, "transfer.advertiseosversion", &transfer_advertise_os_version);
+		/* enabled by default */
+		transfer_advertise_os_version = !!transfer_advertise_os_version;
+	}
+	return transfer_advertise_os_version;
+}
diff --git a/version.h b/version.h
index 5eb586c0bd..300ee73df5 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,8 @@
 #ifndef VERSION_H
 #define VERSION_H
 
+struct repository;
+
 extern const char git_version_string[];
 extern const char git_built_from_commit_string[];
 
@@ -14,4 +16,17 @@ const char *git_user_agent_sanitized(void);
 */
 int get_uname_info(struct strbuf *buf, unsigned int full);
 
+/*
+  Retrieve, sanitize and cache system information for subsequent
+  calls. Return a pointer to the sanitized system information
+  string.
+*/
+const char *os_version_sanitized(void);
+
+/*
+  Retrieve and cache whether os-version capability is enabled.
+  Return 1 if enabled, 0 if disabled.
+*/
+int advertise_os_version(struct repository *r);
+
 #endif /* VERSION_H */
-- 
2.48.0


^ permalink raw reply related	[flat|nested] 111+ messages in thread

end of thread, other threads:[~2025-03-03 16:58 UTC | newest]

Thread overview: 111+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-31 13:40 [PATCH 0/4] Introduce a "promisor-remote" capability Christian Couder
2024-07-31 13:40 ` [PATCH 1/4] version: refactor strbuf_sanitize() Christian Couder
2024-07-31 17:18   ` Junio C Hamano
2024-08-20 11:29     ` Christian Couder
2024-07-31 13:40 ` [PATCH 2/4] strbuf: refactor strbuf_trim_trailing_ch() Christian Couder
2024-07-31 17:29   ` Junio C Hamano
2024-07-31 21:49     ` Taylor Blau
2024-08-20 11:29       ` Christian Couder
2024-08-20 11:29     ` Christian Couder
2024-07-31 13:40 ` [PATCH 3/4] Add 'promisor-remote' capability to protocol v2 Christian Couder
2024-07-31 15:40   ` Taylor Blau
2024-08-20 11:32     ` Christian Couder
2024-08-20 17:01       ` Junio C Hamano
2024-09-10 16:32         ` Christian Couder
2024-07-31 16:16   ` Taylor Blau
2024-08-20 11:32     ` Christian Couder
2024-08-20 16:55       ` Junio C Hamano
2024-09-10 16:32       ` Christian Couder
2024-09-10 17:46         ` Junio C Hamano
2024-07-31 18:25   ` Junio C Hamano
2024-07-31 19:34     ` Junio C Hamano
2024-08-20 12:21     ` Christian Couder
2024-08-05 13:48   ` Patrick Steinhardt
2024-08-19 20:00     ` Junio C Hamano
2024-09-10 16:31     ` Christian Couder
2024-07-31 13:40 ` [PATCH 4/4] promisor-remote: check advertised name or URL Christian Couder
2024-07-31 18:35   ` Junio C Hamano
2024-09-10 16:32     ` Christian Couder
2024-07-31 16:01 ` [PATCH 0/4] Introduce a "promisor-remote" capability Junio C Hamano
2024-07-31 16:17 ` Taylor Blau
2024-09-10 16:29 ` [PATCH v2 " Christian Couder
2024-09-10 16:29   ` [PATCH v2 1/4] version: refactor strbuf_sanitize() Christian Couder
2024-09-10 16:29   ` [PATCH v2 2/4] strbuf: refactor strbuf_trim_trailing_ch() Christian Couder
2024-09-10 16:29   ` [PATCH v2 3/4] Add 'promisor-remote' capability to protocol v2 Christian Couder
2024-09-30  7:56     ` Patrick Steinhardt
2024-09-30 13:28       ` Christian Couder
2024-10-01 10:14         ` Patrick Steinhardt
2024-10-01 18:47           ` Junio C Hamano
2024-11-06 14:04     ` Patrick Steinhardt
2024-11-28  5:47     ` Junio C Hamano
2024-11-28 15:31       ` Christian Couder
2024-11-29  1:31         ` Junio C Hamano
2024-09-10 16:30   ` [PATCH v2 4/4] promisor-remote: check advertised name or URL Christian Couder
2024-09-30  7:57     ` Patrick Steinhardt
2024-09-26 18:09   ` [PATCH v2 0/4] Introduce a "promisor-remote" capability Junio C Hamano
2024-09-27  9:15     ` Christian Couder
2024-09-27 22:48       ` Junio C Hamano
2024-09-27 23:31         ` rsbecker
2024-09-28 10:56           ` Kristoffer Haugsbakk
2024-09-30  7:57         ` Patrick Steinhardt
2024-09-30  9:17           ` Christian Couder
2024-09-30 16:52             ` Junio C Hamano
2024-10-01 10:14             ` Patrick Steinhardt
2024-09-30 16:34           ` Junio C Hamano
2024-09-30 21:26           ` brian m. carlson
2024-09-30 22:27             ` Junio C Hamano
2024-10-01 10:13               ` Patrick Steinhardt
2024-12-06 12:42   ` [PATCH v3 0/5] " Christian Couder
2024-12-06 12:42     ` [PATCH v3 1/5] version: refactor strbuf_sanitize() Christian Couder
2024-12-07  6:21       ` Junio C Hamano
2025-01-27 15:07         ` Christian Couder
2024-12-06 12:42     ` [PATCH v3 2/5] strbuf: refactor strbuf_trim_trailing_ch() Christian Couder
2024-12-07  6:35       ` Junio C Hamano
2025-01-27 15:07         ` Christian Couder
2024-12-16 11:47       ` karthik nayak
2024-12-06 12:42     ` [PATCH v3 3/5] Add 'promisor-remote' capability to protocol v2 Christian Couder
2024-12-07  7:59       ` Junio C Hamano
2025-01-27 15:08         ` Christian Couder
2024-12-06 12:42     ` [PATCH v3 4/5] promisor-remote: check advertised name or URL Christian Couder
2024-12-06 12:42     ` [PATCH v3 5/5] doc: add technical design doc for large object promisors Christian Couder
2024-12-10  1:28       ` Junio C Hamano
2025-01-27 15:12         ` Christian Couder
2024-12-10 11:43       ` Junio C Hamano
2024-12-16  9:00         ` Patrick Steinhardt
2025-01-27 15:11         ` Christian Couder
2025-01-27 18:02           ` Junio C Hamano
2025-02-18 11:42             ` Christian Couder
2024-12-09  8:04     ` [PATCH v3 0/5] Introduce a "promisor-remote" capability Junio C Hamano
2024-12-09 10:40       ` Christian Couder
2024-12-09 10:42         ` Christian Couder
2024-12-09 23:01         ` Junio C Hamano
2025-01-27 15:05           ` Christian Couder
2025-01-27 19:38             ` Junio C Hamano
2025-01-27 15:16     ` [PATCH v4 0/6] " Christian Couder
2025-01-27 15:16       ` [PATCH v4 1/6] version: replace manual ASCII checks with isprint() for clarity Christian Couder
2025-01-27 15:16       ` [PATCH v4 2/6] version: refactor redact_non_printables() Christian Couder
2025-01-27 15:16       ` [PATCH v4 3/6] version: make redact_non_printables() non-static Christian Couder
2025-01-30 10:51         ` Patrick Steinhardt
2025-02-18 11:42           ` Christian Couder
2025-01-27 15:16       ` [PATCH v4 4/6] Add 'promisor-remote' capability to protocol v2 Christian Couder
2025-01-30 10:51         ` Patrick Steinhardt
2025-02-18 11:41           ` Christian Couder
2025-01-27 15:17       ` [PATCH v4 5/6] promisor-remote: check advertised name or URL Christian Couder
2025-01-27 23:48         ` Junio C Hamano
2025-01-28  0:01           ` Junio C Hamano
2025-01-30 10:51           ` Patrick Steinhardt
2025-02-18 11:41             ` Christian Couder
2025-02-18 11:42           ` Christian Couder
2025-01-27 15:17       ` [PATCH v4 6/6] doc: add technical design doc for large object promisors Christian Couder
2025-01-27 21:14       ` [PATCH v4 0/6] Introduce a "promisor-remote" capability Junio C Hamano
2025-02-18 11:40         ` Christian Couder
2025-02-18 11:32       ` [PATCH v5 0/3] " Christian Couder
2025-02-18 11:32         ` [PATCH v5 1/3] Add 'promisor-remote' capability to protocol v2 Christian Couder
2025-02-18 11:32         ` [PATCH v5 2/3] promisor-remote: check advertised name or URL Christian Couder
2025-02-18 11:32         ` [PATCH v5 3/3] doc: add technical design doc for large object promisors Christian Couder
2025-02-21  8:33           ` Patrick Steinhardt
2025-03-03 16:58             ` Junio C Hamano
2025-02-18 19:07         ` [PATCH v5 0/3] Introduce a "promisor-remote" capability Junio C Hamano
2025-02-21  8:34         ` Patrick Steinhardt
2025-02-21 18:40           ` Junio C Hamano
  -- strict thread matches above, loose matches on Subject: below --
2025-01-24 12:21 [PATCH v3 6/6] connect: advertise OS version Usman Akinyemi
2025-02-05 18:52 ` [PATCH v4 0/6][Outreachy] extend agent capability to include OS name Usman Akinyemi
2025-02-05 18:52   ` [PATCH v4 1/6] version: replace manual ASCII checks with isprint() for clarity Usman Akinyemi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox